galaxy-commits
Threads by month
- ----- 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
February 2015
- 2 participants
- 305 discussions
9 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4d2168785082/
Changeset: 4d2168785082
User: erasche2
Date: 2014-11-22 19:18:08+00:00
Summary: Enable user/email list for sharing of datasets
Affected #: 4 files
diff -r 75261cf45d583f8a48172b5209acb24d07fe7b21 -r 4d216878508215489b7434703336f6ad0b3e3e1e config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -740,6 +740,14 @@
# public.
#new_user_dataset_access_role_default_private = False
+# Expose user list. Setting this to true will expose the user list to authenticated users. This
+# makes sharing datasets in smaller galaxy instances much easier as they can type a name/email and
+# have the correct user show up. This makes less sense on large public galaxy instances where
+# that data shouldn't be exposed. For semi-public galaxies, it may make sense to expose just the
+# username and not email, or vice versa.
+#expose_user_name = False
+#expose_user_email = False
+
# -- Beta features
# Use new tool form
diff -r 75261cf45d583f8a48172b5209acb24d07fe7b21 -r 4d216878508215489b7434703336f6ad0b3e3e1e lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -92,6 +92,9 @@
self.user_label_filters = listify( kwargs.get( "user_tool_label_filters", [] ), do_strip=True )
self.user_section_filters = listify( kwargs.get( "user_tool_section_filters", [] ), do_strip=True )
+ self.expose_user_name = kwargs.get( "expose_user_name", False )
+ self.expose_user_email = kwargs.get( "expose_user_email", False )
+
# Check for tools defined in the above non-shed tool configs (i.e., tool_conf.xml) tht have
# been migrated from the Galaxy code distribution to the Tool Shed.
self.check_migrate_tools = string_as_bool( kwargs.get( 'check_migrate_tools', True ) )
diff -r 75261cf45d583f8a48172b5209acb24d07fe7b21 -r 4d216878508215489b7434703336f6ad0b3e3e1e lib/galaxy/webapps/galaxy/api/users.py
--- a/lib/galaxy/webapps/galaxy/api/users.py
+++ b/lib/galaxy/webapps/galaxy/api/users.py
@@ -37,11 +37,19 @@
else:
query = query.filter( trans.app.model.User.table.c.deleted == False ) # noqa
# special case: user can see only their own user
- if not trans.user_is_admin():
+ # special case2: if the galaxy admin has specified that other user email/names are
+ # exposed, we don't want special case #1
+ if not trans.user_is_admin() and not trans.app.config.expose_user_name and not trans.app.config.expose_user_email:
item = trans.user.to_dict( value_mapper={ 'id': trans.security.encode_id } )
return [item]
for user in query:
item = user.to_dict( value_mapper={ 'id': trans.security.encode_id } )
+ # If NOT configured to expose_email, do not expose email UNLESS the user is self, or
+ # the user is an admin
+ if not trans.app.config.expose_user_name and user is not trans.user and not trans.user_is_admin():
+ del item['username']
+ if not trans.app.config.expose_user_email and user is not trans.user and not trans.user_is_admin():
+ del item['email']
# TODO: move into api_values
rval.append( item )
return rval
diff -r 75261cf45d583f8a48172b5209acb24d07fe7b21 -r 4d216878508215489b7434703336f6ad0b3e3e1e templates/webapps/galaxy/history/share.mako
--- a/templates/webapps/galaxy/history/share.mako
+++ b/templates/webapps/galaxy/history/share.mako
@@ -37,9 +37,8 @@
<div style="clear: both"></div><div class="form-row"><label>Galaxy user emails with which to share histories</label>
- <div style="float: left; width: 250px; margin-right: 10px;">
- <input type="text" name="email" value="${email}" size="40">
- </div>
+ <input type="hidden" id="email_select" name="email" style="float: left; width: 250px; margin-right: 10px;">
+ </input><div class="toolParamHelp" style="clear: both;">
Enter a Galaxy user email address or a comma-separated list of addresses if sharing with multiple users
</div>
@@ -55,6 +54,47 @@
<input type="submit" name="share_button" value="Submit"></div></form>
+ <script type="text/javascript">
+ // stolen from templates/admin/impersonate.mako
+ /* This should be ripped out and made generic at some point for the
+ * various API bindings available, and once the API can filter list
+ * queries (term, below) */
+ $("#email_select").select2({
+ placeholder: "Select a user",
+ ajax: {
+ url: "${h.url_for(controller="/api/users", action="index")}",
+ dataType: 'json',
+ quietMillis: 250,
+ matcher: function(term, text) { return text.toUpperCase().indexOf(term.toUpperCase())>=0; },
+ data: function (term) {
+ return {
+ f_email: term
+ };
+ },
+ results: function (data) {
+ var results = [];
+ $.each(data, function(index, item){
+ var text = "";
+ if(typeof(item.username) === "string" && typeof(item.email) === "string"){
+ text = item.username + " <" + item.email + ">";
+ }else if(typeof(item.username) === "string"){
+ text = item.username;
+ }else{
+ text = item.email;
+ }
+ results.push({
+ id: item.email,
+ name: item.username,
+ text: text
+ });
+ });
+ return {
+ results: results
+ };
+ }
+ }
+ });
+ </script>
%else:
## We are sharing restricted histories
%if no_change_needed or can_change:
https://bitbucket.org/galaxy/galaxy-central/commits/ec3301ee4783/
Changeset: ec3301ee4783
User: erasche2
Date: 2014-11-25 19:19:28+00:00
Summary: Must expose username in controller as well
Affected #: 1 file
diff -r 4d216878508215489b7434703336f6ad0b3e3e1e -r ec3301ee47836c121425f21b9f54ab828774c756 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -130,7 +130,7 @@
histories, credentials, and roles.
"""
# attributes that will be accessed and returned when calling to_dict( view='collection' )
- dict_collection_visible_keys = ( 'id', 'email' )
+ dict_collection_visible_keys = ( 'id', 'email', 'username' )
# attributes that will be accessed and returned when calling to_dict( view='element' )
dict_element_visible_keys = ( 'id', 'email', 'username', 'total_disk_usage', 'nice_total_disk_usage' )
https://bitbucket.org/galaxy/galaxy-central/commits/bf8dcef796da/
Changeset: bf8dcef796da
User: erasche2
Date: 2014-12-17 20:15:23+00:00
Summary: Merged galaxy/galaxy-central into default
Affected #: 452 files
diff -r ec3301ee47836c121425f21b9f54ab828774c756 -r bf8dcef796dafaec6462f89624ee1adb92e5a45d .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -20,4 +20,4 @@
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
548ab24667d6206780237bd807f7d857a484c461 latest_2014.08.11
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
-acc8d1e2bc88530aa8d8651cf5f88649f6769304 latest_2014.10.06
+7086b87d83a9092cbece0fec6f3e3ed03266be0c latest_2014.10.06
diff -r ec3301ee47836c121425f21b9f54ab828774c756 -r bf8dcef796dafaec6462f89624ee1adb92e5a45d client/galaxy/scripts/galaxy.library.js
--- a/client/galaxy/scripts/galaxy.library.js
+++ b/client/galaxy/scripts/galaxy.library.js
@@ -36,7 +36,7 @@
initialize: function() {
this.routesHit = 0;
//keep count of number of routes handled by the application
- Backbone.history.on('route', function() { this.routesHit++; }, this);
+ Backbone.history.on( 'route', function() { this.routesHit++; }, this );
},
routes: {
@@ -45,6 +45,7 @@
"library/:library_id/permissions" : "library_permissions",
"folders/:folder_id/permissions" : "folder_permissions",
"folders/:id" : "folder_content",
+ "folders/:id/page/:show_page" : "folder_page",
"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",
@@ -53,13 +54,13 @@
},
back: function() {
- if(this.routesHit > 1) {
+ 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});
+ this.navigate( '#', { trigger:true, replace:true } );
}
}
});
@@ -71,7 +72,8 @@
with_deleted : false,
sort_order : 'asc',
sort_by : 'name',
- library_page_size : 20
+ library_page_size : 20,
+ folder_page_size : 15
}
});
@@ -94,10 +96,10 @@
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:libraries', function() {
+ Galaxy.libraries.libraryToolbarView = new mod_librarytoolbar_view.LibraryToolbarView();
+ Galaxy.libraries.libraryListView = new mod_librarylist_view.LibraryListView();
+ });
this.library_router.on('route:libraries_page', function( show_page ) {
if ( Galaxy.libraries.libraryToolbarView === null ){
@@ -108,66 +110,77 @@
}
});
- this.library_router.on('route:folder_content', function(id) {
+ 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});
- });
+ 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:folder_page', function( id, show_page ) {
+ if ( Galaxy.libraries.folderToolbarView === null ){
+ Galaxy.libraries.folderToolbarView = new mod_foldertoolbar_view.FolderToolbarView( {id: id} );
+ Galaxy.libraries.folderListView = new mod_folderlist_view.FolderListView( { id: id, show_page: show_page } );
+ } else {
+ Galaxy.libraries.folderListView.render( { id: id, show_page: parseInt( show_page ) } )
+ }
+ });
- 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: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_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: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: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: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: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});
- }
- });
+ 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});
}
diff -r ec3301ee47836c121425f21b9f54ab828774c756 -r bf8dcef796dafaec6462f89624ee1adb92e5a45d client/galaxy/scripts/galaxy.masthead.js
--- a/client/galaxy/scripts/galaxy.masthead.js
+++ b/client/galaxy/scripts/galaxy.masthead.js
@@ -251,28 +251,31 @@
},
// initialize
- initialize: function (options){
+ initialize: function ( options ){
// read in defaults
- if (options)
- this.options = _.defaults(options, this.options);
-
+ if ( options ){
+ this.options = _.defaults( options, this.options );
+ }
+
// update url
- if (this.options.content && this.options.content.indexOf('//') === -1)
+ if ( this.options.content !== undefined && this.options.content.indexOf( '//' ) === -1 ){
this.options.content = galaxy_config.root + this.options.content;
+ }
// add template for tab
- this.setElement($(this._template(this.options)));
+ this.setElement( $( this._template( this.options ) ) );
// disable menu items that are not available to anonymous user
// also show title to explain why they are disabled
- if (this.options.disabled){
- $(this.el).find('.root').addClass('disabled');
+ if ( this.options.disabled ){
+ $( this.el ).find( '.root' ).addClass( 'disabled' );
this._attachPopover();
}
// visiblity
- if (!this.options.visible)
+ if ( !this.options.visible ){
this.hide();
+ }
},
// show
diff -r ec3301ee47836c121425f21b9f54ab828774c756 -r bf8dcef796dafaec6462f89624ee1adb92e5a45d client/galaxy/scripts/galaxy.menu.js
--- a/client/galaxy/scripts/galaxy.menu.js
+++ b/client/galaxy/scripts/galaxy.menu.js
@@ -24,7 +24,7 @@
var tab_analysis = new mod_masthead.GalaxyMastheadTab({
id : "analysis",
title : "Analyze Data",
- content : "root/index",
+ content : "",
title_attribute : 'Analysis home view'
});
this.masthead.append(tab_analysis);
@@ -167,7 +167,7 @@
var tab_admin = new mod_masthead.GalaxyMastheadTab({
id : "admin",
title : "Admin",
- content : "admin/index",
+ content : "admin",
extra_class : "admin-only",
title_attribute : 'Administer this Galaxy'
});
diff -r ec3301ee47836c121425f21b9f54ab828774c756 -r bf8dcef796dafaec6462f89624ee1adb92e5a45d client/galaxy/scripts/galaxy.workflow_editor.canvas.js
--- a/client/galaxy/scripts/galaxy.workflow_editor.canvas.js
+++ b/client/galaxy/scripts/galaxy.workflow_editor.canvas.js
@@ -784,6 +784,8 @@
this.tooltip = data.tooltip ? data.tooltip : "";
this.annotation = data.annotation;
this.post_job_actions = data.post_job_actions ? data.post_job_actions : {};
+ this.label = data.label;
+ this.uuid = data.uuid;
this.workflow_outputs = data.workflow_outputs ? data.workflow_outputs : [];
var node = this;
@@ -991,6 +993,8 @@
position : $(node.element).position(),
annotation: node.annotation,
post_job_actions: node.post_job_actions,
+ uuid: node.uuid,
+ label: node.label,
workflow_outputs: node.workflow_outputs
};
nodes[ node.id ] = node_data;
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/galaxy/galaxy-central/commits/bee9255a428c/
Changeset: bee9255a428c
User: erasche2
Date: 2014-12-17 20:54:12+00:00
Summary: Merged galaxy/galaxy-central into default
Affected #: 10 files
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff client/galaxy/scripts/mvc/data.js
--- a/client/galaxy/scripts/mvc/data.js
+++ b/client/galaxy/scripts/mvc/data.js
@@ -169,7 +169,8 @@
});
this.$el.append(data_table);
var column_names = this.model.get_metadata('column_names'),
- header_row = $('<tr/>').appendTo(data_table);
+ header_container = $('<thead/>').appendTo(data_table),
+ header_row = $('<tr/>').appendTo(header_container);
if (column_names) {
header_row.append('<th>' + column_names.join('</th><th>') + '</th>');
} else {
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff lib/galaxy/tools/parser/xml.py
--- a/lib/galaxy/tools/parser/xml.py
+++ b/lib/galaxy/tools/parser/xml.py
@@ -186,6 +186,11 @@
rval = dict(
outputs=__parse_output_elems(test_elem),
inputs=__parse_input_elems(test_elem, i),
+ command=__parse_assert_list_from_elem( test_elem.find("assert_command") ),
+ stdout=__parse_assert_list_from_elem( test_elem.find("assert_stdout") ),
+ stderr=__parse_assert_list_from_elem( test_elem.find("assert_stderr") ),
+ expect_exit_code=test_elem.get("expect_exit_code"),
+ expect_failure=string_as_bool(test_elem.get("expect_failure", False)),
)
_copy_to_dict_if_present(test_elem, rval, ["interactor", "num_outputs"])
return rval
@@ -222,6 +227,11 @@
return name, file, attributes
+def __parse_command_elem( test_elem ):
+ assert_elem = test_elem.find("command")
+ return __parse_assert_list_from_elem( assert_elem )
+
+
def __parse_test_attributes( output_elem, attrib ):
assert_list = __parse_assert_list( output_elem )
file = attrib.pop( 'file', None )
@@ -252,6 +262,10 @@
def __parse_assert_list( output_elem ):
assert_elem = output_elem.find("assert_contents")
+ return __parse_assert_list_from_elem( assert_elem )
+
+
+def __parse_assert_list_from_elem( assert_elem ):
assert_list = None
def convert_elem(elem):
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff lib/galaxy/tools/parser/yaml.py
--- a/lib/galaxy/tools/parser/yaml.py
+++ b/lib/galaxy/tools/parser/yaml.py
@@ -152,27 +152,47 @@
attributes["metadata"] = {}
# TODO
assert_list = []
- for key, assertion in attributes.get("asserts", {}).iteritems():
- # TODO: not handling nested assertions correctly,
- # not sure these are used though.
- children = []
- if "children" in assertion:
- children = assertion["children"]
- del assertion["children"]
- assert_dict = dict(
- tag=key,
- attributes=assertion,
- children=children,
- )
- assert_list.append(assert_dict)
+ assert_list = __to_test_assert_list( attributes.get("asserts", [] ) )
attributes["assert_list"] = assert_list
-
_ensure_has(attributes, defaults)
test_dict["outputs"] = new_outputs
+ test_dict["command"] = __to_test_assert_list( test_dict.get( "command", [] ) )
+ test_dict["stdout"] = __to_test_assert_list( test_dict.get( "stdout", [] ) )
+ test_dict["stderr"] = __to_test_assert_list( test_dict.get( "stderr", [] ) )
+ test_dict["expect_exit_code"] = test_dict.get( "expect_exit_code", None )
+ test_dict["expect_failure"] = test_dict.get( "expect_exit_code", False )
return test_dict
+def __to_test_assert_list(assertions):
+ def expand_dict_form(item):
+ key, value = item
+ new_value = value.copy()
+ new_value["that"] = key
+ return new_value
+
+ if isinstance( assertions, dict ):
+ assertions = map(expand_dict_form, assertions.items() )
+
+ assert_list = []
+ for assertion in assertions:
+ # TODO: not handling nested assertions correctly,
+ # not sure these are used though.
+ children = []
+ if "children" in assertion:
+ children = assertion["children"]
+ del assertion["children"]
+ assert_dict = dict(
+ tag=assertion["that"],
+ attributes=assertion,
+ children=children,
+ )
+ assert_list.append(assert_dict)
+
+ return assert_list or None # XML variant is None if no assertions made
+
+
class YamlPageSource(PageSource):
def __init__(self, inputs_list):
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff lib/galaxy/tools/test.py
--- a/lib/galaxy/tools/test.py
+++ b/lib/galaxy/tools/test.py
@@ -127,6 +127,11 @@
if num_outputs:
num_outputs = int( num_outputs )
self.num_outputs = num_outputs
+ self.command_line = test_dict.get("command", None)
+ self.stdout = test_dict.get("stdout", None)
+ self.stderr = test_dict.get("stderr", None)
+ self.expect_exit_code = test_dict.get("expect_exit_code", None)
+ self.expect_failure = test_dict.get("expect_failure", False)
except Exception, e:
self.error = True
self.exception = e
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff lib/galaxy/web/framework/middleware/remoteuser.py
--- a/lib/galaxy/web/framework/middleware/remoteuser.py
+++ b/lib/galaxy/web/framework/middleware/remoteuser.py
@@ -59,7 +59,7 @@
# Rewrite* method for passing REMOTE_USER and a user is
# un-authenticated. Any other possible values need to go here as well.
path_info = environ.get('PATH_INFO', '')
- if environ.get(self.remote_user_header, '(null)') != '(null)':
+ if not environ.get(self.remote_user_header, '(null)').startswith('(null)'):
if not environ[ self.remote_user_header ].count( '@' ):
if self.maildomain is not None:
environ[ self.remote_user_header ] += '@' + self.maildomain
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff static/scripts/mvc/data.js
--- a/static/scripts/mvc/data.js
+++ b/static/scripts/mvc/data.js
@@ -169,7 +169,8 @@
});
this.$el.append(data_table);
var column_names = this.model.get_metadata('column_names'),
- header_row = $('<tr/>').appendTo(data_table);
+ header_container = $('<thead/>').appendTo(data_table),
+ header_row = $('<tr/>').appendTo(header_container);
if (column_names) {
header_row.append('<th>' + column_names.join('</th><th>') + '</th>');
} else {
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff static/scripts/packed/mvc/data.js
--- a/static/scripts/packed/mvc/data.js
+++ b/static/scripts/packed/mvc/data.js
@@ -1,1 +1,1 @@
-define(["mvc/ui/ui-modal","mvc/ui/ui-frames","mvc/ui/icon-button"],function(k,j,f){var h=Backbone.Model.extend({});var b=Backbone.Model.extend({defaults:{id:"",type:"",name:"",hda_ldda:"hda",metadata:null},initialize:function(){if(!this.get("metadata")){this._set_metadata()}this.on("change",this._set_metadata,this)},_set_metadata:function(){var n=new h();_.each(_.keys(this.attributes),function(o){if(o.indexOf("metadata_")===0){var p=o.split("metadata_")[1];n.set(p,this.attributes[o]);delete this.attributes[o]}},this);this.set("metadata",n,{silent:true})},get_metadata:function(n){return this.attributes.metadata.get(n)},urlRoot:galaxy_config.root+"api/datasets"});var i=b.extend({defaults:_.extend({},b.prototype.defaults,{chunk_url:null,first_data_chunk:null,chunk_index:-1,at_eof:false}),initialize:function(n){b.prototype.initialize.call(this);this.attributes.chunk_index=(this.attributes.first_data_chunk?1:0);this.attributes.chunk_url=galaxy_config.root+"dataset/display?dataset_id="+this.id;this.attributes.url_viz=galaxy_config.root+"visualization"},get_next_chunk:function(){if(this.attributes.at_eof){return null}var n=this,o=$.Deferred();$.getJSON(this.attributes.chunk_url,{chunk:n.attributes.chunk_index++}).success(function(p){var q;if(p.ck_data!==""){q=p}else{n.attributes.at_eof=true;q=null}o.resolve(q)});return o}});var e=Backbone.Collection.extend({model:b});var a=Backbone.View.extend({initialize:function(n){this.row_count=0;this.loading_chunk=false;new d({model:n.model,$el:this.$el})},expand_to_container:function(){if(this.$el.height()<this.scroll_elt.height()){this.attempt_to_fetch()}},attempt_to_fetch:function(o){var n=this;if(!this.loading_chunk&&this.scrolled_to_bottom()){this.loading_chunk=true;this.loading_indicator.show();$.when(n.model.get_next_chunk()).then(function(p){if(p){n._renderChunk(p);n.loading_chunk=false}n.loading_indicator.hide();n.expand_to_container()})}},render:function(){this.loading_indicator=$("<div/>").attr("id","loading_indicator");this.$el.append(this.loading_indicator);var r=$("<table/>").attr({id:"content_table",cellpadding:0});this.$el.append(r);var n=this.model.get_metadata("column_names"),s=$("<tr/>").appendTo(r);if(n){s.append("<th>"+n.join("</th><th>")+"</th>")}else{for(var q=1;q<=this.model.get_metadata("columns");q++){s.append("<th>"+q+"</th>")}}var p=this,o=this.model.get("first_data_chunk");if(o){this._renderChunk(o)}else{$.when(p.model.get_next_chunk()).then(function(t){p._renderChunk(t)})}this.scroll_elt.scroll(function(){p.attempt_to_fetch()})},scrolled_to_bottom:function(){return false},_renderCell:function(q,n,r){var o=$("<td>").text(q);var p=this.model.get_metadata("column_types");if(r!==undefined){o.attr("colspan",r).addClass("stringalign")}else{if(p){if(n<p.length){if(p[n]==="str"||p[n]==="list"){o.addClass("stringalign")}}}}return o},_renderRow:function(n){var o=n.split("\t"),q=$("<tr>"),p=this.model.get_metadata("columns");if(this.row_count%2!==0){q.addClass("dark_row")}if(o.length===p){_.each(o,function(s,r){q.append(this._renderCell(s,r))},this)}else{if(o.length>p){_.each(o.slice(0,p-1),function(s,r){q.append(this._renderCell(s,r))},this);q.append(this._renderCell(o.slice(p-1).join("\t"),p-1))}else{if(p>5&&o.length===p-1){_.each(o,function(s,r){q.append(this._renderCell(s,r))},this);q.append($("<td>"))}else{q.append(this._renderCell(n,0,p))}}}this.row_count++;return q},_renderChunk:function(n){var o=this.$el.find("table");_.each(n.ck_data.split("\n"),function(p,q){if(p!==""){o.append(this._renderRow(p))}},this)}});var g=a.extend({initialize:function(n){a.prototype.initialize.call(this,n);scroll_elt=_.find(this.$el.parents(),function(o){return $(o).css("overflow")==="auto"});if(!scroll_elt){scroll_elt=window}this.scroll_elt=$(scroll_elt)},scrolled_to_bottom:function(){return(this.$el.height()-this.scroll_elt.scrollTop()-this.scroll_elt.height()<=0)}});var m=a.extend({initialize:function(n){a.prototype.initialize.call(this,n);this.scroll_elt=this.$el.css({position:"relative",overflow:"scroll",height:this.options.height||"500px"})},scrolled_to_bottom:function(){return this.$el.scrollTop()+this.$el.innerHeight()>=this.el.scrollHeight}});var d=Backbone.View.extend({col:{chrom:null,start:null,end:null},url_viz:null,dataset_id:null,genome_build:null,file_ext:null,initialize:function(p){var s=parent.Galaxy;if(s&&s.modal){this.modal=s.modal}if(s&&s.frame){this.frame=s.frame}if(!this.modal||!this.frame){return}var o=p.model;var r=o.get("metadata");if(!o.get("file_ext")){return}this.file_ext=o.get("file_ext");if(this.file_ext=="bed"){if(r.get("chromCol")&&r.get("startCol")&&r.get("endCol")){this.col.chrom=r.get("chromCol")-1;this.col.start=r.get("startCol")-1;this.col.end=r.get("endCol")-1}else{console.log("TabularButtonTrackster : Bed-file metadata incomplete.");return}}if(this.file_ext=="vcf"){function q(u,v){for(var t=0;t<v.length;t++){if(v[t].match(u)){return t}}return -1}this.col.chrom=q("Chrom",r.get("column_names"));this.col.start=q("Pos",r.get("column_names"));this.col.end=null;if(this.col.chrom==-1||this.col.start==-1){console.log("TabularButtonTrackster : VCF-file metadata incomplete.");return}}if(this.col.chrom===undefined){return}if(o.id){this.dataset_id=o.id}else{console.log("TabularButtonTrackster : Dataset identification is missing.");return}if(o.get("url_viz")){this.url_viz=o.get("url_viz")}else{console.log("TabularButtonTrackster : Url for visualization controller is missing.");return}if(o.get("genome_build")){this.genome_build=o.get("genome_build")}var n=new f.IconButtonView({model:new f.IconButton({title:"Visualize",icon_class:"chart_curve",id:"btn_viz"})});this.setElement(p.$el);this.$el.append(n.render().$el);this.hide()},events:{"mouseover tr":"show",mouseleave:"hide"},show:function(s){function r(x){return !isNaN(parseFloat(x))&&isFinite(x)}if(this.col.chrom===null){return}var w=$(s.target).parent();var t=w.children().eq(this.col.chrom).html();var n=w.children().eq(this.col.start).html();var p=this.col.end?w.children().eq(this.col.end).html():n;if(!t.match("^#")&&t!==""&&r(n)){var v={dataset_id:this.dataset_id,gene_region:t+":"+n+"-"+p};var q=w.offset();var o=q.left-10;var u=q.top-$(window).scrollTop()+3;$("#btn_viz").css({position:"fixed",top:u+"px",left:o+"px"});$("#btn_viz").off("click");$("#btn_viz").click(this.create_trackster_action(this.url_viz,v,this.genome_build));$("#btn_viz").show()}else{$("#btn_viz").hide()}},hide:function(){this.$el.find("#btn_viz").hide()},create_trackster_action:function(n,q,p){var o=this;return function(){var r={};if(p){r["f-dbkey"]=p}$.ajax({url:n+"/list_tracks?"+$.param(r),dataType:"html",error:function(){o.modal.show({title:"Something went wrong!",body:"Unfortunately we could not add this dataset to the track browser. Please try again or contact us.",buttons:{Cancel:function(){o.modal.hide()}}})},success:function(s){o.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){o.modal.hide()},"View in saved visualization":function(){o.modal.show({title:"Add Data to Saved Visualization",body:s,buttons:{Cancel:function(){o.modal.hide()},"Add to visualization":function(){o.modal.hide();o.modal.$el.find("input[name=id]:checked").each(function(){var t=$(this).val();q.id=t;o.frame.add({title:"Trackster",type:"url",content:n+"/trackster?"+$.param(q)})})}}})},"View in new visualization":function(){o.modal.hide();o.frame.add({title:"Trackster",type:"url",content:n+"/trackster?"+$.param(q)})}}})}});return false}}});var l=function(q,o,r,n){var p=new o({model:new q(r)});p.render();if(n){n.append(p.$el)}return p};var c=function(p){if(!p.model){p.model=new i(p.dataset_config)}var o=p.parent_elt;var q=p.embedded;delete p.embedded;delete p.parent_elt;delete p.dataset_config;var n=(q?new m(p):new g(p));n.render();if(o){o.append(n.$el);n.expand_to_container()}return n};return{Dataset:b,TabularDataset:i,DatasetCollection:e,TabularDatasetChunkedView:a,createTabularDatasetChunkedView:c}});
\ No newline at end of file
+define(["mvc/ui/ui-modal","mvc/ui/ui-frames","mvc/ui/icon-button"],function(k,j,f){var h=Backbone.Model.extend({});var b=Backbone.Model.extend({defaults:{id:"",type:"",name:"",hda_ldda:"hda",metadata:null},initialize:function(){if(!this.get("metadata")){this._set_metadata()}this.on("change",this._set_metadata,this)},_set_metadata:function(){var n=new h();_.each(_.keys(this.attributes),function(o){if(o.indexOf("metadata_")===0){var p=o.split("metadata_")[1];n.set(p,this.attributes[o]);delete this.attributes[o]}},this);this.set("metadata",n,{silent:true})},get_metadata:function(n){return this.attributes.metadata.get(n)},urlRoot:galaxy_config.root+"api/datasets"});var i=b.extend({defaults:_.extend({},b.prototype.defaults,{chunk_url:null,first_data_chunk:null,chunk_index:-1,at_eof:false}),initialize:function(n){b.prototype.initialize.call(this);this.attributes.chunk_index=(this.attributes.first_data_chunk?1:0);this.attributes.chunk_url=galaxy_config.root+"dataset/display?dataset_id="+this.id;this.attributes.url_viz=galaxy_config.root+"visualization"},get_next_chunk:function(){if(this.attributes.at_eof){return null}var n=this,o=$.Deferred();$.getJSON(this.attributes.chunk_url,{chunk:n.attributes.chunk_index++}).success(function(p){var q;if(p.ck_data!==""){q=p}else{n.attributes.at_eof=true;q=null}o.resolve(q)});return o}});var e=Backbone.Collection.extend({model:b});var a=Backbone.View.extend({initialize:function(n){this.row_count=0;this.loading_chunk=false;new d({model:n.model,$el:this.$el})},expand_to_container:function(){if(this.$el.height()<this.scroll_elt.height()){this.attempt_to_fetch()}},attempt_to_fetch:function(o){var n=this;if(!this.loading_chunk&&this.scrolled_to_bottom()){this.loading_chunk=true;this.loading_indicator.show();$.when(n.model.get_next_chunk()).then(function(p){if(p){n._renderChunk(p);n.loading_chunk=false}n.loading_indicator.hide();n.expand_to_container()})}},render:function(){this.loading_indicator=$("<div/>").attr("id","loading_indicator");this.$el.append(this.loading_indicator);var r=$("<table/>").attr({id:"content_table",cellpadding:0});this.$el.append(r);var n=this.model.get_metadata("column_names"),s=$("<thead/>").appendTo(r),t=$("<tr/>").appendTo(s);if(n){t.append("<th>"+n.join("</th><th>")+"</th>")}else{for(var q=1;q<=this.model.get_metadata("columns");q++){t.append("<th>"+q+"</th>")}}var p=this,o=this.model.get("first_data_chunk");if(o){this._renderChunk(o)}else{$.when(p.model.get_next_chunk()).then(function(u){p._renderChunk(u)})}this.scroll_elt.scroll(function(){p.attempt_to_fetch()})},scrolled_to_bottom:function(){return false},_renderCell:function(q,n,r){var o=$("<td>").text(q);var p=this.model.get_metadata("column_types");if(r!==undefined){o.attr("colspan",r).addClass("stringalign")}else{if(p){if(n<p.length){if(p[n]==="str"||p[n]==="list"){o.addClass("stringalign")}}}}return o},_renderRow:function(n){var o=n.split("\t"),q=$("<tr>"),p=this.model.get_metadata("columns");if(this.row_count%2!==0){q.addClass("dark_row")}if(o.length===p){_.each(o,function(s,r){q.append(this._renderCell(s,r))},this)}else{if(o.length>p){_.each(o.slice(0,p-1),function(s,r){q.append(this._renderCell(s,r))},this);q.append(this._renderCell(o.slice(p-1).join("\t"),p-1))}else{if(p>5&&o.length===p-1){_.each(o,function(s,r){q.append(this._renderCell(s,r))},this);q.append($("<td>"))}else{q.append(this._renderCell(n,0,p))}}}this.row_count++;return q},_renderChunk:function(n){var o=this.$el.find("table");_.each(n.ck_data.split("\n"),function(p,q){if(p!==""){o.append(this._renderRow(p))}},this)}});var g=a.extend({initialize:function(n){a.prototype.initialize.call(this,n);scroll_elt=_.find(this.$el.parents(),function(o){return $(o).css("overflow")==="auto"});if(!scroll_elt){scroll_elt=window}this.scroll_elt=$(scroll_elt)},scrolled_to_bottom:function(){return(this.$el.height()-this.scroll_elt.scrollTop()-this.scroll_elt.height()<=0)}});var m=a.extend({initialize:function(n){a.prototype.initialize.call(this,n);this.scroll_elt=this.$el.css({position:"relative",overflow:"scroll",height:this.options.height||"500px"})},scrolled_to_bottom:function(){return this.$el.scrollTop()+this.$el.innerHeight()>=this.el.scrollHeight}});var d=Backbone.View.extend({col:{chrom:null,start:null,end:null},url_viz:null,dataset_id:null,genome_build:null,file_ext:null,initialize:function(p){var s=parent.Galaxy;if(s&&s.modal){this.modal=s.modal}if(s&&s.frame){this.frame=s.frame}if(!this.modal||!this.frame){return}var o=p.model;var r=o.get("metadata");if(!o.get("file_ext")){return}this.file_ext=o.get("file_ext");if(this.file_ext=="bed"){if(r.get("chromCol")&&r.get("startCol")&&r.get("endCol")){this.col.chrom=r.get("chromCol")-1;this.col.start=r.get("startCol")-1;this.col.end=r.get("endCol")-1}else{console.log("TabularButtonTrackster : Bed-file metadata incomplete.");return}}if(this.file_ext=="vcf"){function q(u,v){for(var t=0;t<v.length;t++){if(v[t].match(u)){return t}}return -1}this.col.chrom=q("Chrom",r.get("column_names"));this.col.start=q("Pos",r.get("column_names"));this.col.end=null;if(this.col.chrom==-1||this.col.start==-1){console.log("TabularButtonTrackster : VCF-file metadata incomplete.");return}}if(this.col.chrom===undefined){return}if(o.id){this.dataset_id=o.id}else{console.log("TabularButtonTrackster : Dataset identification is missing.");return}if(o.get("url_viz")){this.url_viz=o.get("url_viz")}else{console.log("TabularButtonTrackster : Url for visualization controller is missing.");return}if(o.get("genome_build")){this.genome_build=o.get("genome_build")}var n=new f.IconButtonView({model:new f.IconButton({title:"Visualize",icon_class:"chart_curve",id:"btn_viz"})});this.setElement(p.$el);this.$el.append(n.render().$el);this.hide()},events:{"mouseover tr":"show",mouseleave:"hide"},show:function(s){function r(x){return !isNaN(parseFloat(x))&&isFinite(x)}if(this.col.chrom===null){return}var w=$(s.target).parent();var t=w.children().eq(this.col.chrom).html();var n=w.children().eq(this.col.start).html();var p=this.col.end?w.children().eq(this.col.end).html():n;if(!t.match("^#")&&t!==""&&r(n)){var v={dataset_id:this.dataset_id,gene_region:t+":"+n+"-"+p};var q=w.offset();var o=q.left-10;var u=q.top-$(window).scrollTop()+3;$("#btn_viz").css({position:"fixed",top:u+"px",left:o+"px"});$("#btn_viz").off("click");$("#btn_viz").click(this.create_trackster_action(this.url_viz,v,this.genome_build));$("#btn_viz").show()}else{$("#btn_viz").hide()}},hide:function(){this.$el.find("#btn_viz").hide()},create_trackster_action:function(n,q,p){var o=this;return function(){var r={};if(p){r["f-dbkey"]=p}$.ajax({url:n+"/list_tracks?"+$.param(r),dataType:"html",error:function(){o.modal.show({title:"Something went wrong!",body:"Unfortunately we could not add this dataset to the track browser. Please try again or contact us.",buttons:{Cancel:function(){o.modal.hide()}}})},success:function(s){o.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){o.modal.hide()},"View in saved visualization":function(){o.modal.show({title:"Add Data to Saved Visualization",body:s,buttons:{Cancel:function(){o.modal.hide()},"Add to visualization":function(){o.modal.hide();o.modal.$el.find("input[name=id]:checked").each(function(){var t=$(this).val();q.id=t;o.frame.add({title:"Trackster",type:"url",content:n+"/trackster?"+$.param(q)})})}}})},"View in new visualization":function(){o.modal.hide();o.frame.add({title:"Trackster",type:"url",content:n+"/trackster?"+$.param(q)})}}})}});return false}}});var l=function(q,o,r,n){var p=new o({model:new q(r)});p.render();if(n){n.append(p.$el)}return p};var c=function(p){if(!p.model){p.model=new i(p.dataset_config)}var o=p.parent_elt;var q=p.embedded;delete p.embedded;delete p.parent_elt;delete p.dataset_config;var n=(q?new m(p):new g(p));n.render();if(o){o.append(n.$el);n.expand_to_container()}return n};return{Dataset:b,TabularDataset:i,DatasetCollection:e,TabularDatasetChunkedView:a,createTabularDatasetChunkedView:c}});
\ No newline at end of file
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff test/functional/test_toolbox.py
--- a/test/functional/test_toolbox.py
+++ b/test/functional/test_toolbox.py
@@ -1,6 +1,7 @@
import new
import sys
from base.twilltestcase import TwillTestCase
+from base.asserts import verify_assertions
from base.interactor import build_interactor, stage_data_in_history, RunToolException
from base.instrument import register_job_data
from galaxy.tools import DataManagerTool
@@ -92,6 +93,9 @@
raise Exception( "Test parse failure" )
def _verify_outputs( self, testdef, history, jobs, shed_tool_id, data_list, galaxy_interactor ):
+ assert len(jobs) == 1, "Test framework logic error, somehow tool test resulted in more than one job."
+ job = jobs[ 0 ]
+
maxseconds = testdef.maxseconds
if testdef.num_outputs is not None:
expected = testdef.num_outputs
@@ -102,7 +106,33 @@
raise Exception( message )
found_exceptions = []
- job_stdio = None
+ if testdef.expect_failure:
+ if testdef.outputs:
+ raise Exception("Cannot specify outputs in a test expecting failure.")
+
+ # Wait for the job to complete and register expections if the final
+ # status was not what test was expecting.
+ job_failed = False
+ try:
+ galaxy_interactor.wait_for_job( job[ 'id' ], history, maxseconds )
+ except Exception as e:
+ job_failed = True
+ if not testdef.expect_failure:
+ found_exceptions.append(e)
+
+ if not job_failed and testdef.expect_failure:
+ error = AssertionError("Expected job to fail but Galaxy indicated the job successfully completed.")
+ found_exceptions.append(error)
+
+ job_stdio = galaxy_interactor.get_job_stdio( job[ 'id' ] )
+
+ expect_exit_code = testdef.expect_exit_code
+ if expect_exit_code is not None:
+ exit_code = job_stdio["exit_code"]
+ if str(expect_exit_code) != str(exit_code):
+ error = AssertionError("Expected job to complete with exit code %s, found %s" % (expect_exit_code, exit_code))
+ found_exceptions.append(error)
+
for output_index, output_tuple in enumerate(testdef.outputs):
# Get the correct hid
name, outfile, attributes = output_tuple
@@ -123,14 +153,25 @@
except Exception as e:
if not found_exceptions:
# Only print this stuff out once.
- for job in jobs:
- job_stdio = galaxy_interactor.get_job_stdio( job[ 'id' ] )
- for stream in ['stdout', 'stderr']:
- if stream in job_stdio:
- print >>sys.stderr, self._format_stream( job_stdio[ stream ], stream=stream, format=True )
+ for stream in ['stdout', 'stderr']:
+ if stream in job_stdio:
+ print >>sys.stderr, self._format_stream( job_stdio[ stream ], stream=stream, format=True )
found_exceptions.append(e)
- if job_stdio is None:
- job_stdio = galaxy_interactor.get_job_stdio( jobs[0][ 'id' ] )
+
+ other_checks = {
+ "command_line": "Command produced by the job",
+ "stdout": "Standard output of the job",
+ "stderr": "Standard error of the job",
+ }
+ for what, description in other_checks.items():
+ if getattr( testdef, what, None ) is not None:
+ try:
+ data = job_stdio[what]
+ verify_assertions( data, getattr( testdef, what ) )
+ except AssertionError, err:
+ errmsg = '%s different than expected\n' % description
+ errmsg += str( err )
+ found_exceptions.append( AssertionError( errmsg ) )
if found_exceptions:
raise JobOutputsError(found_exceptions, job_stdio)
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff test/functional/tools/job_properties.xml
--- /dev/null
+++ b/test/functional/tools/job_properties.xml
@@ -0,0 +1,62 @@
+<tool id="job_properties" name="Test Job Properties">
+ <command>
+ #if $thebool
+ echo "The bool is true";
+ echo "The bool is really true" 1>&2;
+ echo "This is a line of text." > $out_file1
+ #else
+ echo "The bool is not true";
+ echo "The bool is very not true" 1>&2;
+ echo "This is a different line of text." > $out_file1;
+ sh -c "exit 2"
+ #end if
+ #if $failbool
+ ; sh -c "exit 127"
+ #end if
+
+ </command>
+ <inputs>
+ <param name="thebool" type="boolean" label="The boolean property" />
+ <param name="failbool" type="boolean" label="The failure property" checked="false" />
+ </inputs>
+ <outputs>
+ <data name="out_file1" />
+ </outputs>
+ <stdio>
+ <exit_code range="127" level="fatal" description="Failing exit code." />
+ </stdio>
+ <tests>
+ <test expect_exit_code="0">
+ <param name="thebool" value="true" />
+ <output name="out_file1" file="simple_line.txt" />
+ <assert_command>
+ <has_text text="really" />
+ </assert_command>
+ <assert_stdout>
+ <has_line line="The bool is true" />
+ </assert_stdout>
+ <assert_stderr>
+ <has_line line="The bool is really true" />
+ </assert_stderr>
+ </test>
+ <test expect_exit_code="2">
+ <param name="thebool" value="false" />
+ <output name="out_file1" file="simple_line_alternative.txt" />
+ <assert_command>
+ <has_text text="very not" />
+ </assert_command>
+ <assert_stdout>
+ <has_line line="The bool is not true" />
+ </assert_stdout>
+ <assert_stderr>
+ <has_line line="The bool is very not true" />
+ </assert_stderr>
+ </test>
+ <test expect_exit_coded="127" expect_failure="true">
+ <param name="thebool" value="true" />
+ <param name="failbool" value="true" />
+ </test>
+ </tests>
+ <help>
+ </help>
+</tool>
diff -r bf8dcef796dafaec6462f89624ee1adb92e5a45d -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff test/functional/tools/samples_tool_conf.xml
--- a/test/functional/tools/samples_tool_conf.xml
+++ b/test/functional/tools/samples_tool_conf.xml
@@ -13,6 +13,7 @@
<tool file="multi_output_assign_primary.xml" /><tool file="composite_output.xml" /><tool file="metadata.xml" />
+ <tool file="job_properties.xml" /><tool file="gzipped_inputs.xml" /><tool file="output_order.xml" /><tool file="output_format.xml" />
https://bitbucket.org/galaxy/galaxy-central/commits/cf2636a3d9c3/
Changeset: cf2636a3d9c3
User: erasche2
Date: 2015-02-05 20:43:26+00:00
Summary: Merged galaxy/galaxy-central into default
Affected #: 449 files
diff -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -30,9 +30,9 @@
*.pyc
# Galaxy Runtime Files
-paster.lock
-paster.log
-paster.pid
+*.lock
+*.log
+*.pid
# Tool Shed Runtime Files
tool_shed_webapp.lock
@@ -108,12 +108,9 @@
# CSS build artifacts.
sprite-*.less
-# Local node_modules directories
+# Local node_modules and bower_components directories
node_modules
-
-# Testing
-selenium-server.jar
-selenium_results.html
+bower_components
# Documentation build files.
doc/build
diff -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -8,16 +8,18 @@
5e605ed6069fe4c5ca9875e95e91b2713499e8ca release_2014.02.10
9e53251b0b7e93b9563008a2b112f2e815a04bbc release_2014.04.14
7e257c7b10badb65772b1528cb61d58175a42e47 release_2014.06.02
-7a4d321c0e38fa263ea83d29a35a608c3181fcba latest_2014.06.02
-9661b9d5d5b330483ae3ad2236410e0efaa7c500 latest_2014.04.14
-6b0bd93038a843b1585155f0d63f0eea2459c70b latest_2013.01.13
-3e62060b14b9afc46f8e0ec02e1a4500d77db9e1 latest_2013.02.08
-425009b3ff4d8b67d2812253b221f3c4f4a8d1e3 latest_2013.04.01
-9713d86392ef985ffcdc39ff0c8ddf51a1f9ce47 latest_2013.06.03
-9ed84cd208e07e8985ec917cb025fcbbb09edcfb latest_2013.08.12
-81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04
-2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10
+9bce3f426863f8ba88062f67c7efc1836e82ee7c latest_2014.06.02
+8f9dcac033694e4cabcf5daae5cca1cfefbe967f latest_2014.04.14
+9c323aad4ffdd65a3deb06a4a36f6b2c5115a60f latest_2013.01.13
+b986c184be88947b5d1d90be7f36cfd2627dd938 latest_2013.02.08
+dec9431d66b837a208e2f060d90afd913c721227 latest_2013.04.01
+19e56e66b0b344c6e2afa4541f6988e4fdb9af29 latest_2013.06.03
+cee903b8b3eee9145627ee89742555dac581791e latest_2013.08.12
+7d5aa19a166cba9039e15f338a1e3fc924c43d3a latest_2013.11.04
+0c000cc2f9c05bf4c1c2bc3a10215014fd64e696 latest_2014.02.10
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
-548ab24667d6206780237bd807f7d857a484c461 latest_2014.08.11
+f3fc4602e22b39468d780b955a1a05caf867a7e9 latest_2014.08.11
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
-7086b87d83a9092cbece0fec6f3e3ed03266be0c latest_2014.10.06
+9bd6f8b5b8153db752f4e61ed62f2b6c01ae4a11 latest_2014.10.06
+2e8dd2949dd3eee0f56f9a3a5ebf1b2baca24aee release_2015.01.13
+4039bfd5584aac053f686197a76ac176253e6f3d latest_2015.01.13
diff -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d client/GruntFile.js
--- a/client/GruntFile.js
+++ b/client/GruntFile.js
@@ -47,15 +47,77 @@
options: {
spawn: false
}
+ },
+
+ // call bower to install libraries and other external resources
+ "bower-install-simple" : {
+ options: {
+ color: true
+ },
+ "prod": {
+ options: {
+ production: true
+ }
+ },
+ "dev": {
+ options: {
+ production: false
+ }
+ }
+ },
+ // where to move fetched bower components into the build structure (libName: [ bower-location, libs-location ])
+ libraryLocations : {
+ "jquery": [ "dist/jquery.js", "jquery/jquery.js" ],
+ "jquery-migrate": [ "jquery-migrate.js", "jquery/jquery.migrate.js" ],
+ "traceKit": [ "tracekit.js", "tracekit.js" ],
+ "ravenjs": [ "dist/raven.js", "raven.js" ],
+ "underscore": [ "underscore.js", "underscore.js" ],
+ "handlebars": [ "handlebars.runtime.js", "handlebars.runtime.js" ],
+ "lunr.js": [ "lunr.js", "lunr.js" ]
+ //"backbone": [ "backbone.js", "backbone/backbone.js" ],
+
+ // these need to be updated and tested
+ //"require": [ "build/require.js", "require.js" ],
+ //"d3": [ "d3.js", "d3.js" ],
+ //"farbtastic": [ "src/farbtastic.js", "farbtastic.js" ],
+ //"jQTouch": [ "src/reference/jqtouch.js", "jquery/jqtouch.js" ],
+ //"bib2json": [ "Parser.js", "bibtex.js" ],
+ //"jquery-form": [ "jquery.form.js", "jquery/jquery.form.js" ],
+ //"jquery-autocomplete": [ "src/jquery.autocomplete.js", "jquery/jquery.autocomplete.js" ],
+ //"select2": [ "select2.js", "jquery/select2.js" ],
+ //"jStorage": [ "jstorage.js", "jquery/jstorage.js" ],
+ //"jquery.cookie": [ "", "jquery/jquery.cookie.js" ],
+ //"dynatree": [ "dist/jquery.dynatree.js", "jquery/jquery.dynatree.js" ],
+ //"jquery-mousewheel": [ "jquery.mousewheel.js", "jquery/jquery.mousewheel.js" ],
+ //"jquery.event.drag-drop": [
+ // [ "event.drag/jquery.event.drag.js", "jquery/jquery.event.drag.js" ],
+ // [ "event.drag/jquery.event.drop.js", "jquery/jquery.event.drop.js" ]
+ //],
+
+ // these are complicated by additional css/less
+ //"toastr": [ "toastr.js", "toastr.js" ],
+ //"wymeditor": [ "dist/wymeditor/jquery.wymeditor.js", "jquery/jquery.wymeditor.js" ],
+ //"jstree": [ "jstree.js", "jquery/jstree.js" ],
+
+ // these have been customized by Galaxy
+ //"bootstrap": [ "dist/js/bootstrap.js", "bootstrap.js" ],
+ //"jquery-ui": [
+ // // multiple components now
+ // [ "", "jquery/jquery-ui.js" ]
+ //],
+
}
+
});
grunt.loadNpmTasks( 'grunt-contrib-watch' );
grunt.loadNpmTasks( 'grunt-contrib-copy');
- grunt.loadNpmTasks('grunt-exec');
+ grunt.loadNpmTasks( 'grunt-bower-install-simple');
+ grunt.loadNpmTasks( 'grunt-exec' );
grunt.registerTask( 'pack', [ 'exec' ] );
- grunt.registerTask( 'default', [ 'copy', 'pack' ] );
+ grunt.registerTask( 'default', [ 'copy:main', 'pack' ] );
+
// -------------------------------------------------------------------------- copy,pack only those changed
// adapted from grunt-contrib-watch jslint example
@@ -85,4 +147,25 @@
onChange();
});
+ // -------------------------------------------------------------------------- fetch/update external libraries
+ /** copy external libraries from bower components to scripts/libs */
+ function copyLibs(){
+ var libraryLocations = grunt.config( 'libraryLocations' );
+ for( var libName in libraryLocations ){
+ if( libraryLocations.hasOwnProperty( libName ) ){
+
+ var BOWER_DIR = 'bower_components',
+ location = libraryLocations[ libName ],
+ source = [ BOWER_DIR, libName, location[0] ].join( '/' ),
+ destination = 'galaxy/scripts/libs/' + location[1];
+ grunt.log.writeln( source + ' -> ' + destination );
+ grunt.file.copy( source, destination );
+ }
+ }
+ }
+
+ grunt.registerTask( 'copy-libs', 'copy external libraries to src', copyLibs );
+ grunt.registerTask( 'install-libs', 'fetch external libraries and copy to src',
+ [ 'bower-install-simple:prod', 'copy-libs' ] );
+
};
diff -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d client/bower.json
--- /dev/null
+++ b/client/bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "galaxy-client-libs",
+ "version": "0.0.0",
+ "description": "External client-side libraries used by Galaxy",
+ "keywords": [
+ "galaxy",
+ "galaxyproject"
+ ],
+ "homepage": "usegalaxy.org",
+ "dependencies": {
+ "jquery": "~1.11.1",
+ "traceKit": "*",
+ "ravenjs": "~1.1.16",
+ "require": "*",
+ "underscore": "~1.7.0",
+ "backbone": "~1.1.2",
+ "bootstrap": "~3.3.2",
+ "d3": "~3.5.3",
+ "farbtastic": "~2.0.0-alpha.1",
+ "toastr": "~2.1.0",
+ "jQTouch": "git://github.com/senchalabs/jQTouch#~1.0.0",
+ "bib2json": "git://github.com/mayanklahiri/bib2json",
+ "jquery-form": "~3.46.0",
+ "jquery-autocomplete": "git://github.com/dyve/jquery-autocomplete",
+ "select2": "~3.5.2",
+ "jStorage": "~0.4.12",
+ "jquery.cookie": "~1.4.1",
+ "dynatree": "~1.2.5",
+ "jquery-mousewheel": "~3.1.12",
+ "wymeditor": "~1.0.0-rc.1",
+ "jstree": "~3.0.9",
+ "jquery-ui": "git://github.com/jquery/jquery-ui.git#~1.11.2",
+ "jquery.event.drag-drop": "~2.2.1",
+ "handlebars": "~2.0.0",
+ "jquery-migrate": "~1.2.1",
+ "lunr.js": "git://github.com/olivernn/lunr.js.git#~0.5.7"
+ },
+ "resolutions": {
+ "jquery": "~1.11.1"
+ }
+}
diff -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d client/galaxy/scripts/galaxy.masthead.js
--- a/client/galaxy/scripts/galaxy.masthead.js
+++ b/client/galaxy/scripts/galaxy.masthead.js
@@ -364,7 +364,7 @@
var $popover_element = $(this.el).find('.head');
$popover_element.popover({
html: true,
- content: 'Please <a href="' + galaxy_config.root + '/user/login">log in</a> or <a href="' + galaxy_config.root + '/user/create">register</a> to use this feature.',
+ content: 'Please <a href="' + galaxy_config.root + 'user/login?use_panels=True">log in</a> or <a href="' + galaxy_config.root + 'user/create?use_panels=True">register</a> to use this feature.',
placement: 'bottom'
}).on('shown.bs.popover', function() { // hooking on bootstrap event to automatically hide popovers after delay
setTimeout(function() {
diff -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d client/galaxy/scripts/galaxy.workflow_editor.canvas.js
--- a/client/galaxy/scripts/galaxy.workflow_editor.canvas.js
+++ b/client/galaxy/scripts/galaxy.workflow_editor.canvas.js
@@ -805,7 +805,7 @@
nodeView.addDataOutput( output );
} );
nodeView.render();
- workflow.node_changed( this );
+ workflow.node_changed( this, true);
},
update_field_data : function( data ) {
var node = this;
@@ -1089,17 +1089,25 @@
if ( this.active_node != node ) {
this.check_changes_in_active_form();
this.clear_active_node();
- parent.show_form_for_tool( node.form_html + node.tooltip, node );
+ if (parent.__NEWTOOLFORM__) {
+ parent.show_form_for_tool( node.form_html, node );
+ } else {
+ parent.show_form_for_tool( node.form_html + node.tooltip, node );
+ }
node.make_active();
this.active_node = node;
}
},
- node_changed : function ( node ) {
+ node_changed : function ( node, force ) {
this.has_changes = true;
- if ( this.active_node == node ) {
+ if ( this.active_node == node && (!parent.__NEWTOOLFORM__ || force)) {
// Reactive with new form_html
this.check_changes_in_active_form(); //Force changes to be saved even on new connection (previously dumped)
- parent.show_form_for_tool( node.form_html + node.tooltip, node );
+ if (parent.__NEWTOOLFORM__) {
+ parent.show_form_for_tool( node.form_html, node );
+ } else {
+ parent.show_form_for_tool( node.form_html + node.tooltip, node );
+ }
}
},
layout : function () {
@@ -1305,7 +1313,6 @@
return node;
}
-
var ext_to_type = null;
var type_to_type = null;
@@ -1863,6 +1870,9 @@
left: x,
top: y
});
+ self.cv.css( { "background-position-x": x,
+ "background-position-y": y
+ });
self.update_viewport_overlay();
};
// Dragging within canvas background
diff -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d client/galaxy/scripts/libs/handlebars.runtime.js
--- a/client/galaxy/scripts/libs/handlebars.runtime.js
+++ b/client/galaxy/scripts/libs/handlebars.runtime.js
@@ -1,6 +1,8 @@
-/*
+/*!
-Copyright (C) 2011 by Yehuda Katz
+ handlebars v2.0.0
+
+Copyright (C) 2011-2014 by Yehuda Katz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -20,343 +22,639 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+@license
*/
-
-// lib/handlebars/browser-prefix.js
-var Handlebars = {};
-
-(function(Handlebars, undefined) {
-;
-// lib/handlebars/base.js
-
-Handlebars.VERSION = "1.0.0";
-Handlebars.COMPILER_REVISION = 4;
-
-Handlebars.REVISION_CHANGES = {
- 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
- 2: '== 1.0.0-rc.3',
- 3: '== 1.0.0-rc.4',
- 4: '>= 1.0.0'
-};
-
-Handlebars.helpers = {};
-Handlebars.partials = {};
-
-var toString = Object.prototype.toString,
- functionType = '[object Function]',
- objectType = '[object Object]';
-
-Handlebars.registerHelper = function(name, fn, inverse) {
- if (toString.call(name) === objectType) {
- if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); }
- Handlebars.Utils.extend(this.helpers, name);
+/* exported Handlebars */
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define([], factory);
+ } else if (typeof exports === 'object') {
+ module.exports = factory();
} else {
- if (inverse) { fn.not = inverse; }
- this.helpers[name] = fn;
+ root.Handlebars = root.Handlebars || factory();
}
-};
-
-Handlebars.registerPartial = function(name, str) {
- if (toString.call(name) === objectType) {
- Handlebars.Utils.extend(this.partials, name);
- } else {
- this.partials[name] = str;
- }
-};
-
-Handlebars.registerHelper('helperMissing', function(arg) {
- if(arguments.length === 2) {
- return undefined;
- } else {
- throw new Error("Missing helper: '" + arg + "'");
- }
-});
-
-Handlebars.registerHelper('blockHelperMissing', function(context, options) {
- var inverse = options.inverse || function() {}, fn = options.fn;
-
- var type = toString.call(context);
-
- if(type === functionType) { context = context.call(this); }
-
- if(context === true) {
- return fn(this);
- } else if(context === false || context == null) {
- return inverse(this);
- } else if(type === "[object Array]") {
- if(context.length > 0) {
- return Handlebars.helpers.each(context, options);
- } else {
- return inverse(this);
- }
- } else {
- return fn(context);
- }
-});
-
-Handlebars.K = function() {};
-
-Handlebars.createFrame = Object.create || function(object) {
- Handlebars.K.prototype = object;
- var obj = new Handlebars.K();
- Handlebars.K.prototype = null;
- return obj;
-};
-
-Handlebars.logger = {
- DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
-
- methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
-
- // can be overridden in the host environment
- log: function(level, obj) {
- if (Handlebars.logger.level <= level) {
- var method = Handlebars.logger.methodMap[level];
- if (typeof console !== 'undefined' && console[method]) {
- console[method].call(console, obj);
- }
- }
- }
-};
-
-Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
-
-Handlebars.registerHelper('each', function(context, options) {
- var fn = options.fn, inverse = options.inverse;
- var i = 0, ret = "", data;
-
- var type = toString.call(context);
- if(type === functionType) { context = context.call(this); }
-
- if (options.data) {
- data = Handlebars.createFrame(options.data);
+}(this, function () {
+// handlebars/safe-string.js
+var __module3__ = (function() {
+ "use strict";
+ var __exports__;
+ // Build out our basic SafeString type
+ function SafeString(string) {
+ this.string = string;
}
- if(context && typeof context === 'object') {
- if(context instanceof Array){
- for(var j = context.length; i<j; i++) {
- if (data) { data.index = i; }
- ret = ret + fn(context[i], { data: data });
- }
- } else {
- for(var key in context) {
- if(context.hasOwnProperty(key)) {
- if(data) { data.key = key; }
- ret = ret + fn(context[key], {data: data});
- i++;
+ SafeString.prototype.toString = function() {
+ return "" + this.string;
+ };
+
+ __exports__ = SafeString;
+ return __exports__;
+})();
+
+// handlebars/utils.js
+var __module2__ = (function(__dependency1__) {
+ "use strict";
+ var __exports__ = {};
+ /*jshint -W004 */
+ var SafeString = __dependency1__;
+
+ var escape = {
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': """,
+ "'": "'",
+ "`": "`"
+ };
+
+ var badChars = /[&<>"'`]/g;
+ var possible = /[&<>"'`]/;
+
+ function escapeChar(chr) {
+ return escape[chr];
+ }
+
+ function extend(obj /* , ...source */) {
+ for (var i = 1; i < arguments.length; i++) {
+ for (var key in arguments[i]) {
+ if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
+ obj[key] = arguments[i][key];
}
}
}
+
+ return obj;
}
- if(i === 0){
- ret = inverse(this);
+ __exports__.extend = extend;var toString = Object.prototype.toString;
+ __exports__.toString = toString;
+ // Sourced from lodash
+ // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
+ var isFunction = function(value) {
+ return typeof value === 'function';
+ };
+ // fallback for older versions of Chrome and Safari
+ /* istanbul ignore next */
+ if (isFunction(/x/)) {
+ isFunction = function(value) {
+ return typeof value === 'function' && toString.call(value) === '[object Function]';
+ };
}
+ var isFunction;
+ __exports__.isFunction = isFunction;
+ /* istanbul ignore next */
+ var isArray = Array.isArray || function(value) {
+ return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
+ };
+ __exports__.isArray = isArray;
- return ret;
-});
-
-Handlebars.registerHelper('if', function(conditional, options) {
- var type = toString.call(conditional);
- if(type === functionType) { conditional = conditional.call(this); }
-
- if(!conditional || Handlebars.Utils.isEmpty(conditional)) {
- return options.inverse(this);
- } else {
- return options.fn(this);
- }
-});
-
-Handlebars.registerHelper('unless', function(conditional, options) {
- return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
-});
-
-Handlebars.registerHelper('with', function(context, options) {
- var type = toString.call(context);
- if(type === functionType) { context = context.call(this); }
-
- if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
-});
-
-Handlebars.registerHelper('log', function(context, options) {
- var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
- Handlebars.log(level, context);
-});
-;
-// lib/handlebars/utils.js
-
-var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
-
-Handlebars.Exception = function(message) {
- var tmp = Error.prototype.constructor.apply(this, arguments);
-
- // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
- for (var idx = 0; idx < errorProps.length; idx++) {
- this[errorProps[idx]] = tmp[errorProps[idx]];
- }
-};
-Handlebars.Exception.prototype = new Error();
-
-// Build out our basic SafeString type
-Handlebars.SafeString = function(string) {
- this.string = string;
-};
-Handlebars.SafeString.prototype.toString = function() {
- return this.string.toString();
-};
-
-var escape = {
- "&": "&",
- "<": "<",
- ">": ">",
- '"': """,
- "'": "'",
- "`": "`"
-};
-
-var badChars = /[&<>"'`]/g;
-var possible = /[&<>"'`]/;
-
-var escapeChar = function(chr) {
- return escape[chr] || "&";
-};
-
-Handlebars.Utils = {
- extend: function(obj, value) {
- for(var key in value) {
- if(value.hasOwnProperty(key)) {
- obj[key] = value[key];
- }
- }
- },
-
- escapeExpression: function(string) {
+ function escapeExpression(string) {
// don't escape SafeStrings, since they're already safe
- if (string instanceof Handlebars.SafeString) {
+ if (string instanceof SafeString) {
return string.toString();
- } else if (string == null || string === false) {
+ } else if (string == null) {
return "";
+ } else if (!string) {
+ return string + '';
}
// Force a string conversion as this will be done by the append regardless and
// the regex test will do this transparently behind the scenes, causing issues if
// an object's to string has escaped characters in it.
- string = string.toString();
+ string = "" + string;
if(!possible.test(string)) { return string; }
return string.replace(badChars, escapeChar);
- },
+ }
- isEmpty: function(value) {
+ __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
if (!value && value !== 0) {
return true;
- } else if(toString.call(value) === "[object Array]" && value.length === 0) {
+ } else if (isArray(value) && value.length === 0) {
return true;
} else {
return false;
}
}
-};
-;
-// lib/handlebars/runtime.js
-Handlebars.VM = {
- template: function(templateSpec) {
+ __exports__.isEmpty = isEmpty;function appendContextPath(contextPath, id) {
+ return (contextPath ? contextPath + '.' : '') + id;
+ }
+
+ __exports__.appendContextPath = appendContextPath;
+ return __exports__;
+})(__module3__);
+
+// handlebars/exception.js
+var __module4__ = (function() {
+ "use strict";
+ var __exports__;
+
+ var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
+
+ function Exception(message, node) {
+ var line;
+ if (node && node.firstLine) {
+ line = node.firstLine;
+
+ message += ' - ' + line + ':' + node.firstColumn;
+ }
+
+ var tmp = Error.prototype.constructor.call(this, message);
+
+ // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
+ for (var idx = 0; idx < errorProps.length; idx++) {
+ this[errorProps[idx]] = tmp[errorProps[idx]];
+ }
+
+ if (line) {
+ this.lineNumber = line;
+ this.column = node.firstColumn;
+ }
+ }
+
+ Exception.prototype = new Error();
+
+ __exports__ = Exception;
+ return __exports__;
+})();
+
+// handlebars/base.js
+var __module1__ = (function(__dependency1__, __dependency2__) {
+ "use strict";
+ var __exports__ = {};
+ var Utils = __dependency1__;
+ var Exception = __dependency2__;
+
+ var VERSION = "2.0.0";
+ __exports__.VERSION = VERSION;var COMPILER_REVISION = 6;
+ __exports__.COMPILER_REVISION = COMPILER_REVISION;
+ var REVISION_CHANGES = {
+ 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
+ 2: '== 1.0.0-rc.3',
+ 3: '== 1.0.0-rc.4',
+ 4: '== 1.x.x',
+ 5: '== 2.0.0-alpha.x',
+ 6: '>= 2.0.0-beta.1'
+ };
+ __exports__.REVISION_CHANGES = REVISION_CHANGES;
+ var isArray = Utils.isArray,
+ isFunction = Utils.isFunction,
+ toString = Utils.toString,
+ objectType = '[object Object]';
+
+ function HandlebarsEnvironment(helpers, partials) {
+ this.helpers = helpers || {};
+ this.partials = partials || {};
+
+ registerDefaultHelpers(this);
+ }
+
+ __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
+ constructor: HandlebarsEnvironment,
+
+ logger: logger,
+ log: log,
+
+ registerHelper: function(name, fn) {
+ if (toString.call(name) === objectType) {
+ if (fn) { throw new Exception('Arg not supported with multiple helpers'); }
+ Utils.extend(this.helpers, name);
+ } else {
+ this.helpers[name] = fn;
+ }
+ },
+ unregisterHelper: function(name) {
+ delete this.helpers[name];
+ },
+
+ registerPartial: function(name, partial) {
+ if (toString.call(name) === objectType) {
+ Utils.extend(this.partials, name);
+ } else {
+ this.partials[name] = partial;
+ }
+ },
+ unregisterPartial: function(name) {
+ delete this.partials[name];
+ }
+ };
+
+ function registerDefaultHelpers(instance) {
+ instance.registerHelper('helperMissing', function(/* [args, ]options */) {
+ if(arguments.length === 1) {
+ // A missing field in a {{foo}} constuct.
+ return undefined;
+ } else {
+ // Someone is actually trying to call something, blow up.
+ throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
+ }
+ });
+
+ instance.registerHelper('blockHelperMissing', function(context, options) {
+ var inverse = options.inverse,
+ fn = options.fn;
+
+ if(context === true) {
+ return fn(this);
+ } else if(context === false || context == null) {
+ return inverse(this);
+ } else if (isArray(context)) {
+ if(context.length > 0) {
+ if (options.ids) {
+ options.ids = [options.name];
+ }
+
+ return instance.helpers.each(context, options);
+ } else {
+ return inverse(this);
+ }
+ } else {
+ if (options.data && options.ids) {
+ var data = createFrame(options.data);
+ data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name);
+ options = {data: data};
+ }
+
+ return fn(context, options);
+ }
+ });
+
+ instance.registerHelper('each', function(context, options) {
+ if (!options) {
+ throw new Exception('Must pass iterator to #each');
+ }
+
+ var fn = options.fn, inverse = options.inverse;
+ var i = 0, ret = "", data;
+
+ var contextPath;
+ if (options.data && options.ids) {
+ contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
+ }
+
+ if (isFunction(context)) { context = context.call(this); }
+
+ if (options.data) {
+ data = createFrame(options.data);
+ }
+
+ if(context && typeof context === 'object') {
+ if (isArray(context)) {
+ for(var j = context.length; i<j; i++) {
+ if (data) {
+ data.index = i;
+ data.first = (i === 0);
+ data.last = (i === (context.length-1));
+
+ if (contextPath) {
+ data.contextPath = contextPath + i;
+ }
+ }
+ ret = ret + fn(context[i], { data: data });
+ }
+ } else {
+ for(var key in context) {
+ if(context.hasOwnProperty(key)) {
+ if(data) {
+ data.key = key;
+ data.index = i;
+ data.first = (i === 0);
+
+ if (contextPath) {
+ data.contextPath = contextPath + key;
+ }
+ }
+ ret = ret + fn(context[key], {data: data});
+ i++;
+ }
+ }
+ }
+ }
+
+ if(i === 0){
+ ret = inverse(this);
+ }
+
+ return ret;
+ });
+
+ instance.registerHelper('if', function(conditional, options) {
+ if (isFunction(conditional)) { conditional = conditional.call(this); }
+
+ // Default behavior is to render the positive path if the value is truthy and not empty.
+ // The `includeZero` option may be set to treat the condtional as purely not empty based on the
+ // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
+ if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
+ return options.inverse(this);
+ } else {
+ return options.fn(this);
+ }
+ });
+
+ instance.registerHelper('unless', function(conditional, options) {
+ return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
+ });
+
+ instance.registerHelper('with', function(context, options) {
+ if (isFunction(context)) { context = context.call(this); }
+
+ var fn = options.fn;
+
+ if (!Utils.isEmpty(context)) {
+ if (options.data && options.ids) {
+ var data = createFrame(options.data);
+ data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
+ options = {data:data};
+ }
+
+ return fn(context, options);
+ } else {
+ return options.inverse(this);
+ }
+ });
+
+ instance.registerHelper('log', function(message, options) {
+ var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
+ instance.log(level, message);
+ });
+
+ instance.registerHelper('lookup', function(obj, field) {
+ return obj && obj[field];
+ });
+ }
+
+ var logger = {
+ methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
+
+ // State enum
+ DEBUG: 0,
+ INFO: 1,
+ WARN: 2,
+ ERROR: 3,
+ level: 3,
+
+ // can be overridden in the host environment
+ log: function(level, message) {
+ if (logger.level <= level) {
+ var method = logger.methodMap[level];
+ if (typeof console !== 'undefined' && console[method]) {
+ console[method].call(console, message);
+ }
+ }
+ }
+ };
+ __exports__.logger = logger;
+ var log = logger.log;
+ __exports__.log = log;
+ var createFrame = function(object) {
+ var frame = Utils.extend({}, object);
+ frame._parent = object;
+ return frame;
+ };
+ __exports__.createFrame = createFrame;
+ return __exports__;
+})(__module2__, __module4__);
+
+// handlebars/runtime.js
+var __module5__ = (function(__dependency1__, __dependency2__, __dependency3__) {
+ "use strict";
+ var __exports__ = {};
+ var Utils = __dependency1__;
+ var Exception = __dependency2__;
+ var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
+ var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
+ var createFrame = __dependency3__.createFrame;
+
+ function checkRevision(compilerInfo) {
+ var compilerRevision = compilerInfo && compilerInfo[0] || 1,
+ currentRevision = COMPILER_REVISION;
+
+ if (compilerRevision !== currentRevision) {
+ if (compilerRevision < currentRevision) {
+ var runtimeVersions = REVISION_CHANGES[currentRevision],
+ compilerVersions = REVISION_CHANGES[compilerRevision];
+ throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
+ "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
+ } else {
+ // Use the embedded version info since the runtime doesn't know about this revision yet
+ throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
+ "Please update your runtime to a newer version ("+compilerInfo[1]+").");
+ }
+ }
+ }
+
+ __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
+
+ function template(templateSpec, env) {
+ /* istanbul ignore next */
+ if (!env) {
+ throw new Exception("No environment passed to template");
+ }
+ if (!templateSpec || !templateSpec.main) {
+ throw new Exception('Unknown template object: ' + typeof templateSpec);
+ }
+
+ // Note: Using env.VM references rather than local var references throughout this section to allow
+ // for external users to override these as psuedo-supported APIs.
+ env.VM.checkRevision(templateSpec.compiler);
+
+ var invokePartialWrapper = function(partial, indent, name, context, hash, helpers, partials, data, depths) {
+ if (hash) {
+ context = Utils.extend({}, context, hash);
+ }
+
+ var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths);
+
+ if (result == null && env.compile) {
+ var options = { helpers: helpers, partials: partials, data: data, depths: depths };
+ partials[name] = env.compile(partial, { data: data !== undefined, compat: templateSpec.compat }, env);
+ result = partials[name](context, options);
+ }
+ if (result != null) {
+ if (indent) {
+ var lines = result.split('\n');
+ for (var i = 0, l = lines.length; i < l; i++) {
+ if (!lines[i] && i + 1 === l) {
+ break;
+ }
+
+ lines[i] = indent + lines[i];
+ }
+ result = lines.join('\n');
+ }
+ return result;
+ } else {
+ throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
+ }
+ };
+
// Just add water
var container = {
- escapeExpression: Handlebars.Utils.escapeExpression,
- invokePartial: Handlebars.VM.invokePartial,
+ lookup: function(depths, name) {
+ var len = depths.length;
+ for (var i = 0; i < len; i++) {
+ if (depths[i] && depths[i][name] != null) {
+ return depths[i][name];
+ }
+ }
+ },
+ lambda: function(current, context) {
+ return typeof current === 'function' ? current.call(context) : current;
+ },
+
+ escapeExpression: Utils.escapeExpression,
+ invokePartial: invokePartialWrapper,
+
+ fn: function(i) {
+ return templateSpec[i];
+ },
+
programs: [],
- program: function(i, fn, data) {
- var programWrapper = this.programs[i];
- if(data) {
- programWrapper = Handlebars.VM.program(i, fn, data);
+ program: function(i, data, depths) {
+ var programWrapper = this.programs[i],
+ fn = this.fn(i);
+ if (data || depths) {
+ programWrapper = program(this, i, fn, data, depths);
} else if (!programWrapper) {
- programWrapper = this.programs[i] = Handlebars.VM.program(i, fn);
+ programWrapper = this.programs[i] = program(this, i, fn);
}
return programWrapper;
},
+
+ data: function(data, depth) {
+ while (data && depth--) {
+ data = data._parent;
+ }
+ return data;
+ },
merge: function(param, common) {
var ret = param || common;
- if (param && common) {
- ret = {};
- Handlebars.Utils.extend(ret, common);
- Handlebars.Utils.extend(ret, param);
+ if (param && common && (param !== common)) {
+ ret = Utils.extend({}, common, param);
}
+
return ret;
},
- programWithDepth: Handlebars.VM.programWithDepth,
- noop: Handlebars.VM.noop,
- compilerInfo: null
+
+ noop: env.VM.noop,
+ compilerInfo: templateSpec.compiler
};
- return function(context, options) {
+ var ret = function(context, options) {
options = options || {};
- var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
+ var data = options.data;
- var compilerInfo = container.compilerInfo || [],
- compilerRevision = compilerInfo[0] || 1,
- currentRevision = Handlebars.COMPILER_REVISION;
-
- if (compilerRevision !== currentRevision) {
- if (compilerRevision < currentRevision) {
- var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
- compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
- throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
- "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
- } else {
- // Use the embedded version info since the runtime doesn't know about this revision yet
- throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
- "Please update your runtime to a newer version ("+compilerInfo[1]+").";
- }
+ ret._setup(options);
+ if (!options.partial && templateSpec.useData) {
+ data = initData(context, data);
+ }
+ var depths;
+ if (templateSpec.useDepths) {
+ depths = options.depths ? [context].concat(options.depths) : [context];
}
- return result;
+ return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths);
};
- },
+ ret.isTop = true;
- programWithDepth: function(i, fn, data /*, $depth */) {
- var args = Array.prototype.slice.call(arguments, 3);
+ ret._setup = function(options) {
+ if (!options.partial) {
+ container.helpers = container.merge(options.helpers, env.helpers);
- var program = function(context, options) {
+ if (templateSpec.usePartial) {
+ container.partials = container.merge(options.partials, env.partials);
+ }
+ } else {
+ container.helpers = options.helpers;
+ container.partials = options.partials;
+ }
+ };
+
+ ret._child = function(i, data, depths) {
+ if (templateSpec.useDepths && !depths) {
+ throw new Exception('must pass parent depths');
+ }
+
+ return program(container, i, templateSpec[i], data, depths);
+ };
+ return ret;
+ }
+
+ __exports__.template = template;function program(container, i, fn, data, depths) {
+ var prog = function(context, options) {
options = options || {};
- return fn.apply(this, [context, options.data || data].concat(args));
+ return fn.call(container, context, container.helpers, container.partials, options.data || data, depths && [context].concat(depths));
};
- program.program = i;
- program.depth = args.length;
- return program;
- },
- program: function(i, fn, data) {
- var program = function(context, options) {
- options = options || {};
+ prog.program = i;
+ prog.depth = depths ? depths.length : 0;
+ return prog;
+ }
- return fn(context, options.data || data);
- };
- program.program = i;
- program.depth = 0;
- return program;
- },
- noop: function() { return ""; },
- invokePartial: function(partial, name, context, helpers, partials, data) {
- var options = { helpers: helpers, partials: partials, data: data };
+ __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data, depths) {
+ var options = { partial: true, helpers: helpers, partials: partials, data: data, depths: depths };
if(partial === undefined) {
- throw new Handlebars.Exception("The partial " + name + " could not be found");
+ throw new Exception("The partial " + name + " could not be found");
} else if(partial instanceof Function) {
return partial(context, options);
- } else if (!Handlebars.compile) {
- throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
- } else {
- partials[name] = Handlebars.compile(partial, {data: data !== undefined});
- return partials[name](context, options);
}
}
-};
-Handlebars.template = Handlebars.VM.template;
-;
-// lib/handlebars/browser-suffix.js
-})(Handlebars);
-;
+ __exports__.invokePartial = invokePartial;function noop() { return ""; }
+
+ __exports__.noop = noop;function initData(context, data) {
+ if (!data || !('root' in data)) {
+ data = data ? createFrame(data) : {};
+ data.root = context;
+ }
+ return data;
+ }
+ return __exports__;
+})(__module2__, __module4__, __module1__);
+
+// handlebars.runtime.js
+var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
+ "use strict";
+ var __exports__;
+ /*globals Handlebars: true */
+ var base = __dependency1__;
+
+ // Each of these augment the Handlebars object. No need to setup here.
+ // (This is done to easily share code between commonjs and browse envs)
+ var SafeString = __dependency2__;
+ var Exception = __dependency3__;
+ var Utils = __dependency4__;
+ var runtime = __dependency5__;
+
+ // For compatibility and usage outside of module systems, make the Handlebars object a namespace
+ var create = function() {
+ var hb = new base.HandlebarsEnvironment();
+
+ Utils.extend(hb, base);
+ hb.SafeString = SafeString;
+ hb.Exception = Exception;
+ hb.Utils = Utils;
+ hb.escapeExpression = Utils.escapeExpression;
+
+ hb.VM = runtime;
+ hb.template = function(spec) {
+ return runtime.template(spec, hb);
+ };
+
+ return hb;
+ };
+
+ var Handlebars = create();
+ Handlebars.create = create;
+
+ Handlebars['default'] = Handlebars;
+
+ __exports__ = Handlebars;
+ return __exports__;
+})(__module1__, __module3__, __module4__, __module2__, __module5__);
+
+ return __module0__;
+}));
diff -r bee9255a428c5fcda5b3d3b03a7a3f38cdf5d7ff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d client/galaxy/scripts/libs/jquery/jquery.js
--- a/client/galaxy/scripts/libs/jquery/jquery.js
+++ b/client/galaxy/scripts/libs/jquery/jquery.js
@@ -1,5 +1,5 @@
/*!
- * jQuery JavaScript Library v1.11.1
+ * jQuery JavaScript Library v1.11.2
* http://jquery.com/
*
* Includes Sizzle.js
@@ -9,7 +9,7 @@
* Released under the MIT license
* http://jquery.org/license
*
- * Date: 2014-05-01T17:42Z
+ * Date: 2014-12-17T15:27Z
*/
(function( global, factory ) {
@@ -64,7 +64,7 @@
var
- version = "1.11.1",
+ version = "1.11.2",
// Define a local copy of jQuery
jQuery = function( selector, context ) {
@@ -269,7 +269,8 @@
// parseFloat NaNs numeric-cast false positives (null|true|false|"")
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
// subtraction forces infinities to NaN
- return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
+ // adding 1 corrects loss of precision from parseFloat (#15100)
+ return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
},
isEmptyObject: function( obj ) {
@@ -584,14 +585,14 @@
}
var Sizzle =
/*!
- * Sizzle CSS Selector Engine v1.10.19
+ * Sizzle CSS Selector Engine v2.2.0-pre
* http://sizzlejs.com/
*
- * Copyright 2013 jQuery Foundation, Inc. and other contributors
+ * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
- * Date: 2014-04-18
+ * Date: 2014-12-16
*/
(function( window ) {
@@ -618,7 +619,7 @@
contains,
// Instance-specific data
- expando = "sizzle" + -(new Date()),
+ expando = "sizzle" + 1 * new Date(),
preferredDoc = window.document,
dirruns = 0,
done = 0,
@@ -633,7 +634,6 @@
},
// General-purpose constants
- strundefined = typeof undefined,
MAX_NEGATIVE = 1 << 31,
// Instance methods
@@ -643,12 +643,13 @@
push_native = arr.push,
push = arr.push,
slice = arr.slice,
- // Use a stripped-down indexOf if we can't use a native one
- indexOf = arr.indexOf || function( elem ) {
+ // Use a stripped-down indexOf as it's faster than native
+ // http://jsperf.com/thor-indexof-vs-for/5
+ indexOf = function( list, elem ) {
var i = 0,
- len = this.length;
+ len = list.length;
for ( ; i < len; i++ ) {
- if ( this[i] === elem ) {
+ if ( list[i] === elem ) {
return i;
}
}
@@ -688,6 +689,7 @@
")\\)|)",
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
@@ -739,6 +741,14 @@
String.fromCharCode( high + 0x10000 ) :
// Supplemental Plane codepoint (surrogate pair)
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+ },
+
+ // Used for iframes
+ // See setDocument()
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE
+ unloadHandler = function() {
+ setDocument();
};
// Optimize for push.apply( _, NodeList )
@@ -781,19 +791,18 @@
context = context || document;
results = results || [];
-
- if ( !selector || typeof selector !== "string" ) {
+ nodeType = context.nodeType;
+
+ if ( typeof selector !== "string" || !selector ||
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
return results;
}
- if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
- return [];
- }
-
- if ( documentIsHTML && !seed ) {
-
- // Shortcuts
- if ( (match = rquickExpr.exec( selector )) ) {
+ if ( !seed && documentIsHTML ) {
+
+ // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
// Speed-up: Sizzle("#ID")
if ( (m = match[1]) ) {
if ( nodeType === 9 ) {
@@ -825,7 +834,7 @@
return results;
// Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
+ } else if ( (m = match[3]) && support.getElementsByClassName ) {
push.apply( results, context.getElementsByClassName( m ) );
return results;
}
@@ -835,7 +844,7 @@
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
nid = old = expando;
newContext = context;
- newSelector = nodeType === 9 && selector;
+ newSelector = nodeType !== 1 && selector;
// qSA works strangely on Element-rooted queries
// We can work around this by specifying an extra ID on the root
@@ -1022,7 +1031,7 @@
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
*/
function testContext( context ) {
- return context && typeof context.getElementsByTagName !== strundefined && context;
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
}
// Expose support vars for convenience
@@ -1046,9 +1055,8 @@
* @returns {Object} Returns the current document
*/
setDocument = Sizzle.setDocument = function( node ) {
- var hasCompare,
- doc = node ? node.ownerDocument || node : preferredDoc,
- parent = doc.defaultView;
+ var hasCompare, parent,
+ doc = node ? node.ownerDocument || node : preferredDoc;
// If no document and documentElement is available, return
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
@@ -1058,9 +1066,7 @@
// Set our document
document = doc;
docElem = doc.documentElement;
-
- // Support tests
- documentIsHTML = !isXML( doc );
+ parent = doc.defaultView;
// Support: IE>8
// If iframe document is assigned to "document" variable and if iframe has been reloaded,
@@ -1069,21 +1075,22 @@
if ( parent && parent !== parent.top ) {
// IE11 does not have attachEvent, so all must suffer
if ( parent.addEventListener ) {
- parent.addEventListener( "unload", function() {
- setDocument();
- }, false );
+ parent.addEventListener( "unload", unloadHandler, false );
} else if ( parent.attachEvent ) {
- parent.attachEvent( "onunload", function() {
- setDocument();
- });
- }
- }
+ parent.attachEvent( "onunload", unloadHandler );
+ }
+ }
+
+ /* Support tests
+ ---------------------------------------------------------------------- */
+ documentIsHTML = !isXML( doc );
/* Attributes
---------------------------------------------------------------------- */
// Support: IE<8
- // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
+ // Verify that getAttribute really returns attributes and not properties
+ // (excepting IE8 booleans)
support.attributes = assert(function( div ) {
div.className = "i";
return !div.getAttribute("className");
@@ -1098,17 +1105,8 @@
return !div.getElementsByTagName("*").length;
});
- // Check if getElementsByClassName can be trusted
- support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
- div.innerHTML = "<div class='a'></div><div class='a i'></div>";
-
- // Support: Safari<4
- // Catch class over-caching
- div.firstChild.className = "i";
- // Support: Opera<10
- // Catch gEBCN failure to find non-leading classes
- return div.getElementsByClassName("i").length === 2;
- });
+ // Support: IE<9
+ support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
// Support: IE<10
// Check if getElementById returns elements by name
@@ -1122,7 +1120,7 @@
// ID find and filter
if ( support.getById ) {
Expr.find["ID"] = function( id, context ) {
- if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
var m = context.getElementById( id );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
@@ -1143,7 +1141,7 @@
Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
- var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
return node && node.value === attrId;
};
};
@@ -1152,14 +1150,20 @@
// Tag
Expr.find["TAG"] = support.getElementsByTagName ?
function( tag, context ) {
- if ( typeof context.getElementsByTagName !== strundefined ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
return context.getElementsByTagName( tag );
+
+ // DocumentFragment nodes don't have gEBTN
+ } else if ( support.qsa ) {
+ return context.querySelectorAll( tag );
}
} :
+
function( tag, context ) {
var elem,
tmp = [],
i = 0,
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
results = context.getElementsByTagName( tag );
// Filter out possible comments
@@ -1177,7 +1181,7 @@
// Class
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
- if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
+ if ( documentIsHTML ) {
return context.getElementsByClassName( className );
}
};
@@ -1206,13 +1210,15 @@
// setting a boolean content attribute,
// since its presence should be enough
// http://bugs.jquery.com/ticket/12359
- div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
+ docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
+ "<select id='" + expando + "-\f]' msallowcapture=''>" +
+ "<option selected=''></option></select>";
// Support: IE8, Opera 11-12.16
// Nothing should be selected when empty strings follow ^= or $= or *=
// The test attribute must be unknown in Opera but "safe" for WinRT
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
- if ( div.querySelectorAll("[msallowclip^='']").length ) {
+ if ( div.querySelectorAll("[msallowcapture^='']").length ) {
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
}
@@ -1222,12 +1228,24 @@
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
}
+ // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
+ if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+ rbuggyQSA.push("~=");
+ }
+
// Webkit/Opera - :checked should return selected option elements
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
// IE8 throws error here and will not see later tests
if ( !div.querySelectorAll(":checked").length ) {
rbuggyQSA.push(":checked");
}
+
+ // Support: Safari 8+, iOS 8+
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
+ // In-page `selector#id sibing-combinator selector` fails
+ if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
+ rbuggyQSA.push(".#.+[+~]");
+ }
});
assert(function( div ) {
@@ -1344,7 +1362,7 @@
// Maintain original order
return sortInput ?
- ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
0;
}
@@ -1371,7 +1389,7 @@
aup ? -1 :
bup ? 1 :
sortInput ?
- ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
0;
// If the nodes are siblings, we can do a quick check
@@ -1434,7 +1452,7 @@
elem.document && elem.document.nodeType !== 11 ) {
return ret;
}
- } catch(e) {}
+ } catch (e) {}
}
return Sizzle( expr, document, null, [ elem ] ).length > 0;
@@ -1653,7 +1671,7 @@
return pattern ||
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
classCache( className, function( elem ) {
- return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
});
},
@@ -1675,7 +1693,7 @@
operator === "^=" ? check && result.indexOf( check ) === 0 :
operator === "*=" ? check && result.indexOf( check ) > -1 :
operator === "$=" ? check && result.slice( -check.length ) === check :
- operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
false;
};
@@ -1795,7 +1813,7 @@
matched = fn( seed, argument ),
i = matched.length;
while ( i-- ) {
- idx = indexOf.call( seed, matched[i] );
+ idx = indexOf( seed, matched[i] );
seed[ idx ] = !( matches[ idx ] = matched[i] );
}
}) :
@@ -1834,6 +1852,8 @@
function( elem, context, xml ) {
input[0] = elem;
matcher( input, null, xml, results );
+ // Don't keep the element (issue #299)
+ input[0] = null;
return !results.pop();
};
}),
@@ -1845,6 +1865,7 @@
}),
"contains": markFunction(function( text ) {
+ text = text.replace( runescape, funescape );
return function( elem ) {
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
};
@@ -2266,7 +2287,7 @@
i = matcherOut.length;
while ( i-- ) {
if ( (elem = matcherOut[i]) &&
- (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+ (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
seed[temp] = !(results[temp] = elem);
}
@@ -2301,13 +2322,16 @@
return elem === checkContext;
}, implicitRelative, true ),
matchAnyContext = addCombinator( function( elem ) {
- return indexOf.call( checkContext, elem ) > -1;
+ return indexOf( checkContext, elem ) > -1;
}, implicitRelative, true ),
matchers = [ function( elem, context, xml ) {
- return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
(checkContext = context).nodeType ?
matchContext( elem, context, xml ) :
matchAnyContext( elem, context, xml ) );
+ // Avoid hanging onto element (issue #299)
+ checkContext = null;
+ return ret;
} ];
for ( ; i < len; i++ ) {
@@ -2557,7 +2581,7 @@
// Sort stability
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-// Support: Chrome<14
+// Support: Chrome 14-35+
// Always assume duplicates if they aren't passed to the comparison function
support.detectDuplicates = !!hasDuplicate;
@@ -6115,7 +6139,14 @@
if ( window.getComputedStyle ) {
getStyles = function( elem ) {
- return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
+ // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
+ // IE throws on elements created in popups
+ // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
+ if ( elem.ownerDocument.defaultView.opener ) {
+ return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
+ }
+
+ return window.getComputedStyle( elem, null );
};
curCSS = function( elem, name, computed ) {
@@ -6363,6 +6394,8 @@
reliableMarginRightVal =
!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );
+
+ div.removeChild( contents );
}
// Support: IE8
@@ -9070,7 +9103,8 @@
}
// We can fire global events as of now if asked to
- fireGlobals = s.global;
+ // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
+ fireGlobals = jQuery.event && s.global;
// Watch for a new set of requests
if ( fireGlobals && jQuery.active++ === 0 ) {
@@ -9329,13 +9363,6 @@
};
});
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
- jQuery.fn[ type ] = function( fn ) {
- return this.on( type, fn );
- };
-});
-
jQuery._evalUrl = function( url ) {
return jQuery.ajax({
@@ -9561,8 +9588,9 @@
// Support: IE<10
// Open requests must be manually aborted on unload (#5280)
-if ( window.ActiveXObject ) {
- jQuery( window ).on( "unload", function() {
+// See https://support.microsoft.com/kb/2856746 for more info
+if ( window.attachEvent ) {
+ window.attachEvent( "onunload", function() {
for ( var key in xhrCallbacks ) {
xhrCallbacks[ key ]( undefined, true );
}
@@ -9996,6 +10024,16 @@
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
+ jQuery.fn[ type ] = function( fn ) {
+ return this.on( type, fn );
+ };
+});
+
+
+
+
jQuery.expr.filters.animated = function( elem ) {
return jQuery.grep(jQuery.timers, function( fn ) {
return elem === fn.elem;
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/galaxy/galaxy-central/commits/35ddbdd32fb3/
Changeset: 35ddbdd32fb3
User: erasche2
Date: 2015-02-05 23:37:10+00:00
Summary: Fixes for allowing custom entry
Affected #: 1 file
diff -r cf2636a3d9c3e29a4b045b4112de14f388e2168d -r 35ddbdd32fb3f36aadb7de52721f5ad66b753b8e templates/webapps/galaxy/history/share.mako
--- a/templates/webapps/galaxy/history/share.mako
+++ b/templates/webapps/galaxy/history/share.mako
@@ -59,38 +59,85 @@
/* This should be ripped out and made generic at some point for the
* various API bindings available, and once the API can filter list
* queries (term, below) */
+
+ var user_id = "${trans.security.encode_id(trans.user.id)}";
+ var history_id = "${trans.security.encode_id( history.id )}";
+
+ function item_to_label(item){
+ var text = "";
+ if(typeof(item.username) === "string" && typeof(item.email) === "string"){
+ text = item.username + " <" + item.email + ">";
+ }else if(typeof(item.username) === "string"){
+ text = item.username;
+ }else{
+ text = item.email;
+ }
+ return text;
+ //return "id:" + item.id + "|e:" + item.email + "|u:" + item.username;
+ }
+
$("#email_select").select2({
placeholder: "Select a user",
+ multiple: true,
+ initSelection: function(element, callback) {
+ var data = [
+ // Must be here to loop across the users that this has been shared with.
+ %for i, association in enumerate( history.users_shared_with ):
+ <% shared_with = association.user %>
+ {
+ email: "${ shared_with.email }",
+ id: "${trans.security.encode_id(shared_with.id)}",
+ text: item_to_label({"email": "${ shared_with.email }", "username": "${ shared_with.username }" })
+ },
+ %endfor
+ ];
+ callback(data);
+ },
+ tokenSeparators: [',', ' '],
+ // Required for initSelection
+ id: function(object) {
+ return object.id;
+ },
ajax: {
url: "${h.url_for(controller="/api/users", action="index")}",
- dataType: 'json',
- quietMillis: 250,
- matcher: function(term, text) { return text.toUpperCase().indexOf(term.toUpperCase())>=0; },
data: function (term) {
return {
f_email: term
};
},
+ dataType: 'json',
+ quietMillis: 250,
results: function (data) {
- var results = [];
- $.each(data, function(index, item){
- var text = "";
- if(typeof(item.username) === "string" && typeof(item.email) === "string"){
- text = item.username + " <" + item.email + ">";
- }else if(typeof(item.username) === "string"){
- text = item.username;
- }else{
- text = item.email;
+ var results = [];
+ // For every user returned by the API call,
+ $.each(data, function(index, item){
+ // If they aren't the requesting user, add to the
+ // list that will populate the select
+ if(item.id != "${trans.security.encode_id(trans.user.id)}"){
+ results.push({
+ id: item.id,
+ name: item.username,
+ text: item_to_label(item),
+ });
}
- results.push({
- id: item.email,
- name: item.username,
- text: text
- });
- });
- return {
- results: results
- };
+ });
+ return {
+ results: results
+ };
+ }
+ },
+ createSearchChoice: function(term, data) {
+ // Check for a user with a matching email.
+ var matches = _.filter(data, function(user){
+ return user.text.indexOf(term) > -1;
+ });
+ // If there aren't any users with matching object labels, then
+ // display a "default" entry with whatever text they're entering.
+ // id is set to term as that will be used in
+ if(matches.length == 0){
+ return {id: term, text:term};
+ }else{
+ // No extra needed
}
}
});
https://bitbucket.org/galaxy/galaxy-central/commits/d45c3a08dc0c/
Changeset: d45c3a08dc0c
User: erasche2
Date: 2015-02-09 21:17:40+00:00
Summary: Use suggestion from Carl to fix initial selection
Affected #: 1 file
diff -r 35ddbdd32fb3f36aadb7de52721f5ad66b753b8e -r d45c3a08dc0c3d4eb0cc3d88160253f4213bd1d4 templates/webapps/galaxy/history/share.mako
--- a/templates/webapps/galaxy/history/share.mako
+++ b/templates/webapps/galaxy/history/share.mako
@@ -36,8 +36,9 @@
</div><div style="clear: both"></div><div class="form-row">
+ <% existing_emails = [ d.user.email for d in history.users_shared_with ] %><label>Galaxy user emails with which to share histories</label>
- <input type="hidden" id="email_select" name="email" style="float: left; width: 250px; margin-right: 10px;">
+ <input type="hidden" id="email_select" name="email" value="${ existing_emails }" style="float: left; width: 250px; margin-right: 10px;"></input><div class="toolParamHelp" style="clear: both;">
Enter a Galaxy user email address or a comma-separated list of addresses if sharing with multiple users
https://bitbucket.org/galaxy/galaxy-central/commits/153887a934e6/
Changeset: 153887a934e6
User: erasche2
Date: 2015-02-12 20:32:10+00:00
Summary: Works correctly now
Affected #: 1 file
diff -r d45c3a08dc0c3d4eb0cc3d88160253f4213bd1d4 -r 153887a934e6ffa1c79b01ede9850126b2db2a76 templates/webapps/galaxy/history/share.mako
--- a/templates/webapps/galaxy/history/share.mako
+++ b/templates/webapps/galaxy/history/share.mako
@@ -36,7 +36,7 @@
</div><div style="clear: both"></div><div class="form-row">
- <% existing_emails = [ d.user.email for d in history.users_shared_with ] %>
+ <% existing_emails = ','.join([ d.user.email for d in history.users_shared_with ]) %><label>Galaxy user emails with which to share histories</label><input type="hidden" id="email_select" name="email" value="${ existing_emails }" style="float: left; width: 250px; margin-right: 10px;"></input>
https://bitbucket.org/galaxy/galaxy-central/commits/8519e2f351f8/
Changeset: 8519e2f351f8
User: dannon
Date: 2015-02-17 14:46:09+00:00
Summary: Merged in erasche2/galaxy-central (pull request #570)
Enable user/email list for sharing of datasets
Affected #: 5 files
diff -r 2e3855e25b9bdbe6e574a1795fe3dd4334e85eb7 -r 8519e2f351f82229ccec63f5b33ff719b8837fd5 config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -786,6 +786,14 @@
# public.
#new_user_dataset_access_role_default_private = False
+# Expose user list. Setting this to true will expose the user list to authenticated users. This
+# makes sharing datasets in smaller galaxy instances much easier as they can type a name/email and
+# have the correct user show up. This makes less sense on large public galaxy instances where
+# that data shouldn't be exposed. For semi-public galaxies, it may make sense to expose just the
+# username and not email, or vice versa.
+#expose_user_name = False
+#expose_user_email = False
+
# -- Beta features
# Use new tool form
diff -r 2e3855e25b9bdbe6e574a1795fe3dd4334e85eb7 -r 8519e2f351f82229ccec63f5b33ff719b8837fd5 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -106,6 +106,9 @@
self.user_label_filters = listify( kwargs.get( "user_tool_label_filters", [] ), do_strip=True )
self.user_section_filters = listify( kwargs.get( "user_tool_section_filters", [] ), do_strip=True )
+ self.expose_user_name = kwargs.get( "expose_user_name", False )
+ self.expose_user_email = kwargs.get( "expose_user_email", False )
+
# Check for tools defined in the above non-shed tool configs (i.e., tool_conf.xml) tht have
# been migrated from the Galaxy code distribution to the Tool Shed.
self.check_migrate_tools = string_as_bool( kwargs.get( 'check_migrate_tools', True ) )
diff -r 2e3855e25b9bdbe6e574a1795fe3dd4334e85eb7 -r 8519e2f351f82229ccec63f5b33ff719b8837fd5 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -131,7 +131,7 @@
histories, credentials, and roles.
"""
# attributes that will be accessed and returned when calling to_dict( view='collection' )
- dict_collection_visible_keys = ( 'id', 'email' )
+ dict_collection_visible_keys = ( 'id', 'email', 'username' )
# attributes that will be accessed and returned when calling to_dict( view='element' )
dict_element_visible_keys = ( 'id', 'email', 'username', 'total_disk_usage', 'nice_total_disk_usage' )
diff -r 2e3855e25b9bdbe6e574a1795fe3dd4334e85eb7 -r 8519e2f351f82229ccec63f5b33ff719b8837fd5 lib/galaxy/webapps/galaxy/api/users.py
--- a/lib/galaxy/webapps/galaxy/api/users.py
+++ b/lib/galaxy/webapps/galaxy/api/users.py
@@ -43,11 +43,19 @@
else:
query = query.filter( trans.app.model.User.table.c.deleted == False ) # noqa
# special case: user can see only their own user
- if not trans.user_is_admin():
+ # special case2: if the galaxy admin has specified that other user email/names are
+ # exposed, we don't want special case #1
+ if not trans.user_is_admin() and not trans.app.config.expose_user_name and not trans.app.config.expose_user_email:
item = trans.user.to_dict( value_mapper={ 'id': trans.security.encode_id } )
return [item]
for user in query:
item = user.to_dict( value_mapper={ 'id': trans.security.encode_id } )
+ # If NOT configured to expose_email, do not expose email UNLESS the user is self, or
+ # the user is an admin
+ if not trans.app.config.expose_user_name and user is not trans.user and not trans.user_is_admin():
+ del item['username']
+ if not trans.app.config.expose_user_email and user is not trans.user and not trans.user_is_admin():
+ del item['email']
# TODO: move into api_values
rval.append( item )
return rval
diff -r 2e3855e25b9bdbe6e574a1795fe3dd4334e85eb7 -r 8519e2f351f82229ccec63f5b33ff719b8837fd5 templates/webapps/galaxy/history/share.mako
--- a/templates/webapps/galaxy/history/share.mako
+++ b/templates/webapps/galaxy/history/share.mako
@@ -36,10 +36,10 @@
</div><div style="clear: both"></div><div class="form-row">
+ <% existing_emails = ','.join([ d.user.email for d in history.users_shared_with ]) %><label>Galaxy user emails with which to share histories</label>
- <div style="float: left; width: 250px; margin-right: 10px;">
- <input type="text" name="email" value="${email}" size="40">
- </div>
+ <input type="hidden" id="email_select" name="email" value="${ existing_emails }" style="float: left; width: 250px; margin-right: 10px;">
+ </input><div class="toolParamHelp" style="clear: both;">
Enter a Galaxy user email address or a comma-separated list of addresses if sharing with multiple users
</div>
@@ -55,6 +55,94 @@
<input type="submit" name="share_button" value="Submit"></div></form>
+ <script type="text/javascript">
+ // stolen from templates/admin/impersonate.mako
+ /* This should be ripped out and made generic at some point for the
+ * various API bindings available, and once the API can filter list
+ * queries (term, below) */
+
+ var user_id = "${trans.security.encode_id(trans.user.id)}";
+ var history_id = "${trans.security.encode_id( history.id )}";
+
+ function item_to_label(item){
+ var text = "";
+ if(typeof(item.username) === "string" && typeof(item.email) === "string"){
+ text = item.username + " <" + item.email + ">";
+ }else if(typeof(item.username) === "string"){
+ text = item.username;
+ }else{
+ text = item.email;
+ }
+ return text;
+ //return "id:" + item.id + "|e:" + item.email + "|u:" + item.username;
+ }
+
+ $("#email_select").select2({
+ placeholder: "Select a user",
+ multiple: true,
+ initSelection: function(element, callback) {
+ var data = [
+ // Must be here to loop across the users that this has been shared with.
+ %for i, association in enumerate( history.users_shared_with ):
+ <% shared_with = association.user %>
+ {
+ email: "${ shared_with.email }",
+ id: "${trans.security.encode_id(shared_with.id)}",
+ text: item_to_label({"email": "${ shared_with.email }", "username": "${ shared_with.username }" })
+ },
+ %endfor
+ ];
+ callback(data);
+ },
+ tokenSeparators: [',', ' '],
+ // Required for initSelection
+ id: function(object) {
+ return object.id;
+ },
+ ajax: {
+ url: "${h.url_for(controller="/api/users", action="index")}",
+ data: function (term) {
+ return {
+ f_email: term
+ };
+ },
+ dataType: 'json',
+ quietMillis: 250,
+ results: function (data) {
+ var results = [];
+ // For every user returned by the API call,
+ $.each(data, function(index, item){
+ // If they aren't the requesting user, add to the
+ // list that will populate the select
+ if(item.id != "${trans.security.encode_id(trans.user.id)}"){
+ results.push({
+ id: item.id,
+ name: item.username,
+ text: item_to_label(item),
+ });
+ }
+ });
+ return {
+ results: results
+ };
+ }
+ },
+ createSearchChoice: function(term, data) {
+ // Check for a user with a matching email.
+ var matches = _.filter(data, function(user){
+ return user.text.indexOf(term) > -1;
+ });
+ // If there aren't any users with matching object labels, then
+ // display a "default" entry with whatever text they're entering.
+ // id is set to term as that will be used in
+ if(matches.length == 0){
+ return {id: term, text:term};
+ }else{
+ // No extra needed
+ }
+ }
+ });
+ </script>
%else:
## We are sharing restricted histories
%if no_change_needed or can_change:
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/1d6063120517/
Changeset: 1d6063120517
User: dannon
Date: 2015-02-17 14:26:53+00:00
Summary: Update requirements.txt for SQLAlchemy 0.9.8 (tip)
Affected #: 1 file
diff -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e -r 1d60631205172f867df03cb37eb0cb45cb2811fc requirements.txt
--- a/requirements.txt
+++ b/requirements.txt
@@ -14,14 +14,14 @@
# starting a Galaxy server. Use this in conjunction with the
# `GALAXY_ENABLE_EGGS=False` environment variable.
#
-# Note that except in the case of SQLAlchemy and Whoosh, all dependencies will
-# be installed at their newest versions. Galaxy has not been tested with these
-# and you may (likely?) run into problems! The Galaxy Team does not support
-# using Galaxy with dependency versions other than those in eggs.ini, however,
-# if you do find an incompatibility between Galaxy and the latest version, we
-# would appreciate if you would investigate and provide a code fix for the
-# issue. We are trying to move away from our strict version dependency policy
-# and this would greatly help in our efforts.
+# Note that except in the case of Whoosh, all dependencies will be installed at
+# their newest versions. Galaxy has not been tested with these and you may
+# (likely?) run into problems! The Galaxy Team does not support using Galaxy
+# with dependency versions other than those in eggs.ini, however, if you do
+# find an incompatibility between Galaxy and the latest version, we would
+# appreciate if you would investigate and provide a code fix for the issue. We
+# are trying to move away from our strict version dependency policy and this
+# would greatly help in our efforts.
Paste
PasteDeploy
@@ -32,7 +32,7 @@
repoze.lru
Routes
WebOb
-SQLAlchemy<0.8
+SQLAlchemy
Cheetah
pycrypto
MarkupSafe
https://bitbucket.org/galaxy/galaxy-central/commits/2e3855e25b9b/
Changeset: 2e3855e25b9b
User: dannon
Date: 2015-02-17 14:27:27+00:00
Summary: Merge.
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
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: caf8efbfc7325256a8256362c3e61d96f5729d01
https://github.com/galaxyproject/usegalaxy-playbook/commit/caf8efbfc7325256…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2015-02-17 (Tue, 17 Feb 2015)
Changed paths:
M files/galaxy/test.galaxyproject.org/var/integrated_tool_panel.xml
M stage/group_vars/all.yml
Log Message:
-----------
Update Test
1
0
commit/galaxy-central: natefoo: Allow latest SQLAlchemy in requirements.txt
by commits-noreply@bitbucket.org 17 Feb '15
by commits-noreply@bitbucket.org 17 Feb '15
17 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/963441341870/
Changeset: 963441341870
User: natefoo
Date: 2015-02-17 14:23:34+00:00
Summary: Allow latest SQLAlchemy in requirements.txt
Affected #: 1 file
diff -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e -r 963441341870819e393a8958b8da7633b4eecb28 requirements.txt
--- a/requirements.txt
+++ b/requirements.txt
@@ -14,14 +14,14 @@
# starting a Galaxy server. Use this in conjunction with the
# `GALAXY_ENABLE_EGGS=False` environment variable.
#
-# Note that except in the case of SQLAlchemy and Whoosh, all dependencies will
-# be installed at their newest versions. Galaxy has not been tested with these
-# and you may (likely?) run into problems! The Galaxy Team does not support
-# using Galaxy with dependency versions other than those in eggs.ini, however,
-# if you do find an incompatibility between Galaxy and the latest version, we
-# would appreciate if you would investigate and provide a code fix for the
-# issue. We are trying to move away from our strict version dependency policy
-# and this would greatly help in our efforts.
+# Note that except in the case of Whoosh, all dependencies will be installed at
+# their newest versions. Galaxy has not been tested with these and you may
+# (likely?) run into problems! The Galaxy Team does not support using Galaxy
+# with dependency versions other than those in eggs.ini, however, if you do
+# find an incompatibility between Galaxy and the latest version, we would
+# appreciate if you would investigate and provide a code fix for the issue. We
+# are trying to move away from our strict version dependency policy and this
+# would greatly help in our efforts.
Paste
PasteDeploy
@@ -32,7 +32,7 @@
repoze.lru
Routes
WebOb
-SQLAlchemy<0.8
+SQLAlchemy
Cheetah
pycrypto
MarkupSafe
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
11 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8863e5c7e686/
Changeset: 8863e5c7e686
User: dannon
Date: 2015-02-14 15:16:13+00:00
Summary: Initial update of SQLAlchemy to 0.8.7. Definitely still needs testing.
Affected #: 2 files
diff -r b5e29b7e30995a1f67384ce50a490383ee16083c -r 8863e5c7e686f18ddbacabbece22ed8a81c8c45c eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -26,7 +26,7 @@
pysqlite = 2.5.6
python_lzo = 1.08_2.03_static
PyYAML = 3.10
-SQLAlchemy = 0.7.9
+SQLAlchemy = 0.8.7
; msgpack_python = 0.2.4
[eggs:noplatform]
@@ -62,7 +62,8 @@
Routes = 2.1
simplejson = 2.1.1
six = 1.9.0
-sqlalchemy_migrate = 0.7.2
+sqlalchemy_migrate = 0.9.4
+sqlparse = 0.1.14
ssh = 1.7.14
SVGFig = 1.1.6
Tempita = 0.5.1
diff -r b5e29b7e30995a1f67384ce50a490383ee16083c -r 8863e5c7e686f18ddbacabbece22ed8a81c8c45c lib/galaxy/model/migrate/check.py
--- a/lib/galaxy/model/migrate/check.py
+++ b/lib/galaxy/model/migrate/check.py
@@ -4,8 +4,10 @@
from galaxy import eggs
eggs.require( "SQLAlchemy" )
-eggs.require( "decorator" ) #Required by sqlalchemy-migrate
-eggs.require( "Tempita " ) #Required by sqlalchemy-migrate
+eggs.require( "six" ) # Required by sqlalchemy-migrate
+eggs.require( "sqlparse" ) # Required by sqlalchemy-migrate
+eggs.require( "decorator" ) # Required by sqlalchemy-migrate
+eggs.require( "Tempita " ) # Required by sqlalchemy-migrate
eggs.require( "sqlalchemy-migrate" )
from sqlalchemy import *
https://bitbucket.org/galaxy/galaxy-central/commits/d98b6a04b8b8/
Changeset: d98b6a04b8b8
User: dannon
Date: 2015-02-14 15:16:44+00:00
Summary: Fix references to (long deprecated) sqlalchemy.exceptions
Affected #: 2 files
diff -r 8863e5c7e686f18ddbacabbece22ed8a81c8c45c -r d98b6a04b8b85dcd2e0f93876a04079576dda168 lib/galaxy/managers/users.py
--- a/lib/galaxy/managers/users.py
+++ b/lib/galaxy/managers/users.py
@@ -54,7 +54,7 @@
try:
self.app.model.context.flush()
#TODO:?? flush needed for permissions below? If not, make optional
- except sqlalchemy.exceptions.IntegrityError, db_err:
+ except sqlalchemy.exc.IntegrityError, db_err:
raise exceptions.Conflict( db_err.message )
# can throw an sqlalx.IntegrityError if username not unique
diff -r 8863e5c7e686f18ddbacabbece22ed8a81c8c45c -r d98b6a04b8b85dcd2e0f93876a04079576dda168 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py
+++ b/lib/galaxy/model/mapping.py
@@ -1723,7 +1723,7 @@
active_folders=relation( model.LibraryFolder,
primaryjoin=( ( model.LibraryFolder.table.c.parent_id == model.LibraryFolder.table.c.id ) & ( not_( model.LibraryFolder.table.c.deleted ) ) ),
order_by=asc( model.LibraryFolder.table.c.name ),
- lazy=True, #"""sqlalchemy.exceptions.ArgumentError: Error creating eager relationship 'active_folders' on parent class '<class 'galaxy.model.LibraryFolder'>' to child class '<class 'galaxy.model.LibraryFolder'>': Cant use eager loading on a self referential relationship."""
+ lazy=True, #"""sqlalchemy.exc.ArgumentError: Error creating eager relationship 'active_folders' on parent class '<class 'galaxy.model.LibraryFolder'>' to child class '<class 'galaxy.model.LibraryFolder'>': Cant use eager loading on a self referential relationship."""
viewonly=True ),
datasets=relation( model.LibraryDataset,
primaryjoin=( ( model.LibraryDataset.table.c.folder_id == model.LibraryFolder.table.c.id ) ),
https://bitbucket.org/galaxy/galaxy-central/commits/489925951973/
Changeset: 489925951973
User: dannon
Date: 2015-02-14 15:35:42+00:00
Summary: Add all the necessary dependency requires. Note to self: fix the egg dependency resolution bug so we don't have to dot his.
Affected #: 6 files
diff -r d98b6a04b8b85dcd2e0f93876a04079576dda168 -r 48992595197338928f7b92f8574b192f8c54b577 lib/galaxy/model/orm/scripts.py
--- a/lib/galaxy/model/orm/scripts.py
+++ b/lib/galaxy/model/orm/scripts.py
@@ -9,6 +9,8 @@
eggs.require( "decorator" )
eggs.require( "Tempita" )
eggs.require( "SQLAlchemy" )
+eggs.require( "six" ) # required by sqlalchemy-migrate
+eggs.require( "sqlparse" ) # required by sqlalchemy-migrate
eggs.require( "sqlalchemy_migrate" )
from galaxy.util.properties import load_app_properties
diff -r d98b6a04b8b85dcd2e0f93876a04079576dda168 -r 48992595197338928f7b92f8574b192f8c54b577 lib/galaxy/model/tool_shed_install/migrate/check.py
--- a/lib/galaxy/model/tool_shed_install/migrate/check.py
+++ b/lib/galaxy/model/tool_shed_install/migrate/check.py
@@ -4,6 +4,8 @@
from galaxy import eggs
eggs.require( "SQLAlchemy" )
+eggs.require( "six" ) # Required by sqlalchemy-migrate
+eggs.require( "sqlparse" ) # Required by sqlalchemy-migrate
eggs.require( "decorator" ) # Required by sqlalchemy-migrate
eggs.require( "Tempita " ) # Required by sqlalchemy-migrate
eggs.require( "sqlalchemy-migrate" )
diff -r d98b6a04b8b85dcd2e0f93876a04079576dda168 -r 48992595197338928f7b92f8574b192f8c54b577 lib/galaxy/webapps/tool_shed/model/migrate/check.py
--- a/lib/galaxy/webapps/tool_shed/model/migrate/check.py
+++ b/lib/galaxy/webapps/tool_shed/model/migrate/check.py
@@ -2,11 +2,12 @@
from galaxy import eggs
-import pkg_resources
-pkg_resources.require( "SQLAlchemy" )
-pkg_resources.require( "decorator" )
-pkg_resources.require( "sqlalchemy-migrate" )
-pkg_resources.require( "Tempita" )
+eggs.require( "SQLAlchemy" )
+eggs.require( "decorator" )
+eggs.require( "six" ) # Required by sqlalchemy-migrate
+eggs.require( "sqlparse" ) # Required by sqlalchemy-migrate
+eggs.require( "sqlalchemy-migrate" )
+eggs.require( "Tempita" )
from migrate.versioning import repository, schema
diff -r d98b6a04b8b85dcd2e0f93876a04079576dda168 -r 48992595197338928f7b92f8574b192f8c54b577 lib/tool_shed/galaxy_install/migrate/check.py
--- a/lib/tool_shed/galaxy_install/migrate/check.py
+++ b/lib/tool_shed/galaxy_install/migrate/check.py
@@ -5,6 +5,8 @@
from galaxy import eggs
eggs.require( "decorator" )
eggs.require( "Tempita" )
+eggs.require( "six" ) # Required by sqlalchemy-migrate
+eggs.require( "sqlparse" ) # Required by sqlalchemy-migrate
eggs.require( "SQLAlchemy" )
eggs.require( "sqlalchemy_migrate" )
from migrate.versioning import repository
diff -r d98b6a04b8b85dcd2e0f93876a04079576dda168 -r 48992595197338928f7b92f8574b192f8c54b577 scripts/manage_db.py
--- a/scripts/manage_db.py
+++ b/scripts/manage_db.py
@@ -13,6 +13,8 @@
eggs.require( "decorator" )
eggs.require( "Tempita" )
eggs.require( "SQLAlchemy" )
+eggs.require( "six" ) # Required by sqlalchemy-migrate
+eggs.require( "sqlparse" ) # Required by sqlalchemy-migrate
eggs.require( "sqlalchemy_migrate" )
from migrate.versioning.shell import main
diff -r d98b6a04b8b85dcd2e0f93876a04079576dda168 -r 48992595197338928f7b92f8574b192f8c54b577 scripts/manage_tools.py
--- a/scripts/manage_tools.py
+++ b/scripts/manage_tools.py
@@ -8,11 +8,12 @@
from galaxy import eggs
-import pkg_resources
-pkg_resources.require( "SQLAlchemy" )
-pkg_resources.require( "decorator" )
-pkg_resources.require( "Tempita " )
-pkg_resources.require( "sqlalchemy-migrate" )
+eggs.require( "SQLAlchemy" )
+eggs.require( "decorator" )
+eggs.require( "Tempita " )
+eggs.require( "six" ) # Required by sqlalchemy-migrate
+eggs.require( "sqlparse" ) # Required by sqlalchemy-migrate
+eggs.require( "sqlalchemy-migrate" )
from migrate.versioning.shell import main
from ConfigParser import SafeConfigParser
https://bitbucket.org/galaxy/galaxy-central/commits/477ebeedaf0c/
Changeset: 477ebeedaf0c
User: dannon
Date: 2015-02-14 15:38:09+00:00
Summary: Merge.
Affected #: 1 file
diff -r 48992595197338928f7b92f8574b192f8c54b577 -r 477ebeedaf0c845811602e28ea0ec3d3362d3c2a requirements.txt
--- a/requirements.txt
+++ b/requirements.txt
@@ -14,14 +14,14 @@
# starting a Galaxy server. Use this in conjunction with the
# `GALAXY_ENABLE_EGGS=False` environment variable.
#
-# Note that except in the case of SQLAlchemy, all dependencies will be
-# installed at their newest versions. Galaxy has not been tested with these and
-# you may (likely?) run into problems! The Galaxy Team does not support using
-# Galaxy with dependency versions other than those in eggs.ini, however, if you
-# do find an incompatibility between Galaxy and the latest version, we would
-# appreciate if you would investigate and provide a code fix for the issue. We
-# are trying to move away from our strict version dependency policy and this
-# would greatly help in our efforts.
+# Note that except in the case of SQLAlchemy and Whoosh, all dependencies will
+# be installed at their newest versions. Galaxy has not been tested with these
+# and you may (likely?) run into problems! The Galaxy Team does not support
+# using Galaxy with dependency versions other than those in eggs.ini, however,
+# if you do find an incompatibility between Galaxy and the latest version, we
+# would appreciate if you would investigate and provide a code fix for the
+# issue. We are trying to move away from our strict version dependency policy
+# and this would greatly help in our efforts.
Paste
PasteDeploy
https://bitbucket.org/galaxy/galaxy-central/commits/7f780e8c98aa/
Changeset: 7f780e8c98aa
User: dannon
Date: 2015-02-14 15:55:17+00:00
Summary: Merge.
Affected #: 1 file
diff -r 477ebeedaf0c845811602e28ea0ec3d3362d3c2a -r 7f780e8c98aa951432ccc89eb00a697c8d957048 lib/galaxy/util/__init__.py
--- a/lib/galaxy/util/__init__.py
+++ b/lib/galaxy/util/__init__.py
@@ -519,7 +519,7 @@
# This can manipulate the input other than just masking password,
# so the previous string replace method is preferred when the
# password doesn't appear twice in the url
- split._replace(netloc=split.netloc.replace("%s:%s" % (split.username, split.password), '%s:********' % split.username))
+ split = split._replace(netloc=split.netloc.replace("%s:%s" % (split.username, split.password), '%s:********' % split.username))
url = urlparse.urlunsplit(split)
return url
https://bitbucket.org/galaxy/galaxy-central/commits/af7603a13e8d/
Changeset: af7603a13e8d
User: dannon
Date: 2015-02-14 16:05:54+00:00
Summary: Merge.
Affected #: 1 file
diff -r 7f780e8c98aa951432ccc89eb00a697c8d957048 -r af7603a13e8d5340f064312808b6ebfb56d1a959 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -548,7 +548,7 @@
pass
#process change_format tags
- if output.change_format:
+ if output.change_format is not None:
new_format_set = False
for change_elem in output.change_format:
for when_elem in change_elem.findall( 'when' ):
https://bitbucket.org/galaxy/galaxy-central/commits/4909df6a1dbd/
Changeset: 4909df6a1dbd
User: dannon
Date: 2015-02-16 16:17:51+00:00
Summary: Merge.
Affected #: 14 files
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 client/galaxy/scripts/mvc/tools/tools-form-workflow.js
--- a/client/galaxy/scripts/mvc/tools/tools-form-workflow.js
+++ b/client/galaxy/scripts/mvc/tools/tools-form-workflow.js
@@ -21,8 +21,8 @@
this.options = options;
// set labels
- this.options.text_enable = 'In Advance';
- this.options.text_disable = 'At Runtime';
+ this.options.text_enable = 'Set in Advance';
+ this.options.text_disable = 'Set at Runtime';
// configure workflow style
this.options.is_dynamic = false;
@@ -33,7 +33,7 @@
// declare fields as optional
Utils.deepeach(options.inputs, function(item) {
if (item.type) {
- item.optional = (['data', 'data_hidden', 'hidden', 'drill_down', 'repeat', 'conditional']).indexOf(item.type) == -1;
+ item.optional = (['data', 'data_hidden', 'hidden', 'repeat', 'conditional']).indexOf(item.type) == -1;
}
});
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 client/galaxy/scripts/mvc/tools/tools-input.js
--- a/client/galaxy/scripts/mvc/tools/tools-input.js
+++ b/client/galaxy/scripts/mvc/tools/tools-input.js
@@ -9,52 +9,56 @@
initialize: function(app, options) {
// link app
this.app = app;
-
- // set text labels
- this.text_enable = app.options.text_enable || 'Enable';
- this.text_disable = app.options.text_disable || 'Disable';
+
+ // set text labels and icons for optional button
+ this.text_enable = app.options.text_enable || 'Enable';
+ this.text_disable = app.options.text_disable || 'Disable';
+ this.cls_enable = app.options.cls_enable || 'fa fa-plus-square';
+ this.cls_disable = app.options.cls_disable || 'fa fa-minus-square';
// link field
this.field = options.field;
this.default_value = options.default_value;
-
+
// set element
this.setElement(this._template(options));
-
+
// link elements
this.$field = this.$el.find('.ui-table-form-field');
- this.$title_optional = this.$el.find('.ui-table-form-title-optional');
+ this.$optional = this.$el.find('.ui-table-form-optional');
+ this.$optional_icon = this.$el.find('.ui-table-form-optional').find('.icon');
this.$error_text = this.$el.find('.ui-table-form-error-text');
this.$error = this.$el.find('.ui-table-form-error');
-
+
// add field element
this.$field.prepend(this.field.$el);
-
+
// decide wether to expand or collapse optional fields
this.field.skip = false;
var v = this.field.value && this.field.value();
this.field.skip = Boolean(options.optional &&
- (v === null || v == this.default_value ||
- Number(v) == Number(this.default_value) ||
- JSON.stringify(v) == JSON.stringify(this.default_value)));
+ (v === null || v === '' || v === this.default_value ||
+ String(v) === String(this.default_value) ||
+ Number(v) === Number(this.default_value) ||
+ JSON.stringify(v) === JSON.stringify(this.default_value)));
// refresh view
this._refresh();
-
+
// add optional hide/show
var self = this;
- this.$title_optional.on('click', function() {
+ this.$optional.on('click', function() {
// flip flag
self.field.skip = !self.field.skip;
-
+
// refresh view
self._refresh();
-
+
// refresh state
self.app.trigger('refresh');
});
},
-
+
/** Set error text
*/
error: function(text) {
@@ -62,27 +66,46 @@
this.$error.show();
this.$el.addClass('ui-error');
},
-
+
/** Reset this view
*/
reset: function() {
this.$error.hide();
this.$el.removeClass('ui-error');
},
-
+
/** Refresh element
*/
_refresh: function() {
+ // reset optional button
+ this.$optional_icon.removeClass().addClass('icon');
+
+ // identify state
if (!this.field.skip) {
+ // enable input field
this.$field.fadeIn('fast');
- this.$title_optional.html(this.text_disable);
+ this._tooltip(this.text_disable, this.cls_disable);
+
} else {
+ // disable input field
this.$field.hide();
- this.$title_optional.html(this.text_enable);
+ this._tooltip(this.text_enable, this.cls_enable);
+ // reset field value
this.field.value && this.field.value(this.default_value);
}
},
-
+
+ /** Set tooltip text
+ */
+ _tooltip: function(title, cls) {
+ if (this.$optional.length) {
+ this.$optional_icon.addClass(cls)
+ .tooltip({ placement: 'bottom' })
+ .attr('data-original-title', title)
+ .tooltip('fixTitle').tooltip('hide');
+ }
+ },
+
/** Main Template
*/
_template: function(options) {
@@ -91,30 +114,34 @@
'<div class="ui-table-form-error ui-error">' +
'<span class="fa fa-arrow-down"/><span class="ui-table-form-error-text"/>' +
'</div>' +
- '<div class="ui-table-form-title-strong">';
-
+ '<div class="ui-table-form-title">';
+
// is optional
if (options.optional) {
- tmp += options.label +
- '<span> [<span class="ui-table-form-title-optional"/>]</span>';
+ tmp += '<div class="ui-table-form-optional">' +
+ '<i class="icon"/>' + options.label +
+ '</div>';
} else {
- tmp += options.label;
+ tmp += options.label;
}
-
+
// finalize title
tmp += '</div>' +
'<div class="ui-table-form-field">';
+
// add help
+ tmp += '<div class="ui-table-form-info">';
if (options.help) {
- tmp += '<div class="ui-table-form-info">' + options.help + '</div>';
+ tmp += options.help;
}
+ tmp += '</div>';
// finalize
tmp += '</div>' +
'</div>';
-
+
// return input element
return tmp;
}
});
-});
+});
\ No newline at end of file
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 client/galaxy/scripts/mvc/ui/ui-button-check.js
--- a/client/galaxy/scripts/mvc/ui/ui-button-check.js
+++ b/client/galaxy/scripts/mvc/ui/ui-button-check.js
@@ -35,7 +35,7 @@
if (new_val !== undefined) {
this.current = new_val;
this.$el.removeClass()
- .addClass('ui-checkbutton')
+ .addClass('ui-button-check')
.addClass(this.options.icons[new_val]);
this.options.onchange && this.options.onchange(new_val);
}
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 client/galaxy/scripts/mvc/ui/ui-misc.js
--- a/client/galaxy/scripts/mvc/ui/ui-misc.js
+++ b/client/galaxy/scripts/mvc/ui/ui-misc.js
@@ -447,7 +447,7 @@
_template: function(options) {
var tmpl = '<div id="' + options.id + '" >';
if (options.info) {
- tmpl += '<label>' + options.info + '</label>';
+ tmpl += '<div>' + options.info + '</div>';
}
tmpl += '<hidden value="' + options.value + '"/>' +
'</div>';
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/scripts/mvc/tools/tools-form-workflow.js
--- a/static/scripts/mvc/tools/tools-form-workflow.js
+++ b/static/scripts/mvc/tools/tools-form-workflow.js
@@ -21,8 +21,8 @@
this.options = options;
// set labels
- this.options.text_enable = 'In Advance';
- this.options.text_disable = 'At Runtime';
+ this.options.text_enable = 'Set in Advance';
+ this.options.text_disable = 'Set at Runtime';
// configure workflow style
this.options.is_dynamic = false;
@@ -33,7 +33,7 @@
// declare fields as optional
Utils.deepeach(options.inputs, function(item) {
if (item.type) {
- item.optional = (['data', 'data_hidden', 'hidden', 'drill_down', 'repeat', 'conditional']).indexOf(item.type) == -1;
+ item.optional = (['data', 'data_hidden', 'hidden', 'repeat', 'conditional']).indexOf(item.type) == -1;
}
});
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/scripts/mvc/tools/tools-input.js
--- a/static/scripts/mvc/tools/tools-input.js
+++ b/static/scripts/mvc/tools/tools-input.js
@@ -9,52 +9,56 @@
initialize: function(app, options) {
// link app
this.app = app;
-
- // set text labels
- this.text_enable = app.options.text_enable || 'Enable';
- this.text_disable = app.options.text_disable || 'Disable';
+
+ // set text labels and icons for optional button
+ this.text_enable = app.options.text_enable || 'Enable';
+ this.text_disable = app.options.text_disable || 'Disable';
+ this.cls_enable = app.options.cls_enable || 'fa fa-plus-square';
+ this.cls_disable = app.options.cls_disable || 'fa fa-minus-square';
// link field
this.field = options.field;
this.default_value = options.default_value;
-
+
// set element
this.setElement(this._template(options));
-
+
// link elements
this.$field = this.$el.find('.ui-table-form-field');
- this.$title_optional = this.$el.find('.ui-table-form-title-optional');
+ this.$optional = this.$el.find('.ui-table-form-optional');
+ this.$optional_icon = this.$el.find('.ui-table-form-optional').find('.icon');
this.$error_text = this.$el.find('.ui-table-form-error-text');
this.$error = this.$el.find('.ui-table-form-error');
-
+
// add field element
this.$field.prepend(this.field.$el);
-
+
// decide wether to expand or collapse optional fields
this.field.skip = false;
var v = this.field.value && this.field.value();
this.field.skip = Boolean(options.optional &&
- (v === null || v == this.default_value ||
- Number(v) == Number(this.default_value) ||
- JSON.stringify(v) == JSON.stringify(this.default_value)));
+ (v === null || v === '' || v === this.default_value ||
+ String(v) === String(this.default_value) ||
+ Number(v) === Number(this.default_value) ||
+ JSON.stringify(v) === JSON.stringify(this.default_value)));
// refresh view
this._refresh();
-
+
// add optional hide/show
var self = this;
- this.$title_optional.on('click', function() {
+ this.$optional.on('click', function() {
// flip flag
self.field.skip = !self.field.skip;
-
+
// refresh view
self._refresh();
-
+
// refresh state
self.app.trigger('refresh');
});
},
-
+
/** Set error text
*/
error: function(text) {
@@ -62,27 +66,46 @@
this.$error.show();
this.$el.addClass('ui-error');
},
-
+
/** Reset this view
*/
reset: function() {
this.$error.hide();
this.$el.removeClass('ui-error');
},
-
+
/** Refresh element
*/
_refresh: function() {
+ // reset optional button
+ this.$optional_icon.removeClass().addClass('icon');
+
+ // identify state
if (!this.field.skip) {
+ // enable input field
this.$field.fadeIn('fast');
- this.$title_optional.html(this.text_disable);
+ this._tooltip(this.text_disable, this.cls_disable);
+
} else {
+ // disable input field
this.$field.hide();
- this.$title_optional.html(this.text_enable);
+ this._tooltip(this.text_enable, this.cls_enable);
+ // reset field value
this.field.value && this.field.value(this.default_value);
}
},
-
+
+ /** Set tooltip text
+ */
+ _tooltip: function(title, cls) {
+ if (this.$optional.length) {
+ this.$optional_icon.addClass(cls)
+ .tooltip({ placement: 'bottom' })
+ .attr('data-original-title', title)
+ .tooltip('fixTitle').tooltip('hide');
+ }
+ },
+
/** Main Template
*/
_template: function(options) {
@@ -91,30 +114,34 @@
'<div class="ui-table-form-error ui-error">' +
'<span class="fa fa-arrow-down"/><span class="ui-table-form-error-text"/>' +
'</div>' +
- '<div class="ui-table-form-title-strong">';
-
+ '<div class="ui-table-form-title">';
+
// is optional
if (options.optional) {
- tmp += options.label +
- '<span> [<span class="ui-table-form-title-optional"/>]</span>';
+ tmp += '<div class="ui-table-form-optional">' +
+ '<i class="icon"/>' + options.label +
+ '</div>';
} else {
- tmp += options.label;
+ tmp += options.label;
}
-
+
// finalize title
tmp += '</div>' +
'<div class="ui-table-form-field">';
+
// add help
+ tmp += '<div class="ui-table-form-info">';
if (options.help) {
- tmp += '<div class="ui-table-form-info">' + options.help + '</div>';
+ tmp += options.help;
}
+ tmp += '</div>';
// finalize
tmp += '</div>' +
'</div>';
-
+
// return input element
return tmp;
}
});
-});
+});
\ No newline at end of file
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/scripts/mvc/ui/ui-button-check.js
--- a/static/scripts/mvc/ui/ui-button-check.js
+++ b/static/scripts/mvc/ui/ui-button-check.js
@@ -35,7 +35,7 @@
if (new_val !== undefined) {
this.current = new_val;
this.$el.removeClass()
- .addClass('ui-checkbutton')
+ .addClass('ui-button-check')
.addClass(this.options.icons[new_val]);
this.options.onchange && this.options.onchange(new_val);
}
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/scripts/mvc/ui/ui-misc.js
--- a/static/scripts/mvc/ui/ui-misc.js
+++ b/static/scripts/mvc/ui/ui-misc.js
@@ -447,7 +447,7 @@
_template: function(options) {
var tmpl = '<div id="' + options.id + '" >';
if (options.info) {
- tmpl += '<label>' + options.info + '</label>';
+ tmpl += '<div>' + options.info + '</div>';
}
tmpl += '<hidden value="' + options.value + '"/>' +
'</div>';
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/scripts/packed/mvc/tools/tools-form-workflow.js
--- a/static/scripts/packed/mvc/tools/tools-form-workflow.js
+++ b/static/scripts/packed/mvc/tools/tools-form-workflow.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/tools/tools-form-base"],function(b,a){var c=a.extend({initialize:function(e){this.node=workflow.active_node;if(!this.node){console.debug("FAILED - tools-form-workflow:initialize() - Node not found in workflow.");return}this.post_job_actions=this.node.post_job_actions||{};this.options=e;this.options.text_enable="In Advance";this.options.text_disable="At Runtime";this.options.is_dynamic=false;this.options.narrow=true;this.options.initial_errors=true;this.options.cls_portlet="ui-portlet-narrow";b.deepeach(e.inputs,function(f){if(f.type){f.optional=(["data","data_hidden","hidden","drill_down","repeat","conditional"]).indexOf(f.type)==-1}});b.deepeach(e.inputs,function(f){if(f.type){if(f.type=="conditional"){f.test_param.optional=false}}});var d=this;b.get({url:galaxy_config.root+"api/datatypes",cache:true,success:function(f){d.datatypes=f;d._makeSections(e.inputs);a.prototype.initialize.call(d,e)}})},_makeSections:function(d){d[b.uuid()]={label:"Annotation / Notes",name:"annotation",type:"text",area:true,help:"Add an annotation or note for this step. It will be shown with the workflow.",value:this.node.annotation};var f=this.node.output_terminals&&Object.keys(this.node.output_terminals)[0];if(f){d[b.uuid()]={name:"pja__"+f+"__EmailAction",label:"Email notification",type:"boolean",value:String(Boolean(this.post_job_actions["EmailAction"+f])),ignore:"false",help:"An email notification will be send when the job has completed.",payload:{host:window.location.host}};d[b.uuid()]={name:"pja__"+f+"__DeleteIntermediatesAction",label:"Output cleanup",type:"boolean",value:String(Boolean(this.post_job_actions["DeleteIntermediatesAction"+f])),ignore:"false",help:"Delete intermediate outputs if they are not used as input for another job."};for(var e in this.node.output_terminals){d[b.uuid()]=this._makeSection(e)}}},_makeSection:function(h){var g=[];for(key in this.datatypes){g.push({0:this.datatypes[key],1:this.datatypes[key]})}g.sort(function(j,i){return j.label>i.label?1:j.label<i.label?-1:0});g.unshift({0:"Sequences",1:"Sequences"});g.unshift({0:"Roadmaps",1:"Roadmaps"});g.unshift({0:"Leave unchanged",1:""});var f={label:"Add Actions: '"+h+"'",type:"section",inputs:[{action:"RenameDatasetAction",argument:"newname",label:"Rename dataset",type:"text",value:"",ignore:"",help:'This action will rename the result dataset. Click <a href="https://wiki.galaxyproject.org/Learn/AdvancedWorkflow/Variables">here</a> for more information.'},{action:"ChangeDatatypeAction",argument:"newtype",label:"Change datatype",type:"select",ignore:"",options:g,help:"This action will change the datatype of the output to the indicated value."},{action:"TagDatasetAction",argument:"tags",label:"Tags",type:"text",value:"",ignore:"",help:"This action will set tags for the dataset."},{label:"Assign columns",type:"section",inputs:[{action:"ColumnSetAction",argument:"chromCol",label:"Chrom column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"startCol",label:"Start column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"endCol",label:"End column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"strandCol",label:"Strand column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"nameCol",label:"Name column",type:"integer",value:"",ignore:""}],help:"This action will set column assignments in the output dataset. Blank fields are ignored."}]};var d=this;function e(n,o){o=o||[];o.push(n);for(var m in n.inputs){var k=n.inputs[m];if(k.action){k.name="pja__"+h+"__"+k.action;if(k.argument){k.name+="__"+k.argument}if(k.payload){for(var s in k.payload){var q=k.payload[s];k.payload[k.name+"__"+s]=q;delete q}}var r=d.post_job_actions[k.action+h];if(r){for(var l in o){o[l].expand=true}if(k.argument){k.value=r.action_arguments&&r.action_arguments[k.argument]||k.value}else{k.value="true"}}}if(k.inputs){e(k,o.slice(0))}}}e(f);return f},_buildModel:function(){Galaxy.modal.show({title:"Coming soon...",body:"This feature has not been implemented yet.",buttons:{Close:function(){Galaxy.modal.hide()}}})},_updateModel:function(e){var d=this;e={tool_id:this.options.id,tool_version:this.options.version,inputs:e};console.debug("tools-form-workflow::_refreshForm() - Refreshing states.");console.debug(e);var g=this.deferred.register();var f=galaxy_config.root+"api/workflows/build_module";b.request({type:"POST",url:f,data:e,success:function(h){d.node.update_field_data(h);d._errors(h&&h.tool_model);d.deferred.done(g);console.debug("tools-form::_refreshForm() - States refreshed.");console.debug(h)},error:function(h){d.deferred.done(g);console.debug("tools-form::_refreshForm() - Refresh request failed.");console.debug(h)}})}});return{View:c}});
\ No newline at end of file
+define(["utils/utils","mvc/tools/tools-form-base"],function(b,a){var c=a.extend({initialize:function(e){this.node=workflow.active_node;if(!this.node){console.debug("FAILED - tools-form-workflow:initialize() - Node not found in workflow.");return}this.post_job_actions=this.node.post_job_actions||{};this.options=e;this.options.text_enable="Set in Advance";this.options.text_disable="Set at Runtime";this.options.is_dynamic=false;this.options.narrow=true;this.options.initial_errors=true;this.options.cls_portlet="ui-portlet-narrow";b.deepeach(e.inputs,function(f){if(f.type){f.optional=(["data","data_hidden","hidden","repeat","conditional"]).indexOf(f.type)==-1}});b.deepeach(e.inputs,function(f){if(f.type){if(f.type=="conditional"){f.test_param.optional=false}}});var d=this;b.get({url:galaxy_config.root+"api/datatypes",cache:true,success:function(f){d.datatypes=f;d._makeSections(e.inputs);a.prototype.initialize.call(d,e)}})},_makeSections:function(d){d[b.uuid()]={label:"Annotation / Notes",name:"annotation",type:"text",area:true,help:"Add an annotation or note for this step. It will be shown with the workflow.",value:this.node.annotation};var f=this.node.output_terminals&&Object.keys(this.node.output_terminals)[0];if(f){d[b.uuid()]={name:"pja__"+f+"__EmailAction",label:"Email notification",type:"boolean",value:String(Boolean(this.post_job_actions["EmailAction"+f])),ignore:"false",help:"An email notification will be send when the job has completed.",payload:{host:window.location.host}};d[b.uuid()]={name:"pja__"+f+"__DeleteIntermediatesAction",label:"Output cleanup",type:"boolean",value:String(Boolean(this.post_job_actions["DeleteIntermediatesAction"+f])),ignore:"false",help:"Delete intermediate outputs if they are not used as input for another job."};for(var e in this.node.output_terminals){d[b.uuid()]=this._makeSection(e)}}},_makeSection:function(h){var g=[];for(key in this.datatypes){g.push({0:this.datatypes[key],1:this.datatypes[key]})}g.sort(function(j,i){return j.label>i.label?1:j.label<i.label?-1:0});g.unshift({0:"Sequences",1:"Sequences"});g.unshift({0:"Roadmaps",1:"Roadmaps"});g.unshift({0:"Leave unchanged",1:""});var f={label:"Add Actions: '"+h+"'",type:"section",inputs:[{action:"RenameDatasetAction",argument:"newname",label:"Rename dataset",type:"text",value:"",ignore:"",help:'This action will rename the result dataset. Click <a href="https://wiki.galaxyproject.org/Learn/AdvancedWorkflow/Variables">here</a> for more information.'},{action:"ChangeDatatypeAction",argument:"newtype",label:"Change datatype",type:"select",ignore:"",options:g,help:"This action will change the datatype of the output to the indicated value."},{action:"TagDatasetAction",argument:"tags",label:"Tags",type:"text",value:"",ignore:"",help:"This action will set tags for the dataset."},{label:"Assign columns",type:"section",inputs:[{action:"ColumnSetAction",argument:"chromCol",label:"Chrom column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"startCol",label:"Start column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"endCol",label:"End column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"strandCol",label:"Strand column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"nameCol",label:"Name column",type:"integer",value:"",ignore:""}],help:"This action will set column assignments in the output dataset. Blank fields are ignored."}]};var d=this;function e(n,o){o=o||[];o.push(n);for(var m in n.inputs){var k=n.inputs[m];if(k.action){k.name="pja__"+h+"__"+k.action;if(k.argument){k.name+="__"+k.argument}if(k.payload){for(var s in k.payload){var q=k.payload[s];k.payload[k.name+"__"+s]=q;delete q}}var r=d.post_job_actions[k.action+h];if(r){for(var l in o){o[l].expand=true}if(k.argument){k.value=r.action_arguments&&r.action_arguments[k.argument]||k.value}else{k.value="true"}}}if(k.inputs){e(k,o.slice(0))}}}e(f);return f},_buildModel:function(){Galaxy.modal.show({title:"Coming soon...",body:"This feature has not been implemented yet.",buttons:{Close:function(){Galaxy.modal.hide()}}})},_updateModel:function(e){var d=this;e={tool_id:this.options.id,tool_version:this.options.version,inputs:e};console.debug("tools-form-workflow::_refreshForm() - Refreshing states.");console.debug(e);var g=this.deferred.register();var f=galaxy_config.root+"api/workflows/build_module";b.request({type:"POST",url:f,data:e,success:function(h){d.node.update_field_data(h);d._errors(h&&h.tool_model);d.deferred.done(g);console.debug("tools-form::_refreshForm() - States refreshed.");console.debug(h)},error:function(h){d.deferred.done(g);console.debug("tools-form::_refreshForm() - Refresh request failed.");console.debug(h)}})}});return{View:c}});
\ No newline at end of file
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/scripts/packed/mvc/tools/tools-input.js
--- a/static/scripts/packed/mvc/tools/tools-input.js
+++ b/static/scripts/packed/mvc/tools/tools-input.js
@@ -1,1 +1,1 @@
-define([],function(){return Backbone.View.extend({initialize:function(d,c){this.app=d;this.text_enable=d.options.text_enable||"Enable";this.text_disable=d.options.text_disable||"Disable";this.field=c.field;this.default_value=c.default_value;this.setElement(this._template(c));this.$field=this.$el.find(".ui-table-form-field");this.$title_optional=this.$el.find(".ui-table-form-title-optional");this.$error_text=this.$el.find(".ui-table-form-error-text");this.$error=this.$el.find(".ui-table-form-error");this.$field.prepend(this.field.$el);this.field.skip=false;var b=this.field.value&&this.field.value();this.field.skip=Boolean(c.optional&&(b===null||b==this.default_value||Number(b)==Number(this.default_value)||JSON.stringify(b)==JSON.stringify(this.default_value)));this._refresh();var a=this;this.$title_optional.on("click",function(){a.field.skip=!a.field.skip;a._refresh();a.app.trigger("refresh")})},error:function(a){this.$error_text.html(a);this.$error.show();this.$el.addClass("ui-error")},reset:function(){this.$error.hide();this.$el.removeClass("ui-error")},_refresh:function(){if(!this.field.skip){this.$field.fadeIn("fast");this.$title_optional.html(this.text_disable)}else{this.$field.hide();this.$title_optional.html(this.text_enable);this.field.value&&this.field.value(this.default_value)}},_template:function(a){var b='<div class="ui-table-form-element"><div class="ui-table-form-error ui-error"><span class="fa fa-arrow-down"/><span class="ui-table-form-error-text"/></div><div class="ui-table-form-title-strong">';if(a.optional){b+=a.label+'<span> [<span class="ui-table-form-title-optional"/>]</span>'}else{b+=a.label}b+='</div><div class="ui-table-form-field">';if(a.help){b+='<div class="ui-table-form-info">'+a.help+"</div>"}b+="</div></div>";return b}})});
\ No newline at end of file
+define([],function(){return Backbone.View.extend({initialize:function(d,c){this.app=d;this.text_enable=d.options.text_enable||"Enable";this.text_disable=d.options.text_disable||"Disable";this.cls_enable=d.options.cls_enable||"fa fa-plus-square";this.cls_disable=d.options.cls_disable||"fa fa-minus-square";this.field=c.field;this.default_value=c.default_value;this.setElement(this._template(c));this.$field=this.$el.find(".ui-table-form-field");this.$optional=this.$el.find(".ui-table-form-optional");this.$optional_icon=this.$el.find(".ui-table-form-optional").find(".icon");this.$error_text=this.$el.find(".ui-table-form-error-text");this.$error=this.$el.find(".ui-table-form-error");this.$field.prepend(this.field.$el);this.field.skip=false;var b=this.field.value&&this.field.value();this.field.skip=Boolean(c.optional&&(b===null||b===""||b===this.default_value||String(b)===String(this.default_value)||Number(b)===Number(this.default_value)||JSON.stringify(b)===JSON.stringify(this.default_value)));this._refresh();var a=this;this.$optional.on("click",function(){a.field.skip=!a.field.skip;a._refresh();a.app.trigger("refresh")})},error:function(a){this.$error_text.html(a);this.$error.show();this.$el.addClass("ui-error")},reset:function(){this.$error.hide();this.$el.removeClass("ui-error")},_refresh:function(){this.$optional_icon.removeClass().addClass("icon");if(!this.field.skip){this.$field.fadeIn("fast");this._tooltip(this.text_disable,this.cls_disable)}else{this.$field.hide();this._tooltip(this.text_enable,this.cls_enable);this.field.value&&this.field.value(this.default_value)}},_tooltip:function(b,a){if(this.$optional.length){this.$optional_icon.addClass(a).tooltip({placement:"bottom"}).attr("data-original-title",b).tooltip("fixTitle").tooltip("hide")}},_template:function(a){var b='<div class="ui-table-form-element"><div class="ui-table-form-error ui-error"><span class="fa fa-arrow-down"/><span class="ui-table-form-error-text"/></div><div class="ui-table-form-title">';if(a.optional){b+='<div class="ui-table-form-optional"><i class="icon"/>'+a.label+"</div>"}else{b+=a.label}b+='</div><div class="ui-table-form-field">';b+='<div class="ui-table-form-info">';if(a.help){b+=a.help}b+="</div>";b+="</div></div>";return b}})});
\ No newline at end of file
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/scripts/packed/mvc/ui/ui-button-check.js
--- a/static/scripts/packed/mvc/ui/ui-button-check.js
+++ b/static/scripts/packed/mvc/ui/ui-button-check.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){return Backbone.View.extend({optionsDefault:{icons:["fa fa-square-o","fa fa-minus-square-o","fa fa-check-square-o"],value:0},initialize:function(c){this.options=a.merge(c,this.optionsDefault);this.setElement($("<div/>"));this.value(this.options.value);var b=this;this.$el.on("click",function(){b.current=(!b.current&&2)||0;b.value(b.current);b.options.onclick&&b.options.onclick()})},value:function(b){if(b!==undefined){this.current=b;this.$el.removeClass().addClass("ui-checkbutton").addClass(this.options.icons[b]);this.options.onchange&&this.options.onchange(b)}return this.current}})});
\ No newline at end of file
+define(["utils/utils"],function(a){return Backbone.View.extend({optionsDefault:{icons:["fa fa-square-o","fa fa-minus-square-o","fa fa-check-square-o"],value:0},initialize:function(c){this.options=a.merge(c,this.optionsDefault);this.setElement($("<div/>"));this.value(this.options.value);var b=this;this.$el.on("click",function(){b.current=(!b.current&&2)||0;b.value(b.current);b.options.onclick&&b.options.onclick()})},value:function(b){if(b!==undefined){this.current=b;this.$el.removeClass().addClass("ui-button-check").addClass(this.options.icons[b]);this.options.onchange&&this.options.onchange(b)}return this.current}})});
\ No newline at end of file
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/scripts/packed/mvc/ui/ui-misc.js
--- a/static/scripts/packed/mvc/ui/ui-misc.js
+++ b/static/scripts/packed/mvc/ui/ui-misc.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-options","mvc/ui/ui-drilldown","mvc/ui/ui-button-menu","mvc/ui/ui-button-check","mvc/ui/ui-modal"],function(e,h,i,m,l,r,d,b){var q=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(s){return'<img class="ui-image '+s.cls+'" src="'+s.url+'"/>'}});var j=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},title:function(s){this.$el.html(s)},_template:function(s){return'<label class="ui-label '+s.cls+'">'+s.title+"</label>"},value:function(){return options.title}});var c=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){return'<div><span class="fa '+s.icon+'" class="ui-icon"/> '+s.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"ui-button btn btn-default",icon:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",function(){$(".tooltip").hide();if(s.onclick){s.onclick()}});$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t='<button id="'+s.id+'" type="submit" style="float: '+s.floating+';" type="button" class="'+s.cls+'">';if(s.icon){t+='<i class="icon fa '+s.icon+'"></i> '}t+=s.title+"</button>";return t}});var o=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"ui-button-icon",icon:"",tooltip:"",onclick:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));this.$button=this.$el.find(".button");var s=this;$(this.el).on("click",function(){$(".tooltip").hide();if(t.onclick&&!s.disabled){t.onclick()}});$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},disable:function(){this.$button.addClass("disabled");this.disabled=true},enable:function(){this.$button.removeClass("disabled");this.disabled=false},setIcon:function(s){this.$("i").removeClass(this.options.icon).addClass(s);this.options.icon=s},_template:function(s){var t="";if(s.title){t="width: auto;"}var u='<div id="'+s.id+'" style="float: '+s.floating+"; "+t+'" class="'+s.cls+'">';if(s.title){u+='<div class="button"><i class="icon fa '+s.icon+'"/> <span class="title">'+s.title+"</span></div>"}else{u+='<i class="icon fa '+s.icon+'"/>'}u+="</div>";return u}});var p=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick)},_template:function(s){return'<div><a href="javascript:void(0)" class="ui-anchor '+s.cls+'">'+s.title+"</a></div>"}});var a=Backbone.View.extend({optionsDefault:{message:null,status:"info",persistent:false},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement("<div></div>");if(this.options.message){this.update(this.options)}},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(t.message);this.$el.fadeIn();if(this.timeout){window.clearTimeout(this.timeout)}if(!t.persistent){var s=this;this.timeout=window.setTimeout(function(){if(s.$el.is(":visible")){s.$el.fadeOut()}else{s.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(s){return'<div class="ui-message alert alert-'+s.status+'"/>'}});var f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));var s=this;if(this.options.onclick){this.$el.on("submit",function(v){var u=s.$el.find("#search");s.options.onclick(u.val())})}},_template:function(s){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+s.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var n=Backbone.View.extend({optionsDefault:{type:"text",placeholder:"",disabled:false,visible:true,cls:"",area:false},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.value!==undefined){this.value(this.options.value)}if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){if(s.area){return'<textarea id="'+s.id+'" class="ui-textarea '+s.cls+'"></textarea>'}else{return'<input id="'+s.id+'" type="'+s.type+'" value="'+s.value+'" placeholder="'+s.placeholder+'" class="ui-input '+s.cls+'">'}}});var k=Backbone.View.extend({initialize:function(s){this.options=s;this.setElement(this._template(this.options));if(this.options.value!==undefined){this.value(this.options.value)}},value:function(s){if(s!==undefined){this.$("hidden").val(s)}return this.$("hidden").val()},_template:function(t){var s='<div id="'+t.id+'" >';if(t.info){s+="<label>"+t.info+"</label>"}s+='<hidden value="'+t.value+'"/></div>';return s}});return{Anchor:p,Button:g,ButtonIcon:o,ButtonCheck:d,ButtonMenu:r,Icon:c,Image:q,Input:n,Label:j,Message:a,Modal:b,RadioButton:m.RadioButton,Checkbox:m.Checkbox,Radio:m.Radio,Searchbox:f,Select:h,Hidden:k,Slider:i,Drilldown:l}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-options","mvc/ui/ui-drilldown","mvc/ui/ui-button-menu","mvc/ui/ui-button-check","mvc/ui/ui-modal"],function(e,h,i,m,l,r,d,b){var q=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(s){return'<img class="ui-image '+s.cls+'" src="'+s.url+'"/>'}});var j=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},title:function(s){this.$el.html(s)},_template:function(s){return'<label class="ui-label '+s.cls+'">'+s.title+"</label>"},value:function(){return options.title}});var c=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){return'<div><span class="fa '+s.icon+'" class="ui-icon"/> '+s.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"ui-button btn btn-default",icon:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",function(){$(".tooltip").hide();if(s.onclick){s.onclick()}});$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t='<button id="'+s.id+'" type="submit" style="float: '+s.floating+';" type="button" class="'+s.cls+'">';if(s.icon){t+='<i class="icon fa '+s.icon+'"></i> '}t+=s.title+"</button>";return t}});var o=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"ui-button-icon",icon:"",tooltip:"",onclick:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));this.$button=this.$el.find(".button");var s=this;$(this.el).on("click",function(){$(".tooltip").hide();if(t.onclick&&!s.disabled){t.onclick()}});$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},disable:function(){this.$button.addClass("disabled");this.disabled=true},enable:function(){this.$button.removeClass("disabled");this.disabled=false},setIcon:function(s){this.$("i").removeClass(this.options.icon).addClass(s);this.options.icon=s},_template:function(s){var t="";if(s.title){t="width: auto;"}var u='<div id="'+s.id+'" style="float: '+s.floating+"; "+t+'" class="'+s.cls+'">';if(s.title){u+='<div class="button"><i class="icon fa '+s.icon+'"/> <span class="title">'+s.title+"</span></div>"}else{u+='<i class="icon fa '+s.icon+'"/>'}u+="</div>";return u}});var p=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick)},_template:function(s){return'<div><a href="javascript:void(0)" class="ui-anchor '+s.cls+'">'+s.title+"</a></div>"}});var a=Backbone.View.extend({optionsDefault:{message:null,status:"info",persistent:false},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement("<div></div>");if(this.options.message){this.update(this.options)}},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(t.message);this.$el.fadeIn();if(this.timeout){window.clearTimeout(this.timeout)}if(!t.persistent){var s=this;this.timeout=window.setTimeout(function(){if(s.$el.is(":visible")){s.$el.fadeOut()}else{s.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(s){return'<div class="ui-message alert alert-'+s.status+'"/>'}});var f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));var s=this;if(this.options.onclick){this.$el.on("submit",function(v){var u=s.$el.find("#search");s.options.onclick(u.val())})}},_template:function(s){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+s.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var n=Backbone.View.extend({optionsDefault:{type:"text",placeholder:"",disabled:false,visible:true,cls:"",area:false},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.value!==undefined){this.value(this.options.value)}if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){if(s.area){return'<textarea id="'+s.id+'" class="ui-textarea '+s.cls+'"></textarea>'}else{return'<input id="'+s.id+'" type="'+s.type+'" value="'+s.value+'" placeholder="'+s.placeholder+'" class="ui-input '+s.cls+'">'}}});var k=Backbone.View.extend({initialize:function(s){this.options=s;this.setElement(this._template(this.options));if(this.options.value!==undefined){this.value(this.options.value)}},value:function(s){if(s!==undefined){this.$("hidden").val(s)}return this.$("hidden").val()},_template:function(t){var s='<div id="'+t.id+'" >';if(t.info){s+="<div>"+t.info+"</div>"}s+='<hidden value="'+t.value+'"/></div>';return s}});return{Anchor:p,Button:g,ButtonIcon:o,ButtonCheck:d,ButtonMenu:r,Icon:c,Image:q,Input:n,Label:j,Message:a,Modal:b,RadioButton:m.RadioButton,Checkbox:m.Checkbox,Radio:m.Radio,Searchbox:f,Select:h,Hidden:k,Slider:i,Drilldown:l}});
\ No newline at end of file
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 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-input,.ui-textarea,.ui-options .ui-options-list,.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{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}
@@ -1414,11 +1414,10 @@
.ui-table tbody,.ui-table-plain tbody{cursor:pointer}
.ui-table-plain{table-layout:fixed}.ui-table-plain tbody{cursor:auto !important}.ui-table-plain tbody td{padding:0px !important;border:none !important}
.ui-table-plain .ui-table-section{border-left:solid 3px #ebd9b2;border-radius:5px !important;margin-bottom:5px;padding-left:10px}
-.ui-table-form-element{margin-top:5px;margin-bottom:5px;overflow:hidden}.ui-table-form-element .ui-table-form-title-optional{font-weight:bold;text-decoration:underline;cursor:pointer}
+.ui-table-form-element{margin-top:5px;margin-bottom:5px;overflow:visible}.ui-table-form-element .ui-table-form-title{font-weight:bold}.ui-table-form-element .ui-table-form-title .ui-table-form-optional{cursor:pointer}.ui-table-form-element .ui-table-form-title .ui-table-form-optional .icon{margin-right:5px;font-size:1.2em}
.ui-table-form-element .ui-table-form-field{margin-top:5px}
-.ui-table-form-title-strong{font-weight:bold}
+.ui-table-form-separator{font-weight:bold;font-size:0.9em}
.ui-table-form-info{clear:both !important}
-.ui-table-form-separator{font-weight:bold;font-size:0.9em}
.ui-table-form-error{display:none}.ui-table-form-error .ui-table-form-error-text{padding-left:5px}
.ui-portlet,.ui-portlet-repeat,.ui-portlet-limited,.ui-portlet-section,.ui-portlet-narrow,.ui-portlet-repeat,.ui-portlet-limited,.ui-portlet-section,.ui-portlet-narrow{border:solid #d6b161 1px;border-radius:3px;position:relative;clear:both;width:auto;height:100%}.ui-portlet .portlet-header,.ui-portlet-limited .portlet-header,.ui-portlet-narrow .portlet-header{background:#ebd9b2;border-bottom:solid #d6b161 1px;padding:2px 8px;overflow:visible;float:right;width:100%}.ui-portlet .portlet-header .portlet-title,.ui-portlet-limited .portlet-header .portlet-title,.ui-portlet-narrow .portlet-header .portlet-title{display:inline;vertical-align:middle}.ui-portlet .portlet-header .portlet-title .portlet-title-text,.ui-portlet-limited .portlet-header .portlet-title .portlet-title-text,.ui-portlet-narrow .portlet-header .portlet-title .portlet-title-text{vertical-align:middle;line-height:22px}
.ui-portlet .portlet-header .portlet-title .icon,.ui-portlet-limited .portlet-header .portlet-title .icon,.ui-portlet-narrow .portlet-header .portlet-title .icon{font-size:1.2em;vertical-align:middle}
@@ -1435,7 +1434,7 @@
.ui-portlet-limited,.ui-portlet-narrow,.ui-portlet-narrow{max-width:900px}
.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-input,.ui-textarea,.ui-options .ui-options-list,.ui-form-slider .ui-form-slider-text,.ui-select-multiple,.ui-textarea,.ui-options .ui-options-list,.ui-form-slider .ui-form-slider-text,.ui-select-multiple{background:transparent}
+.ui-input,.ui-textarea,.ui-options .ui-options-list,.ui-form-slider .ui-form-slider-text,.ui-select-multiple{width:100%;display:block;height:27px;padding:4px 10px;font-size:12px;line-height:1.428571429;color:#555;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)}.ui-input[disabled],.ui-input[readonly],fieldset[disabled] .ui-input{cursor:not-allowed;background-color:#eee}
.ui-textarea{height:100px !important}
.ui-options .ui-options-list{height:100% !important}.ui-options .ui-options-list input[type=checkbox],.ui-options .ui-options-list input[type=radio]{display:none}
.ui-options .ui-options-list label{margin:0px;cursor:pointer}
@@ -1448,15 +1447,15 @@
.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-checkbutton{font-size:1.2em;width:1.2em;cursor:pointer}
+.ui-button-check{font-size:1.2em;width:1.2em;cursor:pointer}
.ui-select{position:relative}.ui-select .button{position:absolute;top:5px;right:5px}
.ui-select .select2-container{width:100%}
.ui-select select{position:relative;top:0px;height:27px;width:100%;padding-left:5px;padding-right:20px;cursor:pointer;background:transparent;-webkit-appearance:none;border:1px solid #bfbfbf;-moz-border-radius:3px;border-radius:3px}
.ui-select-content .ui-options{float:left;padding-top:2px}
.ui-color-picker .ui-color-picker-header{cursor:pointer}
-.ui-color-picker .ui-color-picker-value{float:left;border-radius:3px;border:solid 1px #000000;width:12px;height:12px;margin-bottom:10px;margin-right:5px}
+.ui-color-picker .ui-color-picker-value{float:left;border-radius:3px;border:solid 1px #000000;width:12px;height:12px;margin-right:5px}
.ui-color-picker .ui-color-picker-label{float:left;line-height:1.2em}
-.ui-color-picker .ui-color-picker-view{display:none;float:left;overflow:auto;height:100%}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel{width:210px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content{margin-bottom:15px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content .label{padding-bottom:2px}
+.ui-color-picker .ui-color-picker-view{height:100%;overflow:auto;display:none;float:left;margin-top:5px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel{width:210px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content{margin-bottom:15px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content .label{padding-bottom:2px}
.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content .line .ui-color-picker-box{cursor:pointer;float:left;margin-right:5px;border:solid 1px #c0c0c0;width:15px;height:15px;border-radius:2px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content .line .ui-color-picker-box .ui-color-picker-check{color:black;font-size:1.2em;position:relative;left:1px}
.libraryRow{background-color:#ebd9b2}
.datasetHighlighted{background-color:#f9f9f9}
diff -r af7603a13e8d5340f064312808b6ebfb56d1a959 -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 static/style/src/less/ui.less
--- a/static/style/src/less/ui.less
+++ b/static/style/src/less/ui.less
@@ -57,7 +57,10 @@
height: auto !important;
ul {
i {
- font-size: 1.2em; margin-right: @ui-margin-horizontal; position: relative; top: 1px;
+ font-size: 1.2em;
+ margin-right: @ui-margin-horizontal;
+ position: relative;
+ top: 1px;
}
}
.button {
@@ -142,26 +145,22 @@
// table form elements
.ui-table-form-element {
- .ui-table-form-title-optional {
+ .ui-table-form-title {
font-weight: bold;
- text-decoration: underline;
- cursor: pointer;
+ .ui-table-form-optional {
+ cursor: pointer;
+ .icon {
+ margin-right: 5px;
+ font-size: 1.2em;
+ }
+ }
}
.ui-table-form-field {
margin-top: @ui-margin-vertical;
}
margin-top: @ui-margin-vertical;
margin-bottom: @ui-margin-vertical;
- overflow: hidden;
-}
-
-.ui-table-form-title-strong {
- font-weight: bold;
-}
-
-.ui-table-form-info {
- &:extend(.toolParamHelp);
- clear: both !important;
+ overflow: visible;
}
.ui-table-form-separator {
@@ -169,6 +168,11 @@
font-size: 0.9em;
}
+.ui-table-form-info {
+ &:extend(.toolParamHelp);
+ clear: both !important;
+}
+
.ui-table-form-error {
display: none;
.ui-table-form-error-text {
@@ -312,8 +316,22 @@
// input elements
.ui-input {
- &:extend(.form-control);
- background: transparent;
+ width: 100%;
+ display: block;
+ height: @input-height-base;
+ padding: @padding-base-vertical @padding-base-horizontal;
+ font-size: @font-size-base;
+ line-height: @line-height-base;
+ color: @input-color;
+ border: 1px solid @input-border;
+ border-radius: @input-border-radius;
+ .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
+ &[disabled],
+ &[readonly],
+ fieldset[disabled] & {
+ cursor: not-allowed;
+ background-color: @input-bg-disabled;
+ }
}
.ui-textarea {
@@ -370,7 +388,6 @@
}
}
-
.ui-form-slider {
display: inline-block;
width: 100%;
@@ -400,7 +417,7 @@
}
}
-.ui-checkbutton {
+.ui-button-check {
font-size: 1.2em;
width: 1.2em;
cursor: pointer;
@@ -453,7 +470,6 @@
border: solid 1px #000000;
width: 12px;
height: 12px;
- margin-bottom: 10px;
margin-right: 5px;
}
.ui-color-picker-label {
@@ -465,6 +481,7 @@
overflow: auto;
display: none;
float: left;
+ margin-top: 5px;
.ui-color-picker-panel {
width: 210px;
.ui-color-picker-content {
https://bitbucket.org/galaxy/galaxy-central/commits/4589eb71e192/
Changeset: 4589eb71e192
User: dannon
Date: 2015-02-16 20:09:42+00:00
Summary: Bump SQLAlchemy all the way to 0.9.8
Affected #: 1 file
diff -r 4909df6a1dbde9ece5f8b5dfd0bbe03597826893 -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -26,7 +26,7 @@
pysqlite = 2.5.6
python_lzo = 1.08_2.03_static
PyYAML = 3.10
-SQLAlchemy = 0.8.7
+SQLAlchemy = 0.9.8
; msgpack_python = 0.2.4
[eggs:noplatform]
https://bitbucket.org/galaxy/galaxy-central/commits/d004eb0d8be7/
Changeset: d004eb0d8be7
User: dannon
Date: 2015-02-17 12:26:52+00:00
Summary: Merge.
Affected #: 20 files
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 client/galaxy/scripts/mvc/history/history-model.js
--- a/client/galaxy/scripts/mvc/history/history-model.js
+++ b/client/galaxy/scripts/mvc/history/history-model.js
@@ -205,6 +205,11 @@
if( this.get( 'deleted' ) ){ return jQuery.when(); }
return this.save( { deleted: true }, options );
},
+ /** purge this history, _Mark_ing it as purged and removing all dataset data from the server */
+ purge : function( options ){
+ if( this.get( 'purged' ) ){ return jQuery.when(); }
+ return this.save( { purged: true }, options );
+ },
/** save this history, _Mark_ing it as undeleted */
undelete : function( options ){
if( !this.get( 'deleted' ) ){ return jQuery.when(); }
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 client/galaxy/scripts/mvc/history/multi-panel.js
--- a/client/galaxy/scripts/mvc/history/multi-panel.js
+++ b/client/galaxy/scripts/mvc/history/multi-panel.js
@@ -128,12 +128,9 @@
/** set up passed-in panel (if any) and listeners */
initialize : function initialize( options ){
options = options || {};
+ this.purgeAllowed = !_.isUndefined( options.purgeAllowed )? options.purgeAllowed: false;
+ this.panel = options.panel || this.createPanel( options );
- //this.log( this + '.init', options );
- // if model, set up model
- // create panel sub-view
-//TODO: use current-history-panel for current
- this.panel = options.panel || this.createPanel( options );
this.setUpListeners();
},
@@ -143,6 +140,7 @@
model : this.model,
//el : this.$panel(),
// non-current panels should set their hdas to draggable
+ purgeAllowed: this.purgeAllowed,
dragItems : true
}, panelOptions );
//this.log( 'panelOptions:', panelOptions );
@@ -245,9 +243,9 @@
});
return $([
'<div class="panel-controls clear flex-row">',
- this.controlsLeftTemplate( data ),
+ this.controlsLeftTemplate({ history: data, view: this }),
//'<button class="btn btn-default">Herp</button>',
- this.controlsRightTemplate( data ),
+ this.controlsRightTemplate({ history: data, view: this }),
'</div>',
'<div class="inner flex-row flex-column-container">',
'<div id="history-', data.id, '" class="history-column history-panel flex-column"></div>',
@@ -317,24 +315,24 @@
/** controls template displaying controls above the panel based on this.currentHistory */
controlsLeftTemplate : _.template([
'<div class="pull-left">',
- '<% if( history.isCurrentHistory ){ %>',
+ '<% if( data.history.isCurrentHistory ){ %>',
'<strong class="current-label">', _l( 'Current History' ), '</strong>',
'<% } else { %>',
'<button class="switch-to btn btn-default">', _l( 'Switch to' ), '</button>',
'<% } %>',
'</div>'
- ].join( '' ), { variable : 'history' }),
+ ].join( '' ), { variable : 'data' }),
/** controls template displaying controls above the panel based on this.currentHistory */
controlsRightTemplate : _.template([
'<div class="pull-right">',
- '<% if( !history.purged ){ %>',
+ '<% if( !data.history.purged ){ %>',
'<div class="panel-menu btn-group">',
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',
'<span class="caret"></span>',
'</button>',
'<ul class="dropdown-menu pull-right" role="menu">',
- '<% if( !history.deleted ){ %>',
+ '<% if( !data.history.deleted ){ %>',
'<li><a href="javascript:void(0);" class="copy-history">',
_l( 'Copy' ),
'</a></li>',
@@ -349,14 +347,16 @@
_l( 'Undelete' ),
'</a></li>',
'<% } %>',
- //'<li><a href="javascript:void(0);" class="purge-history">',
- // _l( 'Purge' ),
- //'</a></li>',
+ '<% if( data.view.purgeAllowed ){ %>',
+ '<li><a href="javascript:void(0);" class="purge-history">',
+ _l( 'Purge' ),
+ '</a></li>',
+ '<% } %>',
'</ul>',
'<% } %>',
'</div>',
'</div>'
- ].join( '' ), { variable: 'history' }),
+ ].join( '' ), { variable: 'data' }),
// ------------------------------------------------------------------------ misc
/** String rep */
@@ -491,7 +491,7 @@
// handle setting a history as current, triggered by history.setAsCurrent
'set-as-current': multipanel.setCurrentHistory,
// handle deleting a history (depends on whether panels is including deleted or not)
- 'change:deleted': multipanel.handleDeletedHistory,
+ 'change:deleted change:purged': multipanel.handleDeletedHistory,
'sort' : function(){ multipanel.renderColumns( 0 ); }
});
@@ -519,7 +519,7 @@
* based on collection.includeDeleted
*/
handleDeletedHistory : function handleDeletedHistory( history ){
- if( history.get( 'deleted' ) ){
+ if( history.get( 'deleted' ) || history.get( 'purged' ) ){
this.log( 'handleDeletedHistory', this.collection.includeDeleted, history );
var multipanel = this;
column = multipanel.columnMap[ history.id ];
@@ -584,7 +584,10 @@
/** create a column and its panel and set up any listeners to them */
createColumn : function createColumn( history, options ){
// options passed can be re-used, so extend them before adding the model to prevent pollution for the next
- options = _.extend( {}, options, { model: history });
+ options = _.extend( {}, options, {
+ model : history,
+ purgeAllowed: Galaxy.config.allow_user_dataset_purge
+ });
var column = new HistoryPanelColumn( options );
if( history.id === this.currentHistoryId ){ column.currentHistory = true; }
this.setUpColumnListeners( column );
@@ -1047,21 +1050,19 @@
mainTemplate : _.template([
'<div class="header flex-column-container">',
'<div class="control-column control-column-left flex-column">',
- '<button class="create-new btn btn-default">', _l( 'Create new' ), '</button> ',
+ '<button class="create-new btn btn-default" tabindex="4">', _l( 'Create new' ), '</button> ',
'<div id="search-histories" class="search-control"></div>',
'<div id="search-datasets" class="search-control"></div>',
- '<button class="open-more-options btn btn-default">',
- //TODO: tip not working
- '<span class="fa fa-ellipsis-h" title="More options"></span>',
- '</button>',
+ '<a class="open-more-options btn btn-default" tabindex="3">',
+ '<span class="fa fa-ellipsis-h"></span>',
+ '</a>',
'</div>',
// feedback
'<div class="control-column control-column-center flex-column">',
- '<div class="header-info">',
- '</div>',
+ '<div class="header-info">', '</div>',
'</div>',
'<div class="control-column control-column-right flex-column">',
- '<button class="done btn btn-default">', _l( 'Done' ), '</button>',
+ '<button class="done btn btn-default" tabindex="1">', _l( 'Done' ), '</button>',
'</div>',
'</div>',
// middle - where the columns go
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 config/plugins/visualizations/scatterplot/templates/scatterplot.mako
--- a/config/plugins/visualizations/scatterplot/templates/scatterplot.mako
+++ b/config/plugins/visualizations/scatterplot/templates/scatterplot.mako
@@ -36,73 +36,75 @@
'mvc/visualization/visualization-model' )}
${h.javascript_link( root + 'plugins/visualizations/scatterplot/static/scatterplot-edit.js' )}
+
+<script type="text/javascript">
+function getModel(){
+ return new ScatterplotModel({
+ id : ${h.dumps( visualization_id )} || undefined,
+ title : "${title}",
+ config : ${h.dumps( config, indent=2 )}
+ });
+}
+function getHDAJSON(){
+ return ${h.dumps( trans.security.encode_dict_ids( hda.to_dict() ), indent=2 )};
+}
+</script>
+
</head>
## ----------------------------------------------------------------------------
<body>
-%if embedded and saved_visualization:
-<figcaption>
- <span class="title">${title}</span>
- <span class="title-info">${info}</span>
-</figcaption>
-<figure class="scatterplot-display"></div>
+ %if embedded and saved_visualization:
+ <figcaption>
+ <span class="title">${title}</span>
+ <span class="title-info">${info}</span>
+ </figcaption>
+ <figure class="scatterplot-display"></figure>
-<script type="text/javascript">
-$(function(){
- var model = new ScatterplotModel({
- id : ${h.dumps( visualization_id )} || undefined,
- title : "${title}",
- config : ${h.dumps( config, indent=2 )}
+ <script type="text/javascript">
+ $(function(){
+ var display = new ScatterplotDisplay({
+ el : $( '.scatterplot-display' ).attr( 'id', 'scatterplot-display-' + '${visualization_id}' ),
+ model : getModel(),
+ dataset : getHDAJSON(),
+ embedded: "${embedded}"
+ }).render();
+ display.fetchData();
+ //window.model = model;
+ //window.display = display;
});
- hdaJson = ${h.dumps( trans.security.encode_dict_ids( hda.to_dict() ), indent=2 )},
- display = new ScatterplotDisplay({
- el : $( '.scatterplot-display' ).attr( 'id', 'scatterplot-display-' + '${visualization_id}' ),
- model : model,
- dataset : hdaJson,
- embedded: "${embedded}"
- }).render();
- display.fetchData();
- //window.model = model;
- //window.display = display;
-});
+ </script>
-</script>
+ %else:
+ <div class="chart-header">
+ <h2>${title or default_title}</h2>
+ <p>${info}</p>
+ </div>
-%else:
-<div class="chart-header">
- <h2>${title or default_title}</h2>
- <p>${info}</p>
-</div>
+ <div class="scatterplot-editor"></div>
+ <script type="text/javascript">
+ $(function(){
+ var model = getModel(),
+ hdaJSON = getHDAJSON(),
+ editor = new ScatterplotConfigEditor({
+ el : $( '.scatterplot-editor' ).attr( 'id', 'scatterplot-editor-hda-' + hdaJSON.id ),
+ model : getModel(),
+ dataset : hdaJSON
+ }).render();
+ window.editor = editor;
-<div class="scatterplot-editor"></div>
-<script type="text/javascript">
-$(function(){
- var model = new ScatterplotModel({
- id : ${h.dumps( visualization_id )} || undefined,
- title : "${title or default_title}",
- config : ${h.dumps( config, indent=2 )}
- }),
- hdaJson = ${h.dumps( trans.security.encode_dict_ids( hda.to_dict() ), indent=2 )},
- editor = new ScatterplotConfigEditor({
- el : $( '.scatterplot-editor' ).attr( 'id', 'scatterplot-editor-hda-' + hdaJson.id ),
- model : model,
- dataset : hdaJson
- }).render();
- window.editor = editor;
-
- $( '.chart-header h2' ).click( function(){
- var returned = prompt( 'Enter a new title:' );
- if( returned ){
- model.set( 'title', returned );
- }
- });
- model.on( 'change:title', function(){
- $( '.chart-header h2' ).text( model.get( 'title' ) );
- document.title = model.get( 'title' ) + ' | ' + '${visualization_display_name}';
- })
-});
-
-</script>
-%endif
+ $( '.chart-header h2' ).click( function(){
+ var returned = prompt( 'Enter a new title:' );
+ if( returned ){
+ model.set( 'title', returned );
+ }
+ });
+ model.on( 'change:title', function(){
+ $( '.chart-header h2' ).text( model.get( 'title' ) );
+ document.title = model.get( 'title' ) + ' | ' + '${visualization_display_name}';
+ })
+ });
+ </script>
+ %endif
</body>
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 lib/galaxy/datatypes/dataproviders/column.py
--- a/lib/galaxy/datatypes/dataproviders/column.py
+++ b/lib/galaxy/datatypes/dataproviders/column.py
@@ -116,8 +116,8 @@
self.column_filters.append( parsed )
def parse_filter( self, filter_param_str ):
- split = filter_param_str.split( '-', 3 )
- if not len( split ) == 3:
+ split = filter_param_str.split( '-', 2 )
+ if not len( split ) >= 3:
return None
column, op, val = split
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 lib/galaxy/managers/deletable.py
--- a/lib/galaxy/managers/deletable.py
+++ b/lib/galaxy/managers/deletable.py
@@ -105,7 +105,7 @@
return item.purged
if new_purged:
self.manager.purge( trans, item, flush=False )
- return self.purged
+ return item.purged
class PurgableFiltersMixin( DeletableFiltersMixin ):
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 lib/galaxy/managers/histories.py
--- a/lib/galaxy/managers/histories.py
+++ b/lib/galaxy/managers/histories.py
@@ -260,7 +260,7 @@
'model_class',
'name',
'deleted',
- #'purged',
+ 'purged',
#'count'
'url',
#TODO: why these?
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -965,7 +965,7 @@
# Old style dynamic options, no dependency information so there isn't
# a lot we can do: if we're dealing with workflows, have to assume
# late validation no matter what.
- if (self.dynamic_options is not None or self.is_dynamic is not None) and ( trans is None or trans.workflow_building_mode ):
+ if self.dynamic_options is not None and ( trans is None or trans.workflow_building_mode ):
return True
# If we got this far, we can actually look at the dependencies
# to see if their values will not be available until runtime.
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 lib/galaxy/webapps/galaxy/api/configuration.py
--- a/lib/galaxy/webapps/galaxy/api/configuration.py
+++ b/lib/galaxy/webapps/galaxy/api/configuration.py
@@ -63,11 +63,11 @@
self.add_view( 'all', self.serializers.keys() )
def default_serializer( self, trans, config, key ):
- return config.get( key, None )
+ return getattr( config, key, None )
def add_serializers( self ):
def _defaults_to( default ):
- return lambda t, i, k: i.get( k, default )
+ return lambda t, i, k: getattr( i, k, default )
self.serializers = {
#TODO: this is available from user data, remove
@@ -90,7 +90,6 @@
'biostar_url_redirect' : lambda *a: self.url_for( controller='biostar', action='biostar_redirect',
qualified=True ),
- 'allow_user_creation' : _defaults_to( False ),
'use_remote_user' : _defaults_to( None ),
'remote_user_logout_href' : _defaults_to( '' ),
'enable_cloud_launch' : _defaults_to( False ),
@@ -111,7 +110,7 @@
def add_serializers( self ):
super( AdminConfigSerializer, self ).add_serializers()
def _defaults_to( default ):
- return lambda t, i, k: i.get( k, default )
+ return lambda t, i, k: getattr( i, k, default )
self.serializers.update({
#TODO: this is available from user data, remove
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 lib/galaxy/webapps/galaxy/api/histories.py
--- a/lib/galaxy/webapps/galaxy/api/histories.py
+++ b/lib/galaxy/webapps/galaxy/api/histories.py
@@ -259,23 +259,23 @@
:type id: str
:param id: the encoded id of the history to delete
:type kwd: dict
- :param kwd: (optional) dictionary structure containing:
+ :param kwd: (optional) dictionary structure containing extra parameters
- * payload: a dictionary itself containing:
- * purge: if True, purge the history and all of its HDAs
+ You can purge a history, removing all it's datasets from disk (if unshared),
+ by passing in ``purge=True`` in the url.
:param keys: same as the use of `keys` in the `index` function above
:param view: same as the use of `view` in the `index` function above
:rtype: dict
- :returns: an error object if an error occurred or a dictionary containing:
- * id: the encoded id of the history,
- * deleted: if the history was marked as deleted,
- * purged: if the history was purged
+ :returns: the deleted or purged history
"""
history_id = id
# a request body is optional here
purge = False
+ if 'purge' in kwd:
+ purge = string_as_bool( kwd.get( 'purge' ) )
+ # for backwards compat, keep the payload sub-dictionary
if kwd.get( 'payload', None ):
purge = string_as_bool( kwd['payload'].get( 'purge', False ) )
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 lib/galaxy/webapps/galaxy/controllers/visualization.py
--- a/lib/galaxy/webapps/galaxy/controllers/visualization.py
+++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py
@@ -801,7 +801,6 @@
raise HTTPNotFound( 'No visualization registry (possibly disabled in galaxy.ini)' )
if visualization_name not in registry.plugins:
raise HTTPNotFound( 'Unknown or invalid visualization: ' + visualization_name )
- # or redirect to list?
plugin = registry.plugins[ visualization_name ]
returned = None
@@ -824,15 +823,21 @@
# look up template and render
template_path = plugin.config[ 'template' ]
returned = registry.fill_template( trans, plugin, template_path,
- visualization_name=visualization_name, visualization_display_name=visualization_display_name,
- title=title, saved_visualization=visualization, visualization_id=encoded_visualization_id,
- embedded=embedded, query=kwargs, vars={}, config=config, **resources )
- #NOTE: passing *unparsed* kwargs as query
- #NOTE: vars is a dictionary for shared data in the template
- # this feels hacky to me but it's what mako recommends:
- # http://docs.makotemplates.org/en/latest/runtime.html
- #TODO: should vars contain all the passed in arguments? is that even necessary?
- #TODO: embedded
+ visualization_name=visualization_name,
+ visualization_display_name=visualization_display_name,
+ title=title,
+ saved_visualization=visualization,
+ visualization_id=encoded_visualization_id,
+ embedded=embedded,
+ #NOTE: passing *unparsed* kwargs as query
+ query=kwargs,
+ #NOTE: vars is a dictionary for shared data in the template
+ # this feels hacky to me but it's what mako recommends:
+ # http://docs.makotemplates.org/en/latest/runtime.html
+ vars={},
+ config=config,
+ **resources
+ )
except Exception, exception:
log.exception( 'error rendering visualization (%s): %s', visualization_name, str( exception ) )
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 lib/galaxy/webapps/galaxy/controllers/workflow.py
--- a/lib/galaxy/webapps/galaxy/controllers/workflow.py
+++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py
@@ -652,9 +652,6 @@
trans.workflow_building_mode = True
module = module_factory.new( trans, type, **kwargs )
tool_model = None
- if type == 'tool':
- tool_model = module.tool.to_json(trans, is_dynamic=False)
- module.state.inputs = copy.deepcopy(tool_model['state_inputs'])
return {
'type': module.type,
'name': module.get_name(),
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 static/scripts/mvc/history/history-model.js
--- a/static/scripts/mvc/history/history-model.js
+++ b/static/scripts/mvc/history/history-model.js
@@ -205,6 +205,11 @@
if( this.get( 'deleted' ) ){ return jQuery.when(); }
return this.save( { deleted: true }, options );
},
+ /** purge this history, _Mark_ing it as purged and removing all dataset data from the server */
+ purge : function( options ){
+ if( this.get( 'purged' ) ){ return jQuery.when(); }
+ return this.save( { purged: true }, options );
+ },
/** save this history, _Mark_ing it as undeleted */
undelete : function( options ){
if( !this.get( 'deleted' ) ){ return jQuery.when(); }
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 static/scripts/mvc/history/multi-panel.js
--- a/static/scripts/mvc/history/multi-panel.js
+++ b/static/scripts/mvc/history/multi-panel.js
@@ -128,12 +128,9 @@
/** set up passed-in panel (if any) and listeners */
initialize : function initialize( options ){
options = options || {};
+ this.purgeAllowed = !_.isUndefined( options.purgeAllowed )? options.purgeAllowed: false;
+ this.panel = options.panel || this.createPanel( options );
- //this.log( this + '.init', options );
- // if model, set up model
- // create panel sub-view
-//TODO: use current-history-panel for current
- this.panel = options.panel || this.createPanel( options );
this.setUpListeners();
},
@@ -143,6 +140,7 @@
model : this.model,
//el : this.$panel(),
// non-current panels should set their hdas to draggable
+ purgeAllowed: this.purgeAllowed,
dragItems : true
}, panelOptions );
//this.log( 'panelOptions:', panelOptions );
@@ -245,9 +243,9 @@
});
return $([
'<div class="panel-controls clear flex-row">',
- this.controlsLeftTemplate( data ),
+ this.controlsLeftTemplate({ history: data, view: this }),
//'<button class="btn btn-default">Herp</button>',
- this.controlsRightTemplate( data ),
+ this.controlsRightTemplate({ history: data, view: this }),
'</div>',
'<div class="inner flex-row flex-column-container">',
'<div id="history-', data.id, '" class="history-column history-panel flex-column"></div>',
@@ -317,24 +315,24 @@
/** controls template displaying controls above the panel based on this.currentHistory */
controlsLeftTemplate : _.template([
'<div class="pull-left">',
- '<% if( history.isCurrentHistory ){ %>',
+ '<% if( data.history.isCurrentHistory ){ %>',
'<strong class="current-label">', _l( 'Current History' ), '</strong>',
'<% } else { %>',
'<button class="switch-to btn btn-default">', _l( 'Switch to' ), '</button>',
'<% } %>',
'</div>'
- ].join( '' ), { variable : 'history' }),
+ ].join( '' ), { variable : 'data' }),
/** controls template displaying controls above the panel based on this.currentHistory */
controlsRightTemplate : _.template([
'<div class="pull-right">',
- '<% if( !history.purged ){ %>',
+ '<% if( !data.history.purged ){ %>',
'<div class="panel-menu btn-group">',
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',
'<span class="caret"></span>',
'</button>',
'<ul class="dropdown-menu pull-right" role="menu">',
- '<% if( !history.deleted ){ %>',
+ '<% if( !data.history.deleted ){ %>',
'<li><a href="javascript:void(0);" class="copy-history">',
_l( 'Copy' ),
'</a></li>',
@@ -349,14 +347,16 @@
_l( 'Undelete' ),
'</a></li>',
'<% } %>',
- //'<li><a href="javascript:void(0);" class="purge-history">',
- // _l( 'Purge' ),
- //'</a></li>',
+ '<% if( data.view.purgeAllowed ){ %>',
+ '<li><a href="javascript:void(0);" class="purge-history">',
+ _l( 'Purge' ),
+ '</a></li>',
+ '<% } %>',
'</ul>',
'<% } %>',
'</div>',
'</div>'
- ].join( '' ), { variable: 'history' }),
+ ].join( '' ), { variable: 'data' }),
// ------------------------------------------------------------------------ misc
/** String rep */
@@ -491,7 +491,7 @@
// handle setting a history as current, triggered by history.setAsCurrent
'set-as-current': multipanel.setCurrentHistory,
// handle deleting a history (depends on whether panels is including deleted or not)
- 'change:deleted': multipanel.handleDeletedHistory,
+ 'change:deleted change:purged': multipanel.handleDeletedHistory,
'sort' : function(){ multipanel.renderColumns( 0 ); }
});
@@ -519,7 +519,7 @@
* based on collection.includeDeleted
*/
handleDeletedHistory : function handleDeletedHistory( history ){
- if( history.get( 'deleted' ) ){
+ if( history.get( 'deleted' ) || history.get( 'purged' ) ){
this.log( 'handleDeletedHistory', this.collection.includeDeleted, history );
var multipanel = this;
column = multipanel.columnMap[ history.id ];
@@ -584,7 +584,10 @@
/** create a column and its panel and set up any listeners to them */
createColumn : function createColumn( history, options ){
// options passed can be re-used, so extend them before adding the model to prevent pollution for the next
- options = _.extend( {}, options, { model: history });
+ options = _.extend( {}, options, {
+ model : history,
+ purgeAllowed: Galaxy.config.allow_user_dataset_purge
+ });
var column = new HistoryPanelColumn( options );
if( history.id === this.currentHistoryId ){ column.currentHistory = true; }
this.setUpColumnListeners( column );
@@ -1047,21 +1050,19 @@
mainTemplate : _.template([
'<div class="header flex-column-container">',
'<div class="control-column control-column-left flex-column">',
- '<button class="create-new btn btn-default">', _l( 'Create new' ), '</button> ',
+ '<button class="create-new btn btn-default" tabindex="4">', _l( 'Create new' ), '</button> ',
'<div id="search-histories" class="search-control"></div>',
'<div id="search-datasets" class="search-control"></div>',
- '<button class="open-more-options btn btn-default">',
- //TODO: tip not working
- '<span class="fa fa-ellipsis-h" title="More options"></span>',
- '</button>',
+ '<a class="open-more-options btn btn-default" tabindex="3">',
+ '<span class="fa fa-ellipsis-h"></span>',
+ '</a>',
'</div>',
// feedback
'<div class="control-column control-column-center flex-column">',
- '<div class="header-info">',
- '</div>',
+ '<div class="header-info">', '</div>',
'</div>',
'<div class="control-column control-column-right flex-column">',
- '<button class="done btn btn-default">', _l( 'Done' ), '</button>',
+ '<button class="done btn btn-default" tabindex="1">', _l( 'Done' ), '</button>',
'</div>',
'</div>',
// middle - where the columns go
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 static/scripts/packed/mvc/history/history-model.js
--- a/static/scripts/packed/mvc/history/history-model.js
+++ b/static/scripts/packed/mvc/history/history-model.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-contents","mvc/base-mvc","utils/localization"],function(h,i,d){var e=Backbone.Model.extend(i.LoggableMixin).extend(i.mixin(i.SearchableModelMixin,{defaults:{model_class:"History",id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:galaxy_config.root+"api/histories",initialize:function(k,l,j){j=j||{};this.logger=j.logger||null;this.log(this+".initialize:",k,l,j);this.log("creating history contents:",l);this.contents=new h.HistoryContents(l||[],{historyId:this.get("id")});this._setUpListeners();this.updateTimeoutId=null},_setUpListeners:function(){this.on("error",function(k,n,j,m,l){this.errorHandler(k,n,j,m,l)});if(this.contents){this.listenTo(this.contents,"error",function(){this.trigger.apply(this,["error:contents"].concat(jQuery.makeArray(arguments)))})}this.on("change:id",function(k,j){if(this.contents){this.contents.historyId=j}},this)},errorHandler:function(k,n,j,m,l){this.clearUpdateTimeout()},ownedByCurrUser:function(){if(!Galaxy||!Galaxy.currUser){return false}if(Galaxy.currUser.isAnonymous()||Galaxy.currUser.id!==this.get("user_id")){return false}return true},contentsCount:function(){return _.reduce(_.values(this.get("state_details")),function(j,k){return j+k},0)},searchAttributes:["name","annotation","tags"],searchAliases:{title:"name",tag:"tags"},checkForUpdates:function(j){if(this.contents.running().length){this.setUpdateTimeout()}else{this.trigger("ready");if(_.isFunction(j)){j.call(this)}}return this},setUpdateTimeout:function(j){j=j||e.UPDATE_DELAY;var k=this;this.clearUpdateTimeout();this.updateTimeoutId=setTimeout(function(){k.refresh()},j);return this.updateTimeoutId},clearUpdateTimeout:function(){if(this.updateTimeoutId){clearTimeout(this.updateTimeoutId);this.updateTimeoutId=null}},refresh:function(k,j){k=k||[];j=j||{};var l=this;j.data=j.data||{};if(k.length){j.data.details=k.join(",")}var m=this.contents.fetch(j);m.done(function(n){l.checkForUpdates(function(){this.fetch()})});return m},_delete:function(j){if(this.get("deleted")){return jQuery.when()}return this.save({deleted:true},j)},undelete:function(j){if(!this.get("deleted")){return jQuery.when()}return this.save({deleted:false},j)},copy:function(m,k){m=(m!==undefined)?(m):(true);if(!this.id){throw new Error("You must set the history ID before copying it.")}var j={history_id:this.id};if(m){j.current=true}if(k){j.name=k}var l=this,n=jQuery.post(this.urlRoot,j);if(m){return n.then(function(o){var p=new e(o);return p.setAsCurrent().done(function(){l.trigger("copied",l,o)})})}return n.done(function(o){l.trigger("copied",l,o)})},setAsCurrent:function(){var j=this,k=jQuery.getJSON("/history/set_as_current?id="+this.id);k.done(function(){j.trigger("set-as-current",j)});return k},toString:function(){return"History("+this.get("id")+","+this.get("name")+")"}}));e.UPDATE_DELAY=4000;e.getHistoryData=function c(j,v){v=v||{};var r=v.detailIdsFn||[];var m=v.hdcaDetailIds||[];var s=jQuery.Deferred(),p=null;function k(w){if(j==="current"){return jQuery.getJSON(galaxy_config.root+"history/current_history_json")}return jQuery.ajax(galaxy_config.root+"api/histories/"+j)}function o(w){return w&&w.empty}function q(x){if(o(x)){return[]}if(_.isFunction(r)){r=r(x)}if(_.isFunction(m)){m=m(x)}var w={};if(r.length){w.dataset_details=r.join(",")}if(m.length){w.dataset_collection_details=m.join(",")}return jQuery.ajax(galaxy_config.root+"api/histories/"+x.id+"/contents",{data:w})}var t=v.historyFn||k,u=v.contentsFn||q;var n=t(j);n.done(function(w){p=w;s.notify({status:"history data retrieved",historyJSON:p})});n.fail(function(y,w,x){s.reject(y,"loading the history")});var l=n.then(u);l.then(function(w){s.notify({status:"contents data retrieved",historyJSON:p,contentsJSON:w});s.resolve(p,w)});l.fail(function(y,w,x){s.reject(y,"loading the contents",{history:p})});return s};var f=Backbone.Collection.extend(i.LoggableMixin).extend({model:e,urlRoot:(window.galaxy_config?galaxy_config.root:"/")+"api/histories",initialize:function(k,j){j=j||{};this.log("HistoryCollection.initialize",arguments);this.includeDeleted=j.includeDeleted||false;this.setUpListeners()},setUpListeners:function a(){var j=this;this.on("change:deleted",function(k){this.debug("change:deleted",j.includeDeleted,k.get("deleted"));if(!j.includeDeleted&&k.get("deleted")){j.remove(k)}});this.on("copied",function(k,l){this.unshift(new e(l,[]))})},create:function g(m,k,j,l){var o=this,n=jQuery.getJSON(galaxy_config.root+"history/create_new_current");return n.done(function(p){var q=new e(p,[],j||{});o.unshift(q);o.trigger("new-current")})},toString:function b(){return"HistoryCollection("+this.length+")"}});return{History:e,HistoryCollection:f}});
\ No newline at end of file
+define(["mvc/history/history-contents","mvc/base-mvc","utils/localization"],function(h,i,d){var e=Backbone.Model.extend(i.LoggableMixin).extend(i.mixin(i.SearchableModelMixin,{defaults:{model_class:"History",id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:galaxy_config.root+"api/histories",initialize:function(k,l,j){j=j||{};this.logger=j.logger||null;this.log(this+".initialize:",k,l,j);this.log("creating history contents:",l);this.contents=new h.HistoryContents(l||[],{historyId:this.get("id")});this._setUpListeners();this.updateTimeoutId=null},_setUpListeners:function(){this.on("error",function(k,n,j,m,l){this.errorHandler(k,n,j,m,l)});if(this.contents){this.listenTo(this.contents,"error",function(){this.trigger.apply(this,["error:contents"].concat(jQuery.makeArray(arguments)))})}this.on("change:id",function(k,j){if(this.contents){this.contents.historyId=j}},this)},errorHandler:function(k,n,j,m,l){this.clearUpdateTimeout()},ownedByCurrUser:function(){if(!Galaxy||!Galaxy.currUser){return false}if(Galaxy.currUser.isAnonymous()||Galaxy.currUser.id!==this.get("user_id")){return false}return true},contentsCount:function(){return _.reduce(_.values(this.get("state_details")),function(j,k){return j+k},0)},searchAttributes:["name","annotation","tags"],searchAliases:{title:"name",tag:"tags"},checkForUpdates:function(j){if(this.contents.running().length){this.setUpdateTimeout()}else{this.trigger("ready");if(_.isFunction(j)){j.call(this)}}return this},setUpdateTimeout:function(j){j=j||e.UPDATE_DELAY;var k=this;this.clearUpdateTimeout();this.updateTimeoutId=setTimeout(function(){k.refresh()},j);return this.updateTimeoutId},clearUpdateTimeout:function(){if(this.updateTimeoutId){clearTimeout(this.updateTimeoutId);this.updateTimeoutId=null}},refresh:function(k,j){k=k||[];j=j||{};var l=this;j.data=j.data||{};if(k.length){j.data.details=k.join(",")}var m=this.contents.fetch(j);m.done(function(n){l.checkForUpdates(function(){this.fetch()})});return m},_delete:function(j){if(this.get("deleted")){return jQuery.when()}return this.save({deleted:true},j)},purge:function(j){if(this.get("purged")){return jQuery.when()}return this.save({purged:true},j)},undelete:function(j){if(!this.get("deleted")){return jQuery.when()}return this.save({deleted:false},j)},copy:function(m,k){m=(m!==undefined)?(m):(true);if(!this.id){throw new Error("You must set the history ID before copying it.")}var j={history_id:this.id};if(m){j.current=true}if(k){j.name=k}var l=this,n=jQuery.post(this.urlRoot,j);if(m){return n.then(function(o){var p=new e(o);return p.setAsCurrent().done(function(){l.trigger("copied",l,o)})})}return n.done(function(o){l.trigger("copied",l,o)})},setAsCurrent:function(){var j=this,k=jQuery.getJSON("/history/set_as_current?id="+this.id);k.done(function(){j.trigger("set-as-current",j)});return k},toString:function(){return"History("+this.get("id")+","+this.get("name")+")"}}));e.UPDATE_DELAY=4000;e.getHistoryData=function c(j,v){v=v||{};var r=v.detailIdsFn||[];var m=v.hdcaDetailIds||[];var s=jQuery.Deferred(),p=null;function k(w){if(j==="current"){return jQuery.getJSON(galaxy_config.root+"history/current_history_json")}return jQuery.ajax(galaxy_config.root+"api/histories/"+j)}function o(w){return w&&w.empty}function q(x){if(o(x)){return[]}if(_.isFunction(r)){r=r(x)}if(_.isFunction(m)){m=m(x)}var w={};if(r.length){w.dataset_details=r.join(",")}if(m.length){w.dataset_collection_details=m.join(",")}return jQuery.ajax(galaxy_config.root+"api/histories/"+x.id+"/contents",{data:w})}var t=v.historyFn||k,u=v.contentsFn||q;var n=t(j);n.done(function(w){p=w;s.notify({status:"history data retrieved",historyJSON:p})});n.fail(function(y,w,x){s.reject(y,"loading the history")});var l=n.then(u);l.then(function(w){s.notify({status:"contents data retrieved",historyJSON:p,contentsJSON:w});s.resolve(p,w)});l.fail(function(y,w,x){s.reject(y,"loading the contents",{history:p})});return s};var f=Backbone.Collection.extend(i.LoggableMixin).extend({model:e,urlRoot:(window.galaxy_config?galaxy_config.root:"/")+"api/histories",initialize:function(k,j){j=j||{};this.log("HistoryCollection.initialize",arguments);this.includeDeleted=j.includeDeleted||false;this.setUpListeners()},setUpListeners:function a(){var j=this;this.on("change:deleted",function(k){this.debug("change:deleted",j.includeDeleted,k.get("deleted"));if(!j.includeDeleted&&k.get("deleted")){j.remove(k)}});this.on("copied",function(k,l){this.unshift(new e(l,[]))})},create:function g(m,k,j,l){var o=this,n=jQuery.getJSON(galaxy_config.root+"history/create_new_current");return n.done(function(p){var q=new e(p,[],j||{});o.unshift(q);o.trigger("new-current")})},toString:function b(){return"HistoryCollection("+this.length+")"}});return{History:e,HistoryCollection:f}});
\ No newline at end of file
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 static/scripts/packed/mvc/history/multi-panel.js
--- a/static/scripts/packed/mvc/history/multi-panel.js
+++ b/static/scripts/packed/mvc/history/multi-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","ui/mode-button","ui/search-input"],function(d,l,z,a){function g(I,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return I.copy()}var F=I.get("name"),C="Copy of '"+F+"'";function D(K){if(!K){if(!Galaxy.modal.$("#invalid-title").size()){var J=$("<p/>").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(J)}return false}return K}function G(J){var K=$('<p><span class="fa fa-spinner fa-spin"></span> Copying history...</p>').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(K);I.copy(true,J).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}function H(){var J=Galaxy.modal.$("#copy-modal-title").val();if(!D(J)){return}G(J)}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['<label for="copy-modal-title">',_l("Enter a title for the copied history"),":","</label><br />",'<input id="copy-modal-title" class="form-control" style="width: 100%" value="',C,'" />'].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:H}},E));$("#copy-modal-title").focus().select();$("#copy-modal-title").on("keydown",function(J){if(J.keyCode===13){H()}})}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($('<span class="fa fa-spinner fa-spin"></span><i>loading datasets...</i>')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(E<C){return false}if(F>D){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(C){C=_.extend(C||{},{isCurrentHistory:this.currentHistory});return $(['<div class="panel-controls clear flex-row">',this.controlsLeftTemplate(C),this.controlsRightTemplate(C),"</div>",'<div class="inner flex-row flex-column-container">','<div id="history-',C.id,'" class="history-column history-panel flex-column"></div>',"</div>"].join(""))},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);if(this.currentHistory){this.panel.$list().before(this.panel._renderDropTargetHelp())}return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history":function(){var C=this;this.model._delete().fail(function(F,D,E){alert(_l("Could not delete the history")+":\n"+E)}).done(function(D){C.render()})},"click .undelete-history":function(){var C=this;this.model.undelete().fail(function(F,D,E){alert(_l("Could not undelete the history")+":\n"+E)}).done(function(D){C.render()})},"click .purge-history":function(){if(confirm(_l("This will permanently remove the data. Are you sure?"))){var C=this;this.model.purge().fail(function(F,D,E){alert(_l("Could not purge the history")+":\n"+E)}).done(function(D){C.render()})}},"click .copy-history":"copy"},copy:function s(){g(this.model)},controlsLeftTemplate:_.template(['<div class="pull-left">',"<% if( history.isCurrentHistory ){ %>",'<strong class="current-label">',_l("Current History"),"</strong>","<% } else { %>",'<button class="switch-to btn btn-default">',_l("Switch to"),"</button>","<% } %>","</div>"].join(""),{variable:"history"}),controlsRightTemplate:_.template(['<div class="pull-right">',"<% if( !history.purged ){ %>",'<div class="panel-menu btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">','<span class="caret"></span>',"</button>",'<ul class="dropdown-menu pull-right" role="menu">',"<% if( !history.deleted ){ %>",'<li><a href="javascript:void(0);" class="copy-history">',_l("Copy"),"</a></li>",'<li><a href="javascript:void(0);" class="delete-history">',_l("Delete"),"</a></li>","<% } else /* if is deleted */ { %>",'<li><a href="javascript:void(0);" class="undelete-history">',_l("Undelete"),"</a></li>","<% } %>","</ul>","<% } %>","</div>","</div>"].join(""),{variable:"history"}),toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({className:"multi-panel-history",initialize:function c(C){C=C||{};this.log(this+".init",C);this.$el.addClass(this.className);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this._initSortOrders();this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},_initSortOrders:function(){function C(D,E){return function F(H,G,I){if(H.id===I){return -1}if(G.id===I){return 1}H=D(H);G=D(G);return E.asc?((H===G)?(0):(H>G?1:-1)):((H===G)?(0):(H>G?-1:1))}}this.sortOrders={update:{text:_l("most recent first"),fn:C(function(D){return Date(D.get("update_time"))},{asc:false})},name:{text:_l("name, a to z"),fn:C(function(D){return D.get("name")},{asc:true})},"name-dsc":{text:_l("name, z to a"),fn:C(function(D){return D.get("name")},{asc:false})},size:{text:_l("size, large to small"),fn:C(function(D){return D.get("size")},{asc:false})},"size-dsc":{text:_l("size, small to large"),fn:C(function(D){return D.get("size")},{asc:true})}};return this.sortOrders},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){if(!(C in this.sortOrders)){C="update"}this.order=C;var G=this.currentHistoryId,F=this.sortOrders[C];this.collection.comparator=function E(I,H){return F.fn(I,H,G)};this.$(".current-order").text(F.text);if(this.$(".more-options").is(":visible")){this.$(".open-more-options.btn").popover("show")}this.collection.sort(D);return this.collection},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(D){var E=this,C={HistoryDatasetAssociation:"hda",HistoryDatasetCollectionAssociation:"hdca"};E.listenTo(D,{"in-view":E.queueHdaFetch});E.listenTo(D.panel,{"view:draggable:dragstart":function(I,G,F,H){E._dropData=JSON.parse(I.dataTransfer.getData("text"));E.currentColumnDropTargetOn()},"view:draggable:dragend":function(I,G,F,H){E._dropData=null;E.currentColumnDropTargetOff()},"droptarget:drop":function(H,I,G){var J=E._dropData.filter(function(K){return((_.isObject(K)&&K.id)&&(_.contains(_.keys(C),K.model_class)))});E._dropData=null;var F=new a.NamedAjaxQueue();J.forEach(function(K){var L=C[K.model_class];F.add({name:"copy-"+K.id,fn:function(){return G.model.contents.copy(K.id,L)}})});F.start();F.done(function(K){G.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.mainTemplate(C));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){return this.$(".header .header-info").text(C)},events:{"click .done.btn":"close","click .create-new.btn":"create","click #include-deleted":"_clickToggleDeletedHistories","click .order .set-order":"_chooseOrder","click #toggle-deleted":"_clickToggleDeletedDatasets","click #toggle-hidden":"_clickToggleHiddenDatasets"},close:function(D){var C="/";if(Galaxy&&Galaxy.options&&Galaxy.options.root){C=Galaxy.options.root}else{if(galaxy_config&&galaxy_config.root){C=galaxy_config.root}}window.location=C},_clickToggleDeletedHistories:function(C){return this.toggleDeletedHistories($(C.currentTarget).is(":checked"))},toggleDeletedHistories:function(C){if(C){window.location=Galaxy.options.root+"history/view_multiple?include_deleted_histories=True"}else{window.location=Galaxy.options.root+"history/view_multiple"}},_clickToggleDeletedDatasets:function(C){return this.toggleDeletedDatasets($(C.currentTarget).is(":checked"))},toggleDeletedDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowDeleted(C,false)},E*200)})},_clickToggleHiddenDatasets:function(C){return this.toggleHiddenDatasets($(C.currentTarget).is(":checked"))},toggleHiddenDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowHidden(C,false)},E*200)})},_chooseOrder:function(D){var C=$(D.currentTarget).data("order");this.sortCollection(C)},setUpBehaviors:function(){var D=this;D._moreOptionsPopover();D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_moreOptionsPopover:function(){return this.$(".open-more-options.btn").popover({container:".header",placement:"bottom",html:true,content:$(this.optionsPopoverTemplate(this))})},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTarget=false;C.panel.$(".history-drop-target").remove()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"},mainTemplate:_.template(['<div class="header flex-column-container">','<div class="control-column control-column-left flex-column">','<button class="create-new btn btn-default">',_l("Create new"),"</button> ",'<div id="search-histories" class="search-control"></div>','<div id="search-datasets" class="search-control"></div>','<button class="open-more-options btn btn-default">','<span class="fa fa-ellipsis-h" title="More options"></span>',"</button>","</div>",'<div class="control-column control-column-center flex-column">','<div class="header-info">',"</div>","</div>",'<div class="control-column control-column-right flex-column">','<button class="done btn btn-default">',_l("Done"),"</button>","</div>","</div>",'<div class="outer-middle flex-row flex-row-container">','<div class="middle flex-column-container flex-row"></div>',"</div>",'<div class="footer flex-column-container">',"</div>"].join(""),{variable:"view"}),optionsPopoverTemplate:_.template(['<div class="more-options">','<div class="order btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',_l("Order histories by")+" ",'<span class="current-order"><%= view.sortOrders[ view.order ].text %></span> ','<span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">',"<% _.each( view.sortOrders, function( order, key ){ %>",'<li><a href="javascript:void(0);" class="set-order" data-order="<%= key %>">',"<%= order.text %>","</a></li>","<% }); %>","</ul>","</div>",'<div class="checkbox"><label><input id="include-deleted" type="checkbox"','<%= view.collection.includeDeleted? " checked" : "" %>>',_l("Include deleted histories"),"</label></div>","<hr />",'<div class="checkbox"><label><input id="toggle-deleted" type="checkbox">',_l("Include deleted datasets"),"</label></div>",'<div class="checkbox"><label><input id="toggle-hidden" type="checkbox">',_l("Include hidden datasets"),"</label></div>","</div>"].join(""),{variable:"view"})});return{MultiPanelColumns:m}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","ui/mode-button","ui/search-input"],function(d,l,z,a){function g(I,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return I.copy()}var F=I.get("name"),C="Copy of '"+F+"'";function D(K){if(!K){if(!Galaxy.modal.$("#invalid-title").size()){var J=$("<p/>").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(J)}return false}return K}function G(J){var K=$('<p><span class="fa fa-spinner fa-spin"></span> Copying history...</p>').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(K);I.copy(true,J).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}function H(){var J=Galaxy.modal.$("#copy-modal-title").val();if(!D(J)){return}G(J)}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['<label for="copy-modal-title">',_l("Enter a title for the copied history"),":","</label><br />",'<input id="copy-modal-title" class="form-control" style="width: 100%" value="',C,'" />'].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:H}},E));$("#copy-modal-title").focus().select();$("#copy-modal-title").on("keydown",function(J){if(J.keyCode===13){H()}})}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.purgeAllowed=!_.isUndefined(C.purgeAllowed)?C.purgeAllowed:false;this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,purgeAllowed:this.purgeAllowed,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($('<span class="fa fa-spinner fa-spin"></span><i>loading datasets...</i>')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(E<C){return false}if(F>D){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(C){C=_.extend(C||{},{isCurrentHistory:this.currentHistory});return $(['<div class="panel-controls clear flex-row">',this.controlsLeftTemplate({history:C,view:this}),this.controlsRightTemplate({history:C,view:this}),"</div>",'<div class="inner flex-row flex-column-container">','<div id="history-',C.id,'" class="history-column history-panel flex-column"></div>',"</div>"].join(""))},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);if(this.currentHistory){this.panel.$list().before(this.panel._renderDropTargetHelp())}return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history":function(){var C=this;this.model._delete().fail(function(F,D,E){alert(_l("Could not delete the history")+":\n"+E)}).done(function(D){C.render()})},"click .undelete-history":function(){var C=this;this.model.undelete().fail(function(F,D,E){alert(_l("Could not undelete the history")+":\n"+E)}).done(function(D){C.render()})},"click .purge-history":function(){if(confirm(_l("This will permanently remove the data. Are you sure?"))){var C=this;this.model.purge().fail(function(F,D,E){alert(_l("Could not purge the history")+":\n"+E)}).done(function(D){C.render()})}},"click .copy-history":"copy"},copy:function s(){g(this.model)},controlsLeftTemplate:_.template(['<div class="pull-left">',"<% if( data.history.isCurrentHistory ){ %>",'<strong class="current-label">',_l("Current History"),"</strong>","<% } else { %>",'<button class="switch-to btn btn-default">',_l("Switch to"),"</button>","<% } %>","</div>"].join(""),{variable:"data"}),controlsRightTemplate:_.template(['<div class="pull-right">',"<% if( !data.history.purged ){ %>",'<div class="panel-menu btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">','<span class="caret"></span>',"</button>",'<ul class="dropdown-menu pull-right" role="menu">',"<% if( !data.history.deleted ){ %>",'<li><a href="javascript:void(0);" class="copy-history">',_l("Copy"),"</a></li>",'<li><a href="javascript:void(0);" class="delete-history">',_l("Delete"),"</a></li>","<% } else /* if is deleted */ { %>",'<li><a href="javascript:void(0);" class="undelete-history">',_l("Undelete"),"</a></li>","<% } %>","<% if( data.view.purgeAllowed ){ %>",'<li><a href="javascript:void(0);" class="purge-history">',_l("Purge"),"</a></li>","<% } %>","</ul>","<% } %>","</div>","</div>"].join(""),{variable:"data"}),toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({className:"multi-panel-history",initialize:function c(C){C=C||{};this.log(this+".init",C);this.$el.addClass(this.className);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this._initSortOrders();this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},_initSortOrders:function(){function C(D,E){return function F(H,G,I){if(H.id===I){return -1}if(G.id===I){return 1}H=D(H);G=D(G);return E.asc?((H===G)?(0):(H>G?1:-1)):((H===G)?(0):(H>G?-1:1))}}this.sortOrders={update:{text:_l("most recent first"),fn:C(function(D){return Date(D.get("update_time"))},{asc:false})},name:{text:_l("name, a to z"),fn:C(function(D){return D.get("name")},{asc:true})},"name-dsc":{text:_l("name, z to a"),fn:C(function(D){return D.get("name")},{asc:false})},size:{text:_l("size, large to small"),fn:C(function(D){return D.get("size")},{asc:false})},"size-dsc":{text:_l("size, small to large"),fn:C(function(D){return D.get("size")},{asc:true})}};return this.sortOrders},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted change:purged":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")||D.get("purged")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){if(!(C in this.sortOrders)){C="update"}this.order=C;var G=this.currentHistoryId,F=this.sortOrders[C];this.collection.comparator=function E(I,H){return F.fn(I,H,G)};this.$(".current-order").text(F.text);if(this.$(".more-options").is(":visible")){this.$(".open-more-options.btn").popover("show")}this.collection.sort(D);return this.collection},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E,purgeAllowed:Galaxy.config.allow_user_dataset_purge});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(D){var E=this,C={HistoryDatasetAssociation:"hda",HistoryDatasetCollectionAssociation:"hdca"};E.listenTo(D,{"in-view":E.queueHdaFetch});E.listenTo(D.panel,{"view:draggable:dragstart":function(I,G,F,H){E._dropData=JSON.parse(I.dataTransfer.getData("text"));E.currentColumnDropTargetOn()},"view:draggable:dragend":function(I,G,F,H){E._dropData=null;E.currentColumnDropTargetOff()},"droptarget:drop":function(H,I,G){var J=E._dropData.filter(function(K){return((_.isObject(K)&&K.id)&&(_.contains(_.keys(C),K.model_class)))});E._dropData=null;var F=new a.NamedAjaxQueue();J.forEach(function(K){var L=C[K.model_class];F.add({name:"copy-"+K.id,fn:function(){return G.model.contents.copy(K.id,L)}})});F.start();F.done(function(K){G.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.mainTemplate(C));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){return this.$(".header .header-info").text(C)},events:{"click .done.btn":"close","click .create-new.btn":"create","click #include-deleted":"_clickToggleDeletedHistories","click .order .set-order":"_chooseOrder","click #toggle-deleted":"_clickToggleDeletedDatasets","click #toggle-hidden":"_clickToggleHiddenDatasets"},close:function(D){var C="/";if(Galaxy&&Galaxy.options&&Galaxy.options.root){C=Galaxy.options.root}else{if(galaxy_config&&galaxy_config.root){C=galaxy_config.root}}window.location=C},_clickToggleDeletedHistories:function(C){return this.toggleDeletedHistories($(C.currentTarget).is(":checked"))},toggleDeletedHistories:function(C){if(C){window.location=Galaxy.options.root+"history/view_multiple?include_deleted_histories=True"}else{window.location=Galaxy.options.root+"history/view_multiple"}},_clickToggleDeletedDatasets:function(C){return this.toggleDeletedDatasets($(C.currentTarget).is(":checked"))},toggleDeletedDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowDeleted(C,false)},E*200)})},_clickToggleHiddenDatasets:function(C){return this.toggleHiddenDatasets($(C.currentTarget).is(":checked"))},toggleHiddenDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowHidden(C,false)},E*200)})},_chooseOrder:function(D){var C=$(D.currentTarget).data("order");this.sortCollection(C)},setUpBehaviors:function(){var D=this;D._moreOptionsPopover();D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_moreOptionsPopover:function(){return this.$(".open-more-options.btn").popover({container:".header",placement:"bottom",html:true,content:$(this.optionsPopoverTemplate(this))})},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTarget=false;C.panel.$(".history-drop-target").remove()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"},mainTemplate:_.template(['<div class="header flex-column-container">','<div class="control-column control-column-left flex-column">','<button class="create-new btn btn-default" tabindex="4">',_l("Create new"),"</button> ",'<div id="search-histories" class="search-control"></div>','<div id="search-datasets" class="search-control"></div>','<a class="open-more-options btn btn-default" tabindex="3">','<span class="fa fa-ellipsis-h"></span>',"</a>","</div>",'<div class="control-column control-column-center flex-column">','<div class="header-info">',"</div>","</div>",'<div class="control-column control-column-right flex-column">','<button class="done btn btn-default" tabindex="1">',_l("Done"),"</button>","</div>","</div>",'<div class="outer-middle flex-row flex-row-container">','<div class="middle flex-column-container flex-row"></div>',"</div>",'<div class="footer flex-column-container">',"</div>"].join(""),{variable:"view"}),optionsPopoverTemplate:_.template(['<div class="more-options">','<div class="order btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',_l("Order histories by")+" ",'<span class="current-order"><%= view.sortOrders[ view.order ].text %></span> ','<span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">',"<% _.each( view.sortOrders, function( order, key ){ %>",'<li><a href="javascript:void(0);" class="set-order" data-order="<%= key %>">',"<%= order.text %>","</a></li>","<% }); %>","</ul>","</div>",'<div class="checkbox"><label><input id="include-deleted" type="checkbox"','<%= view.collection.includeDeleted? " checked" : "" %>>',_l("Include deleted histories"),"</label></div>","<hr />",'<div class="checkbox"><label><input id="toggle-deleted" type="checkbox">',_l("Include deleted datasets"),"</label></div>",'<div class="checkbox"><label><input id="toggle-hidden" type="checkbox">',_l("Include hidden datasets"),"</label></div>","</div>"].join(""),{variable:"view"})});return{MultiPanelColumns:m}});
\ No newline at end of file
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 static/style/Gruntfile.js
--- a/static/style/Gruntfile.js
+++ b/static/style/Gruntfile.js
@@ -64,7 +64,10 @@
// remove tmp files
clean: {
- clean : [ fmt('%s/tmp-site-config.less', out) ]
+ clean : [
+ fmt( '%s/tmp-site-config.less', out ),
+ fmt( '%s/jstree.css', out )
+ ]
}
});
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -2101,14 +2101,14 @@
.multi-panel-history .flex-column-container{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}
.multi-panel-history .flex-row,.multi-panel-history .flex-column{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;-webkit-align-self:auto;-ms-flex-item-align:auto;align-self:auto}
.multi-panel-history .header,.multi-panel-history .footer{width:100%;background-color:lightgrey}.multi-panel-history .header .btn,.multi-panel-history .footer .btn{height:21px}
-.multi-panel-history .header{min-height:29px;max-height:29px}
+.multi-panel-history .header{min-height:29px;max-height:29px}.multi-panel-history .header .more-options .btn{height:26px}
+.multi-panel-history .header .more-options input[type=checkbox]{margin-top:1px}
.multi-panel-history .footer{min-height:0;max-height:0}
.multi-panel-history .smaller-btn{height:20px;line-height:normal;font-size:90%;padding-top:0px;padding-bottom:0px}
.multi-panel-history .control-column{margin-top:4px}.multi-panel-history .control-column .btn{height:20px;line-height:normal;font-size:90%;padding-top:0px;padding-bottom:0px}
.multi-panel-history .control-column .search-control{display:inline-block;width:40%}.multi-panel-history .control-column .search-control .search-clear,.multi-panel-history .control-column .search-control .search-loading{margin-top:-22px}
.multi-panel-history .control-column input.search-query{font-size:90%;height:21px;line-height:normal;padding:2px 2px 1px 2px}
.multi-panel-history .control-column .open-more-options{padding:2px 6px 2px 6px;font-size:100%}
-.multi-panel-history .control-column .more-options input[type=checkbox]{margin-top:2px}
.multi-panel-history .control-column .header-info{display:inline-block;padding:2px 4px 2px 4px;color:grey}
.multi-panel-history .control-column.control-column-right,.multi-panel-history .control-column.control-column-left{margin-right:8px;margin-left:8px}.multi-panel-history .control-column.control-column-right>*,.multi-panel-history .control-column.control-column-left>*{margin:0px 4px 4px 0px}
.multi-panel-history .control-column.control-column-center{text-align:center;max-height:22px;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-height:22px}
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 static/style/src/less/history.less
--- a/static/style/src/less/history.less
+++ b/static/style/src/less/history.less
@@ -650,6 +650,15 @@
.header {
min-height: @mph-header_height;
max-height: @mph-header_height;
+ // popover containing sorting and filters
+ .more-options {
+ .btn {
+ height: 26px;
+ }
+ input[type=checkbox] {
+ margin-top: 1px;
+ }
+ }
}
.footer {
min-height: @mph-footer_height;
@@ -691,9 +700,6 @@
padding: 2px 6px 2px 6px;
font-size: 100%;
}
- .more-options input[type=checkbox] {
- margin-top: 2px;
- }
.header-info {
display: inline-block;
padding: 2px 4px 2px 4px;
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 test/casperjs/api-history-tests.js
--- a/test/casperjs/api-history-tests.js
+++ b/test/casperjs/api-history-tests.js
@@ -118,7 +118,7 @@
"Id of last history (from index) DOES appear after undeletion: " + newFirstHistory.id );
//TODO: show, deleted flag
- //TODO: delete, purge flag
+
// ------------------------------------------------------------------------------------------- UPDATE
// ........................................................................................... name
@@ -294,6 +294,28 @@
//this.test.comment( 'calling show with /deleted should raise a bad request' );
/*
*/
+
+ // ------------------------------------------------------------------------------------------- PURGE
+ var newHistoryId = null;
+ spaceghost.then( function(){
+ this.test.comment( 'calling purge should mark a history, its datasets, and remove the files' );
+ // create new history
+ var newHistory = this.api.histories.create({ name: 'To Purge' });
+ newHistoryId = newHistory.id;
+ });
+ spaceghost.openHomePage().api.tools.thenUploadToCurrent({
+ filepath: '../../test-data/1.sam'
+ });
+ spaceghost.then( function(){
+ var recent = this.api.histories.show( newHistoryId );
+ this.debug( 'size:\n' + recent.size );
+
+ this.api.assertRaises( function(){
+ this.api.histories.delete_( recent.id, true );
+ }, 403, 'This instance does not allow user dataset purging', 'Config does not allow thrown' );
+ });
+ //TODO: a way to set the config to allow user purging and then being able to test this would be good.
+
//this.debug( this.jsonStr( historyShow ) );
});
diff -r 4589eb71e192251691fbf82aac75b9b0d6f47c18 -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 test/casperjs/modules/api.js
--- a/test/casperjs/modules/api.js
+++ b/test/casperjs/modules/api.js
@@ -267,10 +267,12 @@
this.api.spaceghost.info( 'histories.delete: ' + [ id, (( purge )?( '(purge!)' ):( '' )) ] );
// py.payload <-> ajax.data
- var payload = ( purge )?({ purge: true }):({});
- return this.api._ajax( utils.format( this.urlTpls.delete_, this.api.ensureId( id ) ), {
- type : 'DELETE',
- data : payload
+ var url = utils.format( this.urlTpls.delete_, this.api.ensureId( id ) );
+ if( purge ){
+ url += '?purge=True';
+ }
+ return this.api._ajax( url, {
+ type : 'DELETE'
});
};
https://bitbucket.org/galaxy/galaxy-central/commits/17dd62d9a0b0/
Changeset: 17dd62d9a0b0
User: dannon
Date: 2015-02-17 13:37:37+00:00
Summary: Supply remote annotation for complex mappings (also squelches a warning which was causing job failures)
Affected #: 1 file
diff -r d004eb0d8be7f7b64974f368d16d5fd217a08bd8 -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py
+++ b/lib/galaxy/model/mapping.py
@@ -1457,7 +1457,8 @@
backref=backref( "parent", primaryjoin=( model.HistoryDatasetAssociation.table.c.parent_id == model.HistoryDatasetAssociation.table.c.id ), remote_side=[model.HistoryDatasetAssociation.table.c.id], uselist=False ) ),
visible_children=relation(
model.HistoryDatasetAssociation,
- primaryjoin=( ( model.HistoryDatasetAssociation.table.c.parent_id == model.HistoryDatasetAssociation.table.c.id ) & ( model.HistoryDatasetAssociation.table.c.visible == True ) ) ),
+ primaryjoin=( ( model.HistoryDatasetAssociation.table.c.parent_id == model.HistoryDatasetAssociation.table.c.id ) & ( model.HistoryDatasetAssociation.table.c.visible == True ) ),
+ remote_side=[model.HistoryDatasetAssociation.table.c.id] ),
tags=relation( model.HistoryDatasetAssociationTagAssociation, order_by=model.HistoryDatasetAssociationTagAssociation.table.c.id, backref='history_tag_associations' ),
annotations=relation( model.HistoryDatasetAssociationAnnotationAssociation, order_by=model.HistoryDatasetAssociationAnnotationAssociation.table.c.id, backref="hdas" ),
ratings=relation( model.HistoryDatasetAssociationRatingAssociation, order_by=model.HistoryDatasetAssociationRatingAssociation.table.c.id, backref="hdas" ),
@@ -1784,7 +1785,8 @@
backref=backref( "parent", primaryjoin=( model.LibraryDatasetDatasetAssociation.table.c.parent_id == model.LibraryDatasetDatasetAssociation.table.c.id ), remote_side=[model.LibraryDatasetDatasetAssociation.table.c.id] ) ),
visible_children=relation(
model.LibraryDatasetDatasetAssociation,
- primaryjoin=( ( model.LibraryDatasetDatasetAssociation.table.c.parent_id == model.LibraryDatasetDatasetAssociation.table.c.id ) & ( model.LibraryDatasetDatasetAssociation.table.c.visible == True ) ) ),
+ primaryjoin=( ( model.LibraryDatasetDatasetAssociation.table.c.parent_id == model.LibraryDatasetDatasetAssociation.table.c.id ) & ( model.LibraryDatasetDatasetAssociation.table.c.visible == True ) ),
+ remote_side=[model.LibraryDatasetDatasetAssociation.table.c.id]),
extended_metadata=relation(
model.ExtendedMetadata,
primaryjoin=( ( model.LibraryDatasetDatasetAssociation.table.c.extended_metadata_id == model.ExtendedMetadata.table.c.id ) )
https://bitbucket.org/galaxy/galaxy-central/commits/1374a75dfeb1/
Changeset: 1374a75dfeb1
User: dannon
Date: 2015-02-17 14:16:11+00:00
Summary: Merge.
Affected #: 11 files
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -22,4 +22,4 @@
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
782fa60fc65488aea0c618d723e9a63d42caf865 latest_2014.10.06
2e8dd2949dd3eee0f56f9a3a5ebf1b2baca24aee release_2015.01.13
-577b270034b48d90e58ffbea296e700d229545c9 latest_2015.01.13
+d677cb314dccedd8743eba26f1d446cdf97ebf16 latest_2015.01.13
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
@@ -443,7 +443,7 @@
@web.require_admin
def import_workflow( self, trans, workflow_name, repository_id, **kwd ):
"""Import a workflow contained in an installed tool shed repository into Galaxy."""
- message = escape( kwd.get( 'message', '' ) )
+ message = str( escape( kwd.get( 'message', '' ) ) )
status = kwd.get( 'status', 'done' )
if workflow_name:
workflow_name = encoding_util.tool_shed_decode( workflow_name )
@@ -480,7 +480,7 @@
tool shed repository.
"""
# Get the tool_shed_repository from one of the tool_dependencies.
- message = escape( kwd.get( 'message', '' ) )
+ message = str( escape( kwd.get( 'message', '' ) ) )
status = kwd.get( 'status', 'done' )
err_msg = ''
tool_shed_repository = tool_dependencies[ 0 ].tool_shed_repository
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/galaxy/controllers/library_admin.py
--- a/lib/galaxy/webapps/galaxy/controllers/library_admin.py
+++ b/lib/galaxy/webapps/galaxy/controllers/library_admin.py
@@ -162,14 +162,14 @@
library.root_folder = root_folder
trans.sa_session.add_all( ( library, root_folder ) )
trans.sa_session.flush()
- message = "The new library named '%s' has been created" % library.name
+ message = "The new library named '%s' has been created" % escape( library.name )
return trans.response.send_redirect( web.url_for( controller='library_common',
action='browse_library',
cntrller='library_admin',
id=trans.security.encode_id( library.id ),
message=message,
status='done' ) )
- return trans.fill_template( '/admin/library/new_library.mako', message=escape( message ), status=escape( status ) )
+ return trans.fill_template( '/admin/library/new_library.mako', message=message, status=escape( status ) )
@web.expose
@web.require_admin
def delete_library( self, trans, id, **kwd ):
@@ -222,7 +222,7 @@
trans.sa_session.add( library_folder )
trans.sa_session.flush()
if not library.deleted:
- message = "Library '%s' has not been marked deleted, so it cannot be purged" % ( library.name )
+ message = "Library '%s' has not been marked deleted, so it cannot be purged" % escape( library.name )
return trans.response.send_redirect( web.url_for( controller='library_admin',
action='browse_libraries',
message=message,
@@ -232,7 +232,7 @@
library.purged = True
trans.sa_session.add( library )
trans.sa_session.flush()
- message = "Library '%s' and all of its contents have been purged, datasets will be removed from disk via the cleanup_datasets script" % library.name
+ message = "Library '%s' and all of its contents have been purged, datasets will be removed from disk via the cleanup_datasets script" % escape( library.name )
return trans.response.send_redirect( web.url_for( controller='library_admin',
action='browse_libraries',
message=message,
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/galaxy/controllers/library_common.py
--- a/lib/galaxy/webapps/galaxy/controllers/library_common.py
+++ b/lib/galaxy/webapps/galaxy/controllers/library_common.py
@@ -248,7 +248,7 @@
trans.sa_session.refresh( library )
# Copy the permissions to the root folder
trans.app.security_agent.copy_library_permissions( trans, library, library.root_folder )
- message = "Permissions updated for library '%s'." % library.name
+ message = "Permissions updated for library '%s'." % escape( library.name )
return trans.response.send_redirect( web.url_for( controller='library_common',
action='library_permissions',
cntrller=cntrller,
@@ -310,7 +310,7 @@
if info_association and ( not( inherited ) or info_association.inheritable ):
widgets = new_folder.get_template_widgets( trans )
if info_association:
- message = "The new folder named '%s' has been added to the data library. " % new_folder.name
+ message = "The new folder named '%s' has been added to the data library. " % escape( new_folder.name )
message += "Additional information about this folder may be added using the inherited template."
return trans.fill_template( '/library/common/folder_info.mako',
cntrller=cntrller,
@@ -325,7 +325,7 @@
message=escape( message ),
status='done' )
# If not inheritable info_association, redirect to the library.
- message = "The new folder named '%s' has been added to the data library." % new_folder.name
+ message = "The new folder named '%s' has been added to the data library." % escape( new_folder.name )
# SM: This is the second place where the API controller would
# reference the library id:
return trans.response.send_redirect( web.url_for( controller='library_common',
@@ -373,7 +373,7 @@
folder.description = new_description
trans.sa_session.add( folder )
trans.sa_session.flush()
- message = "Information updated for folder '%s'." % folder.name
+ message = "Information updated for folder '%s'." % escape( folder.name )
return trans.response.send_redirect( web.url_for( controller='library_common',
action='folder_info',
cntrller=cntrller,
@@ -429,7 +429,7 @@
permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
trans.app.security_agent.set_all_library_permissions( trans, folder, permissions )
trans.sa_session.refresh( folder )
- message = "Permissions updated for folder '%s'." % folder.name
+ message = "Permissions updated for folder '%s'." % escape( folder.name )
return trans.response.send_redirect( web.url_for( controller='library_common',
action='folder_permissions',
cntrller=cntrller,
@@ -498,10 +498,10 @@
if ldda.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( kwd.get( 'datatype' ) ).allow_datatype_change:
trans.app.datatypes_registry.change_datatype( ldda, kwd.get( 'datatype' ) )
trans.sa_session.flush()
- message = "Data type changed for library dataset '%s'." % ldda.name
+ message = "Data type changed for library dataset '%s'." % escape( ldda.name )
status = 'done'
else:
- message = "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( ldda.extension, kwd.get( 'datatype' ) )
+ message = "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( escape( ldda.extension ), escape( kwd.get( 'datatype' ) ) )
status = 'error'
else:
message = "This dataset is currently being used as input or output. You cannot change datatype until the jobs have completed or you have canceled them."
@@ -532,7 +532,7 @@
setattr( ldda.metadata, name, spec.unwrap( kwd.get( name, None ) ) )
ldda.metadata.dbkey = dbkey
ldda.datatype.after_setting_metadata( ldda )
- message = "Attributes updated for library dataset '%s'." % ldda.name
+ message = "Attributes updated for library dataset '%s'." % escape( ldda.name )
status = 'done'
else:
message = "Attributes updated, but metadata could not be changed because this dataset is currently being used as input or output. You must cancel or wait for these jobs to complete before changing metadata."
@@ -546,7 +546,7 @@
if name not in [ 'name', 'info', 'dbkey' ]:
if spec.get( 'default' ):
setattr( ldda.metadata, name, spec.unwrap( spec.get( 'default' ) ) )
- message = "Attributes have been queued to be updated for library dataset '%s'." % ldda.name
+ message = "Attributes have been queued to be updated for library dataset '%s'." % escape( ldda.name )
status = 'done'
trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute( trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming = { 'input1':ldda } )
else:
@@ -570,7 +570,7 @@
self.delete_extended_metadata(trans, ex_obj)
ex_obj = self.create_extended_metadata(trans, payload)
self.set_item_extended_metadata_obj(trans, ldda, ex_obj)
- message = "Updated Extended metadata '%s'." % ldda.name
+ message = "Updated Extended metadata '%s'." % escape( ldda.name )
status = 'done'
else:
message = "LDDA not found"
@@ -581,7 +581,7 @@
if ex_obj is not None:
self.unset_item_extended_metadata_obj(trans, ldda)
self.delete_extended_metadata(trans, ex_obj)
- message = "Deleted Extended metadata '%s'." % ldda.name
+ message = "Deleted Extended metadata '%s'." % escape( ldda.name )
status = 'done'
@@ -658,7 +658,7 @@
@web.expose
def ldda_permissions( self, trans, cntrller, library_id, folder_id, id, **kwd ):
- message = escape( kwd.get( 'message', '' ) )
+ message = str( escape( kwd.get( 'message', '' ) ) )
status = kwd.get( 'status', 'done' )
show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
@@ -744,7 +744,7 @@
trans.app.security_agent.set_all_library_permissions( trans, ldda, permissions )
trans.sa_session.refresh( ldda )
if len( lddas ) == 1:
- message = "Permissions updated for dataset '%s'." % ldda.name
+ message = "Permissions updated for dataset '%s'." % escape( ldda.name )
else:
message = 'Permissions updated for %d datasets.' % len( lddas )
status= 'done'
@@ -937,13 +937,13 @@
ldda_id_list = [ str( v.id ) for k, v in created_outputs_dict.items() ]
created_ldda_ids=",".join( ldda_id_list )
if replace_dataset:
- message = "Added %d dataset versions to the library dataset '%s' in the folder '%s'." % ( total_added, replace_dataset_name, folder.name )
+ message = "Added %d dataset versions to the library dataset '%s' in the folder '%s'." % ( total_added, escape( replace_dataset_name ), escape( folder.name ) )
else:
if not folder.parent:
# Libraries have the same name as their root_folder
- message = "Added %d datasets to the library '%s' (each is selected). " % ( total_added, folder.name )
+ message = "Added %d datasets to the library '%s' (each is selected). " % ( total_added, escape( folder.name ) )
else:
- message = "Added %d datasets to the folder '%s' (each is selected). " % ( total_added, folder.name )
+ message = "Added %d datasets to the folder '%s' (each is selected). " % ( total_added, escape( folder.name ) )
if cntrller == 'library_admin':
message += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
status='done'
@@ -1399,13 +1399,13 @@
ldda_id_list = created_ldda_ids.split( ',' )
total_added = len( ldda_id_list )
if replace_dataset:
- message = "Added %d dataset versions to the library dataset '%s' in the folder '%s'." % ( total_added, replace_dataset.name, folder.name )
+ message = "Added %d dataset versions to the library dataset '%s' in the folder '%s'." % ( total_added, escape( replace_dataset.name ), escape( folder.name ) )
else:
if not folder.parent:
# Libraries have the same name as their root_folder
- message = "Added %d datasets to the library '%s' (each is selected). " % ( total_added, folder.name )
+ message = "Added %d datasets to the library '%s' (each is selected). " % ( total_added, escape( folder.name ) )
else:
- message = "Added %d datasets to the folder '%s' (each is selected). " % ( total_added, folder.name )
+ message = "Added %d datasets to the folder '%s' (each is selected). " % ( total_added, escape( folder.name ) )
if cntrller == 'library_admin':
message += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
else:
@@ -1591,7 +1591,7 @@
library_dataset.info = new_info
trans.sa_session.add( library_dataset )
trans.sa_session.flush()
- message = "Information updated for library dataset '%s'." % library_dataset.name
+ message = "Information updated for library dataset '%s'." % escape( library_dataset.name )
status = 'done'
# See if we have any associated templates
widgets = []
@@ -1648,7 +1648,7 @@
# Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
trans.app.security_agent.set_all_library_permissions( trans, library_dataset.library_dataset_dataset_association, permissions )
trans.sa_session.refresh( library_dataset.library_dataset_dataset_association )
- message = "Permisisons updated for library dataset '%s'." % library_dataset.name
+ message = "Permisisons updated for library dataset '%s'." % escape( library_dataset.name )
status = 'done'
roles = trans.app.security_agent.get_legitimate_roles( trans, library_dataset, cntrller )
return trans.fill_template( '/library/common/library_dataset_permissions.mako',
@@ -1677,23 +1677,23 @@
contents = util.string_as_bool( kwd.get( 'contents', 'False' ) )
trans.app.security_agent.make_library_public( library, contents=contents )
if contents:
- message = "The data library (%s) and all its contents have been made publicly accessible." % library.name
+ message = "The data library (%s) and all its contents have been made publicly accessible." % escape( library.name )
else:
- message = "The data library (%s) has been made publicly accessible, but access to its contents has been left unchanged." % library.name
+ message = "The data library (%s) has been made publicly accessible, but access to its contents has been left unchanged." % escape( library.name )
elif item_type == 'folder':
folder = trans.sa_session.query( trans.model.LibraryFolder ).get( trans.security.decode_id( id ) )
self._check_access( trans, cntrller, is_admin, folder, current_user_roles, use_panels, library_id, show_deleted )
self._check_manage( trans, cntrller, is_admin, folder, current_user_roles, use_panels, library_id, show_deleted )
trans.app.security_agent.make_folder_public( folder )
- message = "All of the contents of folder (%s) have been made publicly accessible." % folder.name
+ message = "All of the contents of folder (%s) have been made publicly accessible." % escape( folder.name )
elif item_type == 'ldda':
ldda = trans.sa_session.query( trans.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( id ) )
self._check_access( trans, cntrller, is_admin, ldda.library_dataset, current_user_roles, use_panels, library_id, show_deleted )
self._check_manage( trans, cntrller, is_admin, ldda.library_dataset, current_user_roles, use_panels, library_id, show_deleted )
trans.app.security_agent.make_dataset_public( ldda.dataset )
- message = "The libary dataset (%s) has been made publicly accessible." % ldda.name
+ message = "The libary dataset (%s) has been made publicly accessible." % escape( ldda.name )
else:
- message = "Invalid item_type (%s) received." % str( item_type )
+ message = "Invalid item_type (%s) received." % escape( str( item_type ) )
status = 'error'
return trans.response.send_redirect( web.url_for( controller='library_common',
action='browse_library',
@@ -1803,7 +1803,7 @@
if invalid_lddas:
message += "You are not authorized to manage permissions on %s: " % inflector.cond_plural( len( invalid_lddas ), "dataset" )
for ldda in invalid_lddas:
- message += '(%s)' % ldda.name
+ message += '(%s)' % escape( ldda.name )
message += '. '
if valid_ldda_ids:
encoded_ldda_ids = [ trans.security.encode_id( ldda_id ) for ldda_id in valid_ldda_ids ]
@@ -1967,7 +1967,7 @@
return archive.stream
else:
status = 'error'
- message = 'Invalid action (%s) specified.' % str( action )
+ message = 'Invalid action (%s) specified.' % escape( str( action ) )
if library_id:
# If we have a library_id, browse the associated library
return trans.response.send_redirect( web.url_for( controller='library_common',
@@ -2053,11 +2053,11 @@
status = 'error'
invalid_datasets += 1
elif ldda.dataset.state not in [ trans.model.Dataset.states.OK, trans.model.Dataset.states.ERROR ]:
- message += "You cannot import dataset '%s' since its state is '%s'. " % ( ldda.name, ldda.dataset.state )
+ message += "You cannot import dataset '%s' since its state is '%s'. " % ( escape( ldda.name ), ldda.dataset.state )
status = 'error'
invalid_datasets += 1
elif not ldda.has_data():
- message += "You cannot import empty dataset '%s'. " % ldda.name
+ message += "You cannot import empty dataset '%s'. " % escape( ldda.name )
status = 'error'
invalid_datasets += 1
else:
@@ -2140,7 +2140,7 @@
except ValueError:
return None
if not ( is_admin or trans.app.security_agent.can_modify_library_item( current_user_roles, item ) ):
- message = "You are not authorized to modify %s '%s'." % ( item_desc, item.name )
+ message = "You are not authorized to modify %s '%s'." % ( escape( item_desc ), escape( item.name ) )
return trans.response.send_redirect( web.url_for( controller='library_common',
action='browse_library',
cntrller=cntrller,
@@ -2151,9 +2151,9 @@
info_association, inherited = item.get_info_association( restrict=True )
if info_association:
if info_association.inheritable:
- message = "The template for this %s will no longer be inherited to contained folders and datasets." % item_desc
+ message = "The template for this %s will no longer be inherited to contained folders and datasets." % escape( item_desc )
else:
- message = "The template for this %s will now be inherited to contained folders and datasets." % item_desc
+ message = "The template for this %s will now be inherited to contained folders and datasets." % escape( item_desc )
info_association.inheritable = not( info_association.inheritable )
trans.sa_session.add( info_association )
trans.sa_session.flush()
@@ -2260,7 +2260,7 @@
elif invalid_lddas:
message += "You are not authorized to move %s: " % inflector.cond_plural( len( invalid_lddas ), "dataset" )
for ldda in invalid_lddas:
- message += '(%s)' % ldda.name
+ message += '(%s)' % escape( ldda.name )
message += '. '
num_source = len( move_ldda_ids ) - invalid_items
message = "%i %s moved to folder (%s) within data library (%s)" % ( num_source,
@@ -2278,9 +2278,9 @@
move_folder.parent = target_folder
trans.sa_session.add( move_folder )
flush_required = True
- message = "Moved folder (%s) to folder (%s) within data library (%s) " % ( move_folder.name,
- target_folder.name,
- target_library.name )
+ message = "Moved folder (%s) to folder (%s) within data library (%s) " % ( escape( move_folder.name ),
+ escape( target_folder.name ),
+ escape( target_library.name ) )
if flush_required:
trans.sa_session.flush()
if target_library:
@@ -2400,7 +2400,7 @@
is_admin = ( trans.user_is_admin() and cntrller == 'library_admin' )
current_user_roles = trans.get_current_user_roles()
if item_type not in item_types:
- message = 'Bad item_type specified: %s' % str( item_type )
+ message = 'Bad item_type specified: %s' % escape( str( item_type ) )
status = 'error'
else:
if item_type == 'library_dataset':
@@ -2430,12 +2430,12 @@
if flush_needed:
trans.sa_session.flush()
if valid_items:
- message += "%d %s marked deleted. " % ( valid_items, inflector.cond_plural( valid_items, item_desc ) )
+ message += "%d %s marked deleted. " % ( valid_items, escape( inflector.cond_plural( valid_items, item_desc ) ) )
if invalid_items:
- message += '%d invalid %s specifield. ' % ( invalid_items, inflector.cond_plural( invalid_items, item_desc ) )
+ message += '%d invalid %s specifield. ' % ( invalid_items, escape( inflector.cond_plural( invalid_items, item_desc ) ) )
status = 'error'
if not_authorized_items:
- message += 'You are not authorized to delete %d %s. ' % ( not_authorized_items, inflector.cond_plural( not_authorized_items, item_desc ) )
+ message += 'You are not authorized to delete %d %s. ' % ( not_authorized_items, escape( inflector.cond_plural( not_authorized_items, item_desc ) ) )
status = 'error'
if item_type == 'library':
return trans.response.send_redirect( web.url_for( controller=cntrller,
@@ -2462,7 +2462,7 @@
is_admin = ( trans.user_is_admin() and cntrller == 'library_admin' )
current_user_roles = trans.get_current_user_roles()
if item_type not in item_types:
- message = 'Bad item_type specified: %s' % str( item_type )
+ message = 'Bad item_type specified: %s' % escape( str( item_type ) )
status = 'error'
else:
if item_type == 'library_dataset':
@@ -2496,15 +2496,15 @@
if flush_needed:
trans.sa_session.flush()
if valid_items:
- message += "%d %s marked undeleted. " % ( valid_items, inflector.cond_plural( valid_items, item_desc ) )
+ message += "%d %s marked undeleted. " % ( valid_items, escape( inflector.cond_plural( valid_items, item_desc ) ) )
if invalid_items:
- message += '%d invalid %s specifield. ' % ( invalid_items, inflector.cond_plural( invalid_items, item_desc ) )
+ message += '%d invalid %s specifield. ' % ( invalid_items, escape( inflector.cond_plural( invalid_items, item_desc ) ) )
status = 'error'
if not_authorized_items:
- message += 'You are not authorized to undelete %d %s. ' % ( not_authorized_items, inflector.cond_plural( not_authorized_items, item_desc ) )
+ message += 'You are not authorized to undelete %d %s. ' % ( not_authorized_items, escape( inflector.cond_plural( not_authorized_items, item_desc ) ) )
status = 'error'
if purged_items:
- message += '%d %s marked purged, so cannot be undeleted. ' % ( purged_items, inflector.cond_plural( purged_items, item_desc ) )
+ message += '%d %s marked purged, so cannot be undeleted. ' % ( purged_items, escape( inflector.cond_plural( purged_items, item_desc ) ) )
status = 'error'
if item_type == 'library':
return trans.response.send_redirect( web.url_for( controller=cntrller,
@@ -2525,7 +2525,7 @@
if isinstance( item, trans.model.HistoryDatasetAssociation ):
# Make sure the user has the DATASET_ACCESS permission on the history_dataset_association.
if not item:
- message = "Invalid history dataset (%s) specified." % str( item )
+ message = "Invalid history dataset (%s) specified." % escape( str( item ) )
can_access = False
elif not trans.app.security_agent.can_access_dataset( current_user_roles, item.dataset ) and item.history.user==trans.user:
message = "You do not have permission to access the history dataset with id (%s)." % str( item.id )
@@ -2533,7 +2533,7 @@
else:
# Make sure the user has the LIBRARY_ACCESS permission on the library item.
if not item:
- message = "Invalid library item (%s) specified." % str( item )
+ message = "Invalid library item (%s) specified." % escape( str( item ) )
can_access = False
elif not ( is_admin or trans.app.security_agent.can_access_library_item( current_user_roles, item, trans.user ) ):
if isinstance( item, trans.model.Library ):
@@ -2542,7 +2542,7 @@
item_type = 'folder'
else:
item_type = '(unknown item type)'
- message = "You do not have permission to access the %s with id (%s)." % ( item_type, str( item.id ) )
+ message = "You do not have permission to access the %s with id (%s)." % ( escape( item_type ), str( item.id ) )
can_access = False
if not can_access:
if cntrller == 'api':
@@ -2566,7 +2566,7 @@
def _check_add( self, trans, cntrller, is_admin, item, current_user_roles, use_panels, library_id, show_deleted ):
# Deny access if the user is not an admin and does not have the LIBRARY_ADD permission.
if not ( is_admin or trans.app.security_agent.can_add_library_item( current_user_roles, item ) ):
- message = "You are not authorized to add an item to (%s)." % item.name
+ message = "You are not authorized to add an item to (%s)." % escape( item.name )
# Redirect to the real parent library since we know we have access to it.
if cntrller == 'api':
return 403, message
@@ -2585,7 +2585,7 @@
if not ( is_admin or \
( trans.app.security_agent.can_manage_library_item( current_user_roles, item ) and
trans.app.security_agent.can_manage_dataset( current_user_roles, library_dataset.library_dataset_dataset_association.dataset ) ) ):
- message = "You are not authorized to manage permissions on library dataset (%s)." % library_dataset.name
+ message = "You are not authorized to manage permissions on library dataset (%s)." % escape( library_dataset.name )
if cntrller == 'api':
return 403, message
return trans.response.send_redirect( web.url_for( controller='library_common',
@@ -2597,7 +2597,7 @@
status='error' ) )
# Deny access if the user is not an admin and does not have the LIBRARY_MANAGE permission.
if not ( is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, item ) ):
- message = "You are not authorized to manage permissions on (%s)." % item.name
+ message = "You are not authorized to manage permissions on (%s)." % escape( item.name )
if cntrller == 'api':
return 403, message
return trans.response.send_redirect( web.url_for( controller='library_common',
@@ -2611,7 +2611,7 @@
def _check_modify( self, trans, cntrller, is_admin, item, current_user_roles, use_panels, library_id, show_deleted ):
# Deny modification if the user is not an admin and does not have the LIBRARY_MODIFY permission.
if not ( is_admin or trans.app.security_agent.can_modify_library_item( current_user_roles, item ) ):
- message = "You are not authorized to modify (%s)." % item.name
+ message = "You are not authorized to modify (%s)." % escape( item.name )
if cntrller == 'api':
return 403, message
return trans.response.send_redirect( web.url_for( controller='library_common',
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/galaxy/controllers/user.py
--- a/lib/galaxy/webapps/galaxy/controllers/user.py
+++ b/lib/galaxy/webapps/galaxy/controllers/user.py
@@ -574,7 +574,7 @@
username = trans.user.username
is_activation_sent = self.send_verification_email( trans, email, username )
if is_activation_sent:
- message = 'This account has not been activated yet. The activation link has been sent again. Please check your email address <b>%s</b> including the spam/trash folder.<br><a target="_top" href="%s">Return to the home page</a>.' % ( email, url_for( '/' ) )
+ message = 'This account has not been activated yet. The activation link has been sent again. Please check your email address <b>%s</b> including the spam/trash folder.<br><a target="_top" href="%s">Return to the home page</a>.' % ( escape( email ), url_for( '/' ) )
status = 'error'
else:
message = 'This account has not been activated yet but we are unable to send the activation link. Please contact your local Galaxy administrator.<br><a target="_top" href="%s">Return to the home page</a>.' % url_for( '/' )
@@ -678,7 +678,7 @@
trans.log_event( "User created a new account" )
trans.log_event( "User logged in" )
if success and is_admin:
- message = 'Created new user account (%s)' % user.email
+ message = 'Created new user account (%s)' % escape( user.email )
trans.response.send_redirect( web.url_for( controller='admin',
action='users',
cntrller=cntrller,
@@ -775,7 +775,7 @@
if trans.webapp.name == 'galaxy' and trans.app.config.user_activation_on:
is_activation_sent = self.send_verification_email( trans, email, username )
if is_activation_sent:
- message = 'Now logged in as %s.<br>Verification email has been sent to your email address. Please verify it by clicking the activation link in the email.<br>Please check your spam/trash folder in case you cannot find the message.<br><a target="_top" href="%s">Return to the home page.</a>' % ( user.email, url_for( '/' ) )
+ message = 'Now logged in as %s.<br>Verification email has been sent to your email address. Please verify it by clicking the activation link in the email.<br>Please check your spam/trash folder in case you cannot find the message.<br><a target="_top" href="%s">Return to the home page.</a>' % ( escape( user.email ), url_for( '/' ) )
success = True
else:
message = 'Unable to send activation email, please contact your local Galaxy administrator.'
@@ -783,7 +783,7 @@
message += ' Contact: %s' % trans.app.config.error_email_to
success = False
else: # User activation is OFF, proceed without sending the activation email.
- message = 'Now logged in as %s.<br><a target="_top" href="%s">Return to the home page.</a>' % ( user.email, url_for( '/' ) )
+ message = 'Now logged in as %s.<br><a target="_top" href="%s">Return to the home page.</a>' % ( escape( user.email ), url_for( '/' ) )
success = True
return ( message, status, user, success )
@@ -793,7 +793,7 @@
"""
if username is None:
username = trans.user.username
- activation_link = self.prepare_activation_link( trans, email )
+ activation_link = self.prepare_activation_link( trans, escape( email ) )
body = ("Hello %s,\n\n"
"In order to complete the activation process for %s begun on %s at %s, please click on the following link to verify your account:\n\n"
@@ -801,7 +801,7 @@
"By clicking on the above link and opening a Galaxy account you are also confirming that you have read and agreed to Galaxy's Terms and Conditions for use of this service (%s). This includes a quota limit of one account per user. Attempts to subvert this limit by creating multiple accounts or through any other method may result in termination of all associated accounts and data.\n\n"
"Please contact us if you need help with your account at: %s. You can also browse resources available at: %s. \n\n"
"More about the Galaxy Project can be found at galaxyproject.org\n\n"
- "Your Galaxy Team" % (username, email,
+ "Your Galaxy Team" % (escape( username ), escape( email ),
datetime.utcnow().strftime( "%D"),
trans.request.host, activation_link,
trans.app.config.terms_url,
@@ -1178,7 +1178,7 @@
if not username:
return "A public user name is required in the tool shed."
if username in [ 'repos' ]:
- return "The term <b>%s</b> is a reserved word in the tool shed, so it cannot be used as a public user name." % username
+ return "The term <b>%s</b> is a reserved word in the tool shed, so it cannot be used as a public user name." % escape( username )
message = "\n".join( [ validate_email( trans, email ),
validate_password( trans, password, confirm ),
validate_publicname( trans, username ) ] ).rstrip()
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/galaxy/controllers/workflow.py
--- a/lib/galaxy/webapps/galaxy/controllers/workflow.py
+++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py
@@ -826,7 +826,7 @@
"""
url = kwd.get( 'url', '' )
workflow_text = kwd.get( 'workflow_text', '' )
- message = escape( kwd.get( 'message', '' ) )
+ message = str( escape( kwd.get( 'message', '' ) ) )
status = kwd.get( 'status', 'done' )
import_button = kwd.get( 'import_button', False )
# The special Galaxy integration landing page's URL on myExperiment
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/tool_shed/controllers/admin.py
--- a/lib/galaxy/webapps/tool_shed/controllers/admin.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/admin.py
@@ -140,7 +140,7 @@
trans.sa_session.flush()
# Update the Tool Shed's repository registry.
trans.app.repository_registry.add_category_entry( category )
- message = "Category '%s' has been created" % category.name
+ message = "Category '%s' has been created" % escape( category.name )
status = 'done'
trans.response.send_redirect( web.url_for( controller='admin',
action='manage_categories',
@@ -184,7 +184,7 @@
count += 1
deleted_repositories += " %s " % repository.name
if count:
- message = "Deleted %d %s: %s" % ( count, inflector.cond_plural( len( ids ), "repository" ), deleted_repositories )
+ message = "Deleted %d %s: %s" % ( count, inflector.cond_plural( len( ids ), "repository" ), escape( deleted_repositories ) )
else:
message = "All selected repositories were already marked deleted."
else:
@@ -258,7 +258,7 @@
if original_category_name != new_name:
# Update the Tool Shed's repository registry.
trans.app.repository_registry.edit_category_entry( original_category_name, new_name )
- message = "The information has been saved for category '%s'" % ( category.name )
+ message = "The information has been saved for category '%s'" % escape( category.name )
status = 'done'
return trans.response.send_redirect( web.url_for( controller='admin',
action='manage_categories',
@@ -431,7 +431,7 @@
trans.sa_session.flush()
# Update the Tool Shed's repository registry.
trans.app.repository_registry.remove_category_entry( category )
- message += " %s " % category.name
+ message += " %s " % escape( category.name )
else:
message = "No category ids received for deleting."
status = 'error'
@@ -462,7 +462,7 @@
trans.sa_session.delete( rca )
trans.sa_session.flush()
purged_categories += " %s " % category.name
- message = "Purged %d categories: %s" % ( count, purged_categories )
+ message = "Purged %d categories: %s" % ( count, escape( purged_categories ) )
else:
message = "No category ids received for purging."
status = 'error'
@@ -491,7 +491,7 @@
trans.app.repository_registry.add_category_entry( category )
count += 1
undeleted_categories += " %s" % category.name
- message = "Undeleted %d categories: %s" % ( count, undeleted_categories )
+ message = "Undeleted %d categories: %s" % ( count, escape( undeleted_categories ) )
else:
message = "No category ids received for undeleting."
status = 'error'
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/tool_shed/controllers/repository.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py
@@ -1126,11 +1126,11 @@
if mark_deprecated:
# Update the repository registry.
trans.app.repository_registry.remove_entry( repository )
- message = 'The repository <b>%s</b> has been marked as deprecated.' % repository.name
+ message = 'The repository <b>%s</b> has been marked as deprecated.' % escape( repository.name )
else:
# Update the repository registry.
trans.app.repository_registry.add_entry( repository )
- message = 'The repository <b>%s</b> has been marked as not deprecated.' % repository.name
+ message = 'The repository <b>%s</b> has been marked as not deprecated.' % escape( repository.name )
trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
operation='repositories_i_own',
@@ -1388,8 +1388,8 @@
else:
kwd[ 'message' ] = "tool id: <b>%s</b><br/>tool name: <b>%s</b><br/>tool version: <b>%s</b><br/>exact matches only: <b>%s</b>" % \
( basic_util.stringify( tool_ids ),
- basic_util.stringify( tool_names ),
- basic_util.stringify( tool_versions ),
+ escape( basic_util.stringify( tool_names ) ),
+ escape( basic_util.stringify( tool_versions ) ),
str( exact_matches_checked ) )
self.matched_repository_grid.title = "Repositories with matching tools"
return self.matched_repository_grid( trans, **kwd )
@@ -1479,7 +1479,7 @@
return self.install_matched_repository_grid( trans, **kwd )
else:
kwd[ 'message' ] = "workflow name: <b>%s</b><br/>exact matches only: <b>%s</b>" % \
- ( basic_util.stringify( workflow_names ), str( exact_matches_checked ) )
+ ( escape( basic_util.stringify( workflow_names ) ), str( exact_matches_checked ) )
self.matched_repository_grid.title = "Repositories with matching workflows"
return self.matched_repository_grid( trans, **kwd )
else:
@@ -3076,7 +3076,7 @@
changeset_revision=changeset_revision ) )
else:
message = "The change log for the repository named <b>%s</b> owned by <b>%s</b> does not include revision <b>%s</b>." % \
- ( str( name ), str( owner ), str( changeset_revision ) )
+ ( escape( str( name ) ), escape( str( owner ) ), escape( str( changeset_revision ) ) )
return trans.response.send_redirect( web.url_for( controller='repository',
action='index',
repository_id=repository_id,
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/tool_shed/controllers/repository_review.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository_review.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository_review.py
@@ -51,7 +51,7 @@
review.approved = approved_select_field_value
trans.sa_session.add( review )
trans.sa_session.flush()
- message = 'Approved value <b>%s</b> saved for this revision.' % approved_select_field_value
+ message = 'Approved value <b>%s</b> saved for this revision.' % escape( approved_select_field_value )
repository_id = trans.security.encode_id( review.repository_id )
changeset_revision = review.changeset_revision
return trans.response.send_redirect( web.url_for( controller='repository_review',
@@ -121,7 +121,7 @@
component = trans.app.model.Component( name=name, description=description )
trans.sa_session.add( component )
trans.sa_session.flush()
- message = "Component '%s' has been created" % component.name
+ message = "Component '%s' has been created" % escape( component.name )
status = 'done'
trans.response.send_redirect( web.url_for( controller='repository_review',
action='manage_components',
@@ -151,7 +151,7 @@
repository_id=repository_id,
changeset_revision=changeset_revision,
user_id=trans.security.encode_id( trans.user.id ) ):
- message = "You have already created a review for revision <b>%s</b> of repository <b>%s</b>." % ( changeset_revision, repository.name )
+ message = "You have already created a review for revision <b>%s</b> of repository <b>%s</b>." % ( changeset_revision, escape( repository.name ) )
status = "error"
else:
# See if there are any reviews for previous changeset revisions that the user can copy.
@@ -188,7 +188,7 @@
status=status ) )
else:
message = "A new review cannot be created for revision <b>%s</b> of repository <b>%s</b>. Select a valid revision and try again." \
- % ( changeset_revision, repository.name )
+ % ( changeset_revision, escape( repository.name ) )
kwd[ 'message' ] = message
kwd[ 'status' ] = 'error'
else:
@@ -218,7 +218,7 @@
component.description = new_description
trans.sa_session.add( component )
trans.sa_session.flush()
- message = "The information has been saved for the component named <b>%s</b>" % ( component.name )
+ message = "The information has been saved for the component named <b>%s</b>" % escape( component.name )
status = 'done'
return trans.response.send_redirect( web.url_for( controller='repository_review',
action='manage_components',
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/galaxy/webapps/tool_shed/controllers/upload.py
--- a/lib/galaxy/webapps/tool_shed/controllers/upload.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/upload.py
@@ -256,7 +256,7 @@
source_type = "file"
source = uploaded_file_filename
message = "The %s <b>%s</b> has been successfully%suploaded to the repository. " % \
- ( source_type, source, uncompress_str )
+ ( source_type, escape( source ), uncompress_str )
if istar and ( undesirable_dirs_removed or undesirable_files_removed ):
items_removed = undesirable_dirs_removed + undesirable_files_removed
message += " %d undesirable items (.hg .svn .git directories, .DS_Store, hgrc files, etc) " % items_removed
diff -r 17dd62d9a0b0614f5b7fd1fbf360450855c7ab18 -r 1374a75dfeb17af8913e4fffa8b6f11bdf6f668e lib/tool_shed/util/repository_util.py
--- a/lib/tool_shed/util/repository_util.py
+++ b/lib/tool_shed/util/repository_util.py
@@ -167,7 +167,7 @@
sa_session.flush()
# Update the repository registry.
app.repository_registry.add_entry( repository )
- message = "Repository <b>%s</b> has been created." % str( repository.name )
+ message = "Repository <b>%s</b> has been created." % escape( str( repository.name ) )
return repository, message
def create_repository_admin_role( app, repository ):
@@ -285,7 +285,7 @@
repositories=in_repositories )
sa_session.refresh( role )
message += "Role <b>%s</b> has been associated with %d users, %d groups and %d repositories. " % \
- ( str( role.name ), len( in_users ), len( in_groups ), len( in_repositories ) )
+ ( escape( str( role.name ) ), len( in_users ), len( in_groups ), len( in_repositories ) )
in_users = []
out_users = []
in_groups = []
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: Update tag latest_2015.01.13 for changeset d677cb314dcc
by commits-noreply@bitbucket.org 17 Feb '15
by commits-noreply@bitbucket.org 17 Feb '15
17 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/02ddea42faad/
Changeset: 02ddea42faad
Branch: stable
User: natefoo
Date: 2015-02-17 14:00:22+00:00
Summary: Update tag latest_2015.01.13 for changeset d677cb314dcc
Affected #: 1 file
diff -r d677cb314dccedd8743eba26f1d446cdf97ebf16 -r 02ddea42faade21f5a76602d1e4035aa02a0151e .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -22,4 +22,4 @@
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
782fa60fc65488aea0c618d723e9a63d42caf865 latest_2014.10.06
2e8dd2949dd3eee0f56f9a3a5ebf1b2baca24aee release_2015.01.13
-a6e9a1d7267410f697f30102ed78317b08274026 latest_2015.01.13
+d677cb314dccedd8743eba26f1d446cdf97ebf16 latest_2015.01.13
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: carlfeberhard: UI, History: allow purging, implement purge option in multi-view dropdowns; Managers: fix purgable return value; API, histories: return purged in summary view
by commits-noreply@bitbucket.org 16 Feb '15
by commits-noreply@bitbucket.org 16 Feb '15
16 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6ed64b39bcef/
Changeset: 6ed64b39bcef
User: carlfeberhard
Date: 2015-02-16 22:51:51+00:00
Summary: UI, History: allow purging, implement purge option in multi-view dropdowns; Managers: fix purgable return value; API, histories: return purged in summary view
Affected #: 8 files
diff -r 1fb4f358624fbc34472c63991db8a93d690f37af -r 6ed64b39bcef417a2361e42336c3a46ad10354de client/galaxy/scripts/mvc/history/history-model.js
--- a/client/galaxy/scripts/mvc/history/history-model.js
+++ b/client/galaxy/scripts/mvc/history/history-model.js
@@ -205,6 +205,11 @@
if( this.get( 'deleted' ) ){ return jQuery.when(); }
return this.save( { deleted: true }, options );
},
+ /** purge this history, _Mark_ing it as purged and removing all dataset data from the server */
+ purge : function( options ){
+ if( this.get( 'purged' ) ){ return jQuery.when(); }
+ return this.save( { purged: true }, options );
+ },
/** save this history, _Mark_ing it as undeleted */
undelete : function( options ){
if( !this.get( 'deleted' ) ){ return jQuery.when(); }
diff -r 1fb4f358624fbc34472c63991db8a93d690f37af -r 6ed64b39bcef417a2361e42336c3a46ad10354de client/galaxy/scripts/mvc/history/multi-panel.js
--- a/client/galaxy/scripts/mvc/history/multi-panel.js
+++ b/client/galaxy/scripts/mvc/history/multi-panel.js
@@ -128,12 +128,9 @@
/** set up passed-in panel (if any) and listeners */
initialize : function initialize( options ){
options = options || {};
+ this.purgeAllowed = !_.isUndefined( options.purgeAllowed )? options.purgeAllowed: false;
+ this.panel = options.panel || this.createPanel( options );
- //this.log( this + '.init', options );
- // if model, set up model
- // create panel sub-view
-//TODO: use current-history-panel for current
- this.panel = options.panel || this.createPanel( options );
this.setUpListeners();
},
@@ -143,6 +140,7 @@
model : this.model,
//el : this.$panel(),
// non-current panels should set their hdas to draggable
+ purgeAllowed: this.purgeAllowed,
dragItems : true
}, panelOptions );
//this.log( 'panelOptions:', panelOptions );
@@ -245,9 +243,9 @@
});
return $([
'<div class="panel-controls clear flex-row">',
- this.controlsLeftTemplate( data ),
+ this.controlsLeftTemplate({ history: data, view: this }),
//'<button class="btn btn-default">Herp</button>',
- this.controlsRightTemplate( data ),
+ this.controlsRightTemplate({ history: data, view: this }),
'</div>',
'<div class="inner flex-row flex-column-container">',
'<div id="history-', data.id, '" class="history-column history-panel flex-column"></div>',
@@ -317,24 +315,24 @@
/** controls template displaying controls above the panel based on this.currentHistory */
controlsLeftTemplate : _.template([
'<div class="pull-left">',
- '<% if( history.isCurrentHistory ){ %>',
+ '<% if( data.history.isCurrentHistory ){ %>',
'<strong class="current-label">', _l( 'Current History' ), '</strong>',
'<% } else { %>',
'<button class="switch-to btn btn-default">', _l( 'Switch to' ), '</button>',
'<% } %>',
'</div>'
- ].join( '' ), { variable : 'history' }),
+ ].join( '' ), { variable : 'data' }),
/** controls template displaying controls above the panel based on this.currentHistory */
controlsRightTemplate : _.template([
'<div class="pull-right">',
- '<% if( !history.purged ){ %>',
+ '<% if( !data.history.purged ){ %>',
'<div class="panel-menu btn-group">',
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',
'<span class="caret"></span>',
'</button>',
'<ul class="dropdown-menu pull-right" role="menu">',
- '<% if( !history.deleted ){ %>',
+ '<% if( !data.history.deleted ){ %>',
'<li><a href="javascript:void(0);" class="copy-history">',
_l( 'Copy' ),
'</a></li>',
@@ -349,14 +347,16 @@
_l( 'Undelete' ),
'</a></li>',
'<% } %>',
- //'<li><a href="javascript:void(0);" class="purge-history">',
- // _l( 'Purge' ),
- //'</a></li>',
+ '<% if( data.view.purgeAllowed ){ %>',
+ '<li><a href="javascript:void(0);" class="purge-history">',
+ _l( 'Purge' ),
+ '</a></li>',
+ '<% } %>',
'</ul>',
'<% } %>',
'</div>',
'</div>'
- ].join( '' ), { variable: 'history' }),
+ ].join( '' ), { variable: 'data' }),
// ------------------------------------------------------------------------ misc
/** String rep */
@@ -491,7 +491,7 @@
// handle setting a history as current, triggered by history.setAsCurrent
'set-as-current': multipanel.setCurrentHistory,
// handle deleting a history (depends on whether panels is including deleted or not)
- 'change:deleted': multipanel.handleDeletedHistory,
+ 'change:deleted change:purged': multipanel.handleDeletedHistory,
'sort' : function(){ multipanel.renderColumns( 0 ); }
});
@@ -519,7 +519,7 @@
* based on collection.includeDeleted
*/
handleDeletedHistory : function handleDeletedHistory( history ){
- if( history.get( 'deleted' ) ){
+ if( history.get( 'deleted' ) || history.get( 'purged' ) ){
this.log( 'handleDeletedHistory', this.collection.includeDeleted, history );
var multipanel = this;
column = multipanel.columnMap[ history.id ];
@@ -584,7 +584,10 @@
/** create a column and its panel and set up any listeners to them */
createColumn : function createColumn( history, options ){
// options passed can be re-used, so extend them before adding the model to prevent pollution for the next
- options = _.extend( {}, options, { model: history });
+ options = _.extend( {}, options, {
+ model : history,
+ purgeAllowed: Galaxy.config.allow_user_dataset_purge
+ });
var column = new HistoryPanelColumn( options );
if( history.id === this.currentHistoryId ){ column.currentHistory = true; }
this.setUpColumnListeners( column );
diff -r 1fb4f358624fbc34472c63991db8a93d690f37af -r 6ed64b39bcef417a2361e42336c3a46ad10354de lib/galaxy/managers/deletable.py
--- a/lib/galaxy/managers/deletable.py
+++ b/lib/galaxy/managers/deletable.py
@@ -105,7 +105,7 @@
return item.purged
if new_purged:
self.manager.purge( trans, item, flush=False )
- return self.purged
+ return item.purged
class PurgableFiltersMixin( DeletableFiltersMixin ):
diff -r 1fb4f358624fbc34472c63991db8a93d690f37af -r 6ed64b39bcef417a2361e42336c3a46ad10354de lib/galaxy/managers/histories.py
--- a/lib/galaxy/managers/histories.py
+++ b/lib/galaxy/managers/histories.py
@@ -260,7 +260,7 @@
'model_class',
'name',
'deleted',
- #'purged',
+ 'purged',
#'count'
'url',
#TODO: why these?
diff -r 1fb4f358624fbc34472c63991db8a93d690f37af -r 6ed64b39bcef417a2361e42336c3a46ad10354de static/scripts/mvc/history/history-model.js
--- a/static/scripts/mvc/history/history-model.js
+++ b/static/scripts/mvc/history/history-model.js
@@ -205,6 +205,11 @@
if( this.get( 'deleted' ) ){ return jQuery.when(); }
return this.save( { deleted: true }, options );
},
+ /** purge this history, _Mark_ing it as purged and removing all dataset data from the server */
+ purge : function( options ){
+ if( this.get( 'purged' ) ){ return jQuery.when(); }
+ return this.save( { purged: true }, options );
+ },
/** save this history, _Mark_ing it as undeleted */
undelete : function( options ){
if( !this.get( 'deleted' ) ){ return jQuery.when(); }
diff -r 1fb4f358624fbc34472c63991db8a93d690f37af -r 6ed64b39bcef417a2361e42336c3a46ad10354de static/scripts/mvc/history/multi-panel.js
--- a/static/scripts/mvc/history/multi-panel.js
+++ b/static/scripts/mvc/history/multi-panel.js
@@ -128,12 +128,9 @@
/** set up passed-in panel (if any) and listeners */
initialize : function initialize( options ){
options = options || {};
+ this.purgeAllowed = !_.isUndefined( options.purgeAllowed )? options.purgeAllowed: false;
+ this.panel = options.panel || this.createPanel( options );
- //this.log( this + '.init', options );
- // if model, set up model
- // create panel sub-view
-//TODO: use current-history-panel for current
- this.panel = options.panel || this.createPanel( options );
this.setUpListeners();
},
@@ -143,6 +140,7 @@
model : this.model,
//el : this.$panel(),
// non-current panels should set their hdas to draggable
+ purgeAllowed: this.purgeAllowed,
dragItems : true
}, panelOptions );
//this.log( 'panelOptions:', panelOptions );
@@ -245,9 +243,9 @@
});
return $([
'<div class="panel-controls clear flex-row">',
- this.controlsLeftTemplate( data ),
+ this.controlsLeftTemplate({ history: data, view: this }),
//'<button class="btn btn-default">Herp</button>',
- this.controlsRightTemplate( data ),
+ this.controlsRightTemplate({ history: data, view: this }),
'</div>',
'<div class="inner flex-row flex-column-container">',
'<div id="history-', data.id, '" class="history-column history-panel flex-column"></div>',
@@ -317,24 +315,24 @@
/** controls template displaying controls above the panel based on this.currentHistory */
controlsLeftTemplate : _.template([
'<div class="pull-left">',
- '<% if( history.isCurrentHistory ){ %>',
+ '<% if( data.history.isCurrentHistory ){ %>',
'<strong class="current-label">', _l( 'Current History' ), '</strong>',
'<% } else { %>',
'<button class="switch-to btn btn-default">', _l( 'Switch to' ), '</button>',
'<% } %>',
'</div>'
- ].join( '' ), { variable : 'history' }),
+ ].join( '' ), { variable : 'data' }),
/** controls template displaying controls above the panel based on this.currentHistory */
controlsRightTemplate : _.template([
'<div class="pull-right">',
- '<% if( !history.purged ){ %>',
+ '<% if( !data.history.purged ){ %>',
'<div class="panel-menu btn-group">',
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',
'<span class="caret"></span>',
'</button>',
'<ul class="dropdown-menu pull-right" role="menu">',
- '<% if( !history.deleted ){ %>',
+ '<% if( !data.history.deleted ){ %>',
'<li><a href="javascript:void(0);" class="copy-history">',
_l( 'Copy' ),
'</a></li>',
@@ -349,14 +347,16 @@
_l( 'Undelete' ),
'</a></li>',
'<% } %>',
- //'<li><a href="javascript:void(0);" class="purge-history">',
- // _l( 'Purge' ),
- //'</a></li>',
+ '<% if( data.view.purgeAllowed ){ %>',
+ '<li><a href="javascript:void(0);" class="purge-history">',
+ _l( 'Purge' ),
+ '</a></li>',
+ '<% } %>',
'</ul>',
'<% } %>',
'</div>',
'</div>'
- ].join( '' ), { variable: 'history' }),
+ ].join( '' ), { variable: 'data' }),
// ------------------------------------------------------------------------ misc
/** String rep */
@@ -491,7 +491,7 @@
// handle setting a history as current, triggered by history.setAsCurrent
'set-as-current': multipanel.setCurrentHistory,
// handle deleting a history (depends on whether panels is including deleted or not)
- 'change:deleted': multipanel.handleDeletedHistory,
+ 'change:deleted change:purged': multipanel.handleDeletedHistory,
'sort' : function(){ multipanel.renderColumns( 0 ); }
});
@@ -519,7 +519,7 @@
* based on collection.includeDeleted
*/
handleDeletedHistory : function handleDeletedHistory( history ){
- if( history.get( 'deleted' ) ){
+ if( history.get( 'deleted' ) || history.get( 'purged' ) ){
this.log( 'handleDeletedHistory', this.collection.includeDeleted, history );
var multipanel = this;
column = multipanel.columnMap[ history.id ];
@@ -584,7 +584,10 @@
/** create a column and its panel and set up any listeners to them */
createColumn : function createColumn( history, options ){
// options passed can be re-used, so extend them before adding the model to prevent pollution for the next
- options = _.extend( {}, options, { model: history });
+ options = _.extend( {}, options, {
+ model : history,
+ purgeAllowed: Galaxy.config.allow_user_dataset_purge
+ });
var column = new HistoryPanelColumn( options );
if( history.id === this.currentHistoryId ){ column.currentHistory = true; }
this.setUpColumnListeners( column );
diff -r 1fb4f358624fbc34472c63991db8a93d690f37af -r 6ed64b39bcef417a2361e42336c3a46ad10354de static/scripts/packed/mvc/history/history-model.js
--- a/static/scripts/packed/mvc/history/history-model.js
+++ b/static/scripts/packed/mvc/history/history-model.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-contents","mvc/base-mvc","utils/localization"],function(h,i,d){var e=Backbone.Model.extend(i.LoggableMixin).extend(i.mixin(i.SearchableModelMixin,{defaults:{model_class:"History",id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:galaxy_config.root+"api/histories",initialize:function(k,l,j){j=j||{};this.logger=j.logger||null;this.log(this+".initialize:",k,l,j);this.log("creating history contents:",l);this.contents=new h.HistoryContents(l||[],{historyId:this.get("id")});this._setUpListeners();this.updateTimeoutId=null},_setUpListeners:function(){this.on("error",function(k,n,j,m,l){this.errorHandler(k,n,j,m,l)});if(this.contents){this.listenTo(this.contents,"error",function(){this.trigger.apply(this,["error:contents"].concat(jQuery.makeArray(arguments)))})}this.on("change:id",function(k,j){if(this.contents){this.contents.historyId=j}},this)},errorHandler:function(k,n,j,m,l){this.clearUpdateTimeout()},ownedByCurrUser:function(){if(!Galaxy||!Galaxy.currUser){return false}if(Galaxy.currUser.isAnonymous()||Galaxy.currUser.id!==this.get("user_id")){return false}return true},contentsCount:function(){return _.reduce(_.values(this.get("state_details")),function(j,k){return j+k},0)},searchAttributes:["name","annotation","tags"],searchAliases:{title:"name",tag:"tags"},checkForUpdates:function(j){if(this.contents.running().length){this.setUpdateTimeout()}else{this.trigger("ready");if(_.isFunction(j)){j.call(this)}}return this},setUpdateTimeout:function(j){j=j||e.UPDATE_DELAY;var k=this;this.clearUpdateTimeout();this.updateTimeoutId=setTimeout(function(){k.refresh()},j);return this.updateTimeoutId},clearUpdateTimeout:function(){if(this.updateTimeoutId){clearTimeout(this.updateTimeoutId);this.updateTimeoutId=null}},refresh:function(k,j){k=k||[];j=j||{};var l=this;j.data=j.data||{};if(k.length){j.data.details=k.join(",")}var m=this.contents.fetch(j);m.done(function(n){l.checkForUpdates(function(){this.fetch()})});return m},_delete:function(j){if(this.get("deleted")){return jQuery.when()}return this.save({deleted:true},j)},undelete:function(j){if(!this.get("deleted")){return jQuery.when()}return this.save({deleted:false},j)},copy:function(m,k){m=(m!==undefined)?(m):(true);if(!this.id){throw new Error("You must set the history ID before copying it.")}var j={history_id:this.id};if(m){j.current=true}if(k){j.name=k}var l=this,n=jQuery.post(this.urlRoot,j);if(m){return n.then(function(o){var p=new e(o);return p.setAsCurrent().done(function(){l.trigger("copied",l,o)})})}return n.done(function(o){l.trigger("copied",l,o)})},setAsCurrent:function(){var j=this,k=jQuery.getJSON("/history/set_as_current?id="+this.id);k.done(function(){j.trigger("set-as-current",j)});return k},toString:function(){return"History("+this.get("id")+","+this.get("name")+")"}}));e.UPDATE_DELAY=4000;e.getHistoryData=function c(j,v){v=v||{};var r=v.detailIdsFn||[];var m=v.hdcaDetailIds||[];var s=jQuery.Deferred(),p=null;function k(w){if(j==="current"){return jQuery.getJSON(galaxy_config.root+"history/current_history_json")}return jQuery.ajax(galaxy_config.root+"api/histories/"+j)}function o(w){return w&&w.empty}function q(x){if(o(x)){return[]}if(_.isFunction(r)){r=r(x)}if(_.isFunction(m)){m=m(x)}var w={};if(r.length){w.dataset_details=r.join(",")}if(m.length){w.dataset_collection_details=m.join(",")}return jQuery.ajax(galaxy_config.root+"api/histories/"+x.id+"/contents",{data:w})}var t=v.historyFn||k,u=v.contentsFn||q;var n=t(j);n.done(function(w){p=w;s.notify({status:"history data retrieved",historyJSON:p})});n.fail(function(y,w,x){s.reject(y,"loading the history")});var l=n.then(u);l.then(function(w){s.notify({status:"contents data retrieved",historyJSON:p,contentsJSON:w});s.resolve(p,w)});l.fail(function(y,w,x){s.reject(y,"loading the contents",{history:p})});return s};var f=Backbone.Collection.extend(i.LoggableMixin).extend({model:e,urlRoot:(window.galaxy_config?galaxy_config.root:"/")+"api/histories",initialize:function(k,j){j=j||{};this.log("HistoryCollection.initialize",arguments);this.includeDeleted=j.includeDeleted||false;this.setUpListeners()},setUpListeners:function a(){var j=this;this.on("change:deleted",function(k){this.debug("change:deleted",j.includeDeleted,k.get("deleted"));if(!j.includeDeleted&&k.get("deleted")){j.remove(k)}});this.on("copied",function(k,l){this.unshift(new e(l,[]))})},create:function g(m,k,j,l){var o=this,n=jQuery.getJSON(galaxy_config.root+"history/create_new_current");return n.done(function(p){var q=new e(p,[],j||{});o.unshift(q);o.trigger("new-current")})},toString:function b(){return"HistoryCollection("+this.length+")"}});return{History:e,HistoryCollection:f}});
\ No newline at end of file
+define(["mvc/history/history-contents","mvc/base-mvc","utils/localization"],function(h,i,d){var e=Backbone.Model.extend(i.LoggableMixin).extend(i.mixin(i.SearchableModelMixin,{defaults:{model_class:"History",id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:galaxy_config.root+"api/histories",initialize:function(k,l,j){j=j||{};this.logger=j.logger||null;this.log(this+".initialize:",k,l,j);this.log("creating history contents:",l);this.contents=new h.HistoryContents(l||[],{historyId:this.get("id")});this._setUpListeners();this.updateTimeoutId=null},_setUpListeners:function(){this.on("error",function(k,n,j,m,l){this.errorHandler(k,n,j,m,l)});if(this.contents){this.listenTo(this.contents,"error",function(){this.trigger.apply(this,["error:contents"].concat(jQuery.makeArray(arguments)))})}this.on("change:id",function(k,j){if(this.contents){this.contents.historyId=j}},this)},errorHandler:function(k,n,j,m,l){this.clearUpdateTimeout()},ownedByCurrUser:function(){if(!Galaxy||!Galaxy.currUser){return false}if(Galaxy.currUser.isAnonymous()||Galaxy.currUser.id!==this.get("user_id")){return false}return true},contentsCount:function(){return _.reduce(_.values(this.get("state_details")),function(j,k){return j+k},0)},searchAttributes:["name","annotation","tags"],searchAliases:{title:"name",tag:"tags"},checkForUpdates:function(j){if(this.contents.running().length){this.setUpdateTimeout()}else{this.trigger("ready");if(_.isFunction(j)){j.call(this)}}return this},setUpdateTimeout:function(j){j=j||e.UPDATE_DELAY;var k=this;this.clearUpdateTimeout();this.updateTimeoutId=setTimeout(function(){k.refresh()},j);return this.updateTimeoutId},clearUpdateTimeout:function(){if(this.updateTimeoutId){clearTimeout(this.updateTimeoutId);this.updateTimeoutId=null}},refresh:function(k,j){k=k||[];j=j||{};var l=this;j.data=j.data||{};if(k.length){j.data.details=k.join(",")}var m=this.contents.fetch(j);m.done(function(n){l.checkForUpdates(function(){this.fetch()})});return m},_delete:function(j){if(this.get("deleted")){return jQuery.when()}return this.save({deleted:true},j)},purge:function(j){if(this.get("purged")){return jQuery.when()}return this.save({purged:true},j)},undelete:function(j){if(!this.get("deleted")){return jQuery.when()}return this.save({deleted:false},j)},copy:function(m,k){m=(m!==undefined)?(m):(true);if(!this.id){throw new Error("You must set the history ID before copying it.")}var j={history_id:this.id};if(m){j.current=true}if(k){j.name=k}var l=this,n=jQuery.post(this.urlRoot,j);if(m){return n.then(function(o){var p=new e(o);return p.setAsCurrent().done(function(){l.trigger("copied",l,o)})})}return n.done(function(o){l.trigger("copied",l,o)})},setAsCurrent:function(){var j=this,k=jQuery.getJSON("/history/set_as_current?id="+this.id);k.done(function(){j.trigger("set-as-current",j)});return k},toString:function(){return"History("+this.get("id")+","+this.get("name")+")"}}));e.UPDATE_DELAY=4000;e.getHistoryData=function c(j,v){v=v||{};var r=v.detailIdsFn||[];var m=v.hdcaDetailIds||[];var s=jQuery.Deferred(),p=null;function k(w){if(j==="current"){return jQuery.getJSON(galaxy_config.root+"history/current_history_json")}return jQuery.ajax(galaxy_config.root+"api/histories/"+j)}function o(w){return w&&w.empty}function q(x){if(o(x)){return[]}if(_.isFunction(r)){r=r(x)}if(_.isFunction(m)){m=m(x)}var w={};if(r.length){w.dataset_details=r.join(",")}if(m.length){w.dataset_collection_details=m.join(",")}return jQuery.ajax(galaxy_config.root+"api/histories/"+x.id+"/contents",{data:w})}var t=v.historyFn||k,u=v.contentsFn||q;var n=t(j);n.done(function(w){p=w;s.notify({status:"history data retrieved",historyJSON:p})});n.fail(function(y,w,x){s.reject(y,"loading the history")});var l=n.then(u);l.then(function(w){s.notify({status:"contents data retrieved",historyJSON:p,contentsJSON:w});s.resolve(p,w)});l.fail(function(y,w,x){s.reject(y,"loading the contents",{history:p})});return s};var f=Backbone.Collection.extend(i.LoggableMixin).extend({model:e,urlRoot:(window.galaxy_config?galaxy_config.root:"/")+"api/histories",initialize:function(k,j){j=j||{};this.log("HistoryCollection.initialize",arguments);this.includeDeleted=j.includeDeleted||false;this.setUpListeners()},setUpListeners:function a(){var j=this;this.on("change:deleted",function(k){this.debug("change:deleted",j.includeDeleted,k.get("deleted"));if(!j.includeDeleted&&k.get("deleted")){j.remove(k)}});this.on("copied",function(k,l){this.unshift(new e(l,[]))})},create:function g(m,k,j,l){var o=this,n=jQuery.getJSON(galaxy_config.root+"history/create_new_current");return n.done(function(p){var q=new e(p,[],j||{});o.unshift(q);o.trigger("new-current")})},toString:function b(){return"HistoryCollection("+this.length+")"}});return{History:e,HistoryCollection:f}});
\ No newline at end of file
diff -r 1fb4f358624fbc34472c63991db8a93d690f37af -r 6ed64b39bcef417a2361e42336c3a46ad10354de static/scripts/packed/mvc/history/multi-panel.js
--- a/static/scripts/packed/mvc/history/multi-panel.js
+++ b/static/scripts/packed/mvc/history/multi-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","ui/mode-button","ui/search-input"],function(d,l,z,a){function g(I,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return I.copy()}var F=I.get("name"),C="Copy of '"+F+"'";function D(K){if(!K){if(!Galaxy.modal.$("#invalid-title").size()){var J=$("<p/>").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(J)}return false}return K}function G(J){var K=$('<p><span class="fa fa-spinner fa-spin"></span> Copying history...</p>').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(K);I.copy(true,J).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}function H(){var J=Galaxy.modal.$("#copy-modal-title").val();if(!D(J)){return}G(J)}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['<label for="copy-modal-title">',_l("Enter a title for the copied history"),":","</label><br />",'<input id="copy-modal-title" class="form-control" style="width: 100%" value="',C,'" />'].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:H}},E));$("#copy-modal-title").focus().select();$("#copy-modal-title").on("keydown",function(J){if(J.keyCode===13){H()}})}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($('<span class="fa fa-spinner fa-spin"></span><i>loading datasets...</i>')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(E<C){return false}if(F>D){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(C){C=_.extend(C||{},{isCurrentHistory:this.currentHistory});return $(['<div class="panel-controls clear flex-row">',this.controlsLeftTemplate(C),this.controlsRightTemplate(C),"</div>",'<div class="inner flex-row flex-column-container">','<div id="history-',C.id,'" class="history-column history-panel flex-column"></div>',"</div>"].join(""))},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);if(this.currentHistory){this.panel.$list().before(this.panel._renderDropTargetHelp())}return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history":function(){var C=this;this.model._delete().fail(function(F,D,E){alert(_l("Could not delete the history")+":\n"+E)}).done(function(D){C.render()})},"click .undelete-history":function(){var C=this;this.model.undelete().fail(function(F,D,E){alert(_l("Could not undelete the history")+":\n"+E)}).done(function(D){C.render()})},"click .purge-history":function(){if(confirm(_l("This will permanently remove the data. Are you sure?"))){var C=this;this.model.purge().fail(function(F,D,E){alert(_l("Could not purge the history")+":\n"+E)}).done(function(D){C.render()})}},"click .copy-history":"copy"},copy:function s(){g(this.model)},controlsLeftTemplate:_.template(['<div class="pull-left">',"<% if( history.isCurrentHistory ){ %>",'<strong class="current-label">',_l("Current History"),"</strong>","<% } else { %>",'<button class="switch-to btn btn-default">',_l("Switch to"),"</button>","<% } %>","</div>"].join(""),{variable:"history"}),controlsRightTemplate:_.template(['<div class="pull-right">',"<% if( !history.purged ){ %>",'<div class="panel-menu btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">','<span class="caret"></span>',"</button>",'<ul class="dropdown-menu pull-right" role="menu">',"<% if( !history.deleted ){ %>",'<li><a href="javascript:void(0);" class="copy-history">',_l("Copy"),"</a></li>",'<li><a href="javascript:void(0);" class="delete-history">',_l("Delete"),"</a></li>","<% } else /* if is deleted */ { %>",'<li><a href="javascript:void(0);" class="undelete-history">',_l("Undelete"),"</a></li>","<% } %>","</ul>","<% } %>","</div>","</div>"].join(""),{variable:"history"}),toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({className:"multi-panel-history",initialize:function c(C){C=C||{};this.log(this+".init",C);this.$el.addClass(this.className);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this._initSortOrders();this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},_initSortOrders:function(){function C(D,E){return function F(H,G,I){if(H.id===I){return -1}if(G.id===I){return 1}H=D(H);G=D(G);return E.asc?((H===G)?(0):(H>G?1:-1)):((H===G)?(0):(H>G?-1:1))}}this.sortOrders={update:{text:_l("most recent first"),fn:C(function(D){return Date(D.get("update_time"))},{asc:false})},name:{text:_l("name, a to z"),fn:C(function(D){return D.get("name")},{asc:true})},"name-dsc":{text:_l("name, z to a"),fn:C(function(D){return D.get("name")},{asc:false})},size:{text:_l("size, large to small"),fn:C(function(D){return D.get("size")},{asc:false})},"size-dsc":{text:_l("size, small to large"),fn:C(function(D){return D.get("size")},{asc:true})}};return this.sortOrders},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){if(!(C in this.sortOrders)){C="update"}this.order=C;var G=this.currentHistoryId,F=this.sortOrders[C];this.collection.comparator=function E(I,H){return F.fn(I,H,G)};this.$(".current-order").text(F.text);if(this.$(".more-options").is(":visible")){this.$(".open-more-options.btn").popover("show")}this.collection.sort(D);return this.collection},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(D){var E=this,C={HistoryDatasetAssociation:"hda",HistoryDatasetCollectionAssociation:"hdca"};E.listenTo(D,{"in-view":E.queueHdaFetch});E.listenTo(D.panel,{"view:draggable:dragstart":function(I,G,F,H){E._dropData=JSON.parse(I.dataTransfer.getData("text"));E.currentColumnDropTargetOn()},"view:draggable:dragend":function(I,G,F,H){E._dropData=null;E.currentColumnDropTargetOff()},"droptarget:drop":function(H,I,G){var J=E._dropData.filter(function(K){return((_.isObject(K)&&K.id)&&(_.contains(_.keys(C),K.model_class)))});E._dropData=null;var F=new a.NamedAjaxQueue();J.forEach(function(K){var L=C[K.model_class];F.add({name:"copy-"+K.id,fn:function(){return G.model.contents.copy(K.id,L)}})});F.start();F.done(function(K){G.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.mainTemplate(C));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){return this.$(".header .header-info").text(C)},events:{"click .done.btn":"close","click .create-new.btn":"create","click #include-deleted":"_clickToggleDeletedHistories","click .order .set-order":"_chooseOrder","click #toggle-deleted":"_clickToggleDeletedDatasets","click #toggle-hidden":"_clickToggleHiddenDatasets"},close:function(D){var C="/";if(Galaxy&&Galaxy.options&&Galaxy.options.root){C=Galaxy.options.root}else{if(galaxy_config&&galaxy_config.root){C=galaxy_config.root}}window.location=C},_clickToggleDeletedHistories:function(C){return this.toggleDeletedHistories($(C.currentTarget).is(":checked"))},toggleDeletedHistories:function(C){if(C){window.location=Galaxy.options.root+"history/view_multiple?include_deleted_histories=True"}else{window.location=Galaxy.options.root+"history/view_multiple"}},_clickToggleDeletedDatasets:function(C){return this.toggleDeletedDatasets($(C.currentTarget).is(":checked"))},toggleDeletedDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowDeleted(C,false)},E*200)})},_clickToggleHiddenDatasets:function(C){return this.toggleHiddenDatasets($(C.currentTarget).is(":checked"))},toggleHiddenDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowHidden(C,false)},E*200)})},_chooseOrder:function(D){var C=$(D.currentTarget).data("order");this.sortCollection(C)},setUpBehaviors:function(){var D=this;D._moreOptionsPopover();D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_moreOptionsPopover:function(){return this.$(".open-more-options.btn").popover({container:".header",placement:"bottom",html:true,content:$(this.optionsPopoverTemplate(this))})},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTarget=false;C.panel.$(".history-drop-target").remove()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"},mainTemplate:_.template(['<div class="header flex-column-container">','<div class="control-column control-column-left flex-column">','<button class="create-new btn btn-default" tabindex="4">',_l("Create new"),"</button> ",'<div id="search-histories" class="search-control"></div>','<div id="search-datasets" class="search-control"></div>','<a class="open-more-options btn btn-default" tabindex="3">','<span class="fa fa-ellipsis-h"></span>',"</a>","</div>",'<div class="control-column control-column-center flex-column">','<div class="header-info">',"</div>","</div>",'<div class="control-column control-column-right flex-column">','<button class="done btn btn-default" tabindex="1">',_l("Done"),"</button>","</div>","</div>",'<div class="outer-middle flex-row flex-row-container">','<div class="middle flex-column-container flex-row"></div>',"</div>",'<div class="footer flex-column-container">',"</div>"].join(""),{variable:"view"}),optionsPopoverTemplate:_.template(['<div class="more-options">','<div class="order btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',_l("Order histories by")+" ",'<span class="current-order"><%= view.sortOrders[ view.order ].text %></span> ','<span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">',"<% _.each( view.sortOrders, function( order, key ){ %>",'<li><a href="javascript:void(0);" class="set-order" data-order="<%= key %>">',"<%= order.text %>","</a></li>","<% }); %>","</ul>","</div>",'<div class="checkbox"><label><input id="include-deleted" type="checkbox"','<%= view.collection.includeDeleted? " checked" : "" %>>',_l("Include deleted histories"),"</label></div>","<hr />",'<div class="checkbox"><label><input id="toggle-deleted" type="checkbox">',_l("Include deleted datasets"),"</label></div>",'<div class="checkbox"><label><input id="toggle-hidden" type="checkbox">',_l("Include hidden datasets"),"</label></div>","</div>"].join(""),{variable:"view"})});return{MultiPanelColumns:m}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","ui/mode-button","ui/search-input"],function(d,l,z,a){function g(I,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return I.copy()}var F=I.get("name"),C="Copy of '"+F+"'";function D(K){if(!K){if(!Galaxy.modal.$("#invalid-title").size()){var J=$("<p/>").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(J)}return false}return K}function G(J){var K=$('<p><span class="fa fa-spinner fa-spin"></span> Copying history...</p>').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(K);I.copy(true,J).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}function H(){var J=Galaxy.modal.$("#copy-modal-title").val();if(!D(J)){return}G(J)}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['<label for="copy-modal-title">',_l("Enter a title for the copied history"),":","</label><br />",'<input id="copy-modal-title" class="form-control" style="width: 100%" value="',C,'" />'].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:H}},E));$("#copy-modal-title").focus().select();$("#copy-modal-title").on("keydown",function(J){if(J.keyCode===13){H()}})}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.purgeAllowed=!_.isUndefined(C.purgeAllowed)?C.purgeAllowed:false;this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,purgeAllowed:this.purgeAllowed,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($('<span class="fa fa-spinner fa-spin"></span><i>loading datasets...</i>')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(E<C){return false}if(F>D){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(C){C=_.extend(C||{},{isCurrentHistory:this.currentHistory});return $(['<div class="panel-controls clear flex-row">',this.controlsLeftTemplate({history:C,view:this}),this.controlsRightTemplate({history:C,view:this}),"</div>",'<div class="inner flex-row flex-column-container">','<div id="history-',C.id,'" class="history-column history-panel flex-column"></div>',"</div>"].join(""))},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);if(this.currentHistory){this.panel.$list().before(this.panel._renderDropTargetHelp())}return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history":function(){var C=this;this.model._delete().fail(function(F,D,E){alert(_l("Could not delete the history")+":\n"+E)}).done(function(D){C.render()})},"click .undelete-history":function(){var C=this;this.model.undelete().fail(function(F,D,E){alert(_l("Could not undelete the history")+":\n"+E)}).done(function(D){C.render()})},"click .purge-history":function(){if(confirm(_l("This will permanently remove the data. Are you sure?"))){var C=this;this.model.purge().fail(function(F,D,E){alert(_l("Could not purge the history")+":\n"+E)}).done(function(D){C.render()})}},"click .copy-history":"copy"},copy:function s(){g(this.model)},controlsLeftTemplate:_.template(['<div class="pull-left">',"<% if( data.history.isCurrentHistory ){ %>",'<strong class="current-label">',_l("Current History"),"</strong>","<% } else { %>",'<button class="switch-to btn btn-default">',_l("Switch to"),"</button>","<% } %>","</div>"].join(""),{variable:"data"}),controlsRightTemplate:_.template(['<div class="pull-right">',"<% if( !data.history.purged ){ %>",'<div class="panel-menu btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">','<span class="caret"></span>',"</button>",'<ul class="dropdown-menu pull-right" role="menu">',"<% if( !data.history.deleted ){ %>",'<li><a href="javascript:void(0);" class="copy-history">',_l("Copy"),"</a></li>",'<li><a href="javascript:void(0);" class="delete-history">',_l("Delete"),"</a></li>","<% } else /* if is deleted */ { %>",'<li><a href="javascript:void(0);" class="undelete-history">',_l("Undelete"),"</a></li>","<% } %>","<% if( data.view.purgeAllowed ){ %>",'<li><a href="javascript:void(0);" class="purge-history">',_l("Purge"),"</a></li>","<% } %>","</ul>","<% } %>","</div>","</div>"].join(""),{variable:"data"}),toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({className:"multi-panel-history",initialize:function c(C){C=C||{};this.log(this+".init",C);this.$el.addClass(this.className);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this._initSortOrders();this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},_initSortOrders:function(){function C(D,E){return function F(H,G,I){if(H.id===I){return -1}if(G.id===I){return 1}H=D(H);G=D(G);return E.asc?((H===G)?(0):(H>G?1:-1)):((H===G)?(0):(H>G?-1:1))}}this.sortOrders={update:{text:_l("most recent first"),fn:C(function(D){return Date(D.get("update_time"))},{asc:false})},name:{text:_l("name, a to z"),fn:C(function(D){return D.get("name")},{asc:true})},"name-dsc":{text:_l("name, z to a"),fn:C(function(D){return D.get("name")},{asc:false})},size:{text:_l("size, large to small"),fn:C(function(D){return D.get("size")},{asc:false})},"size-dsc":{text:_l("size, small to large"),fn:C(function(D){return D.get("size")},{asc:true})}};return this.sortOrders},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted change:purged":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")||D.get("purged")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){if(!(C in this.sortOrders)){C="update"}this.order=C;var G=this.currentHistoryId,F=this.sortOrders[C];this.collection.comparator=function E(I,H){return F.fn(I,H,G)};this.$(".current-order").text(F.text);if(this.$(".more-options").is(":visible")){this.$(".open-more-options.btn").popover("show")}this.collection.sort(D);return this.collection},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E,purgeAllowed:Galaxy.config.allow_user_dataset_purge});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(D){var E=this,C={HistoryDatasetAssociation:"hda",HistoryDatasetCollectionAssociation:"hdca"};E.listenTo(D,{"in-view":E.queueHdaFetch});E.listenTo(D.panel,{"view:draggable:dragstart":function(I,G,F,H){E._dropData=JSON.parse(I.dataTransfer.getData("text"));E.currentColumnDropTargetOn()},"view:draggable:dragend":function(I,G,F,H){E._dropData=null;E.currentColumnDropTargetOff()},"droptarget:drop":function(H,I,G){var J=E._dropData.filter(function(K){return((_.isObject(K)&&K.id)&&(_.contains(_.keys(C),K.model_class)))});E._dropData=null;var F=new a.NamedAjaxQueue();J.forEach(function(K){var L=C[K.model_class];F.add({name:"copy-"+K.id,fn:function(){return G.model.contents.copy(K.id,L)}})});F.start();F.done(function(K){G.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.mainTemplate(C));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){return this.$(".header .header-info").text(C)},events:{"click .done.btn":"close","click .create-new.btn":"create","click #include-deleted":"_clickToggleDeletedHistories","click .order .set-order":"_chooseOrder","click #toggle-deleted":"_clickToggleDeletedDatasets","click #toggle-hidden":"_clickToggleHiddenDatasets"},close:function(D){var C="/";if(Galaxy&&Galaxy.options&&Galaxy.options.root){C=Galaxy.options.root}else{if(galaxy_config&&galaxy_config.root){C=galaxy_config.root}}window.location=C},_clickToggleDeletedHistories:function(C){return this.toggleDeletedHistories($(C.currentTarget).is(":checked"))},toggleDeletedHistories:function(C){if(C){window.location=Galaxy.options.root+"history/view_multiple?include_deleted_histories=True"}else{window.location=Galaxy.options.root+"history/view_multiple"}},_clickToggleDeletedDatasets:function(C){return this.toggleDeletedDatasets($(C.currentTarget).is(":checked"))},toggleDeletedDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowDeleted(C,false)},E*200)})},_clickToggleHiddenDatasets:function(C){return this.toggleHiddenDatasets($(C.currentTarget).is(":checked"))},toggleHiddenDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowHidden(C,false)},E*200)})},_chooseOrder:function(D){var C=$(D.currentTarget).data("order");this.sortCollection(C)},setUpBehaviors:function(){var D=this;D._moreOptionsPopover();D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_moreOptionsPopover:function(){return this.$(".open-more-options.btn").popover({container:".header",placement:"bottom",html:true,content:$(this.optionsPopoverTemplate(this))})},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTarget=false;C.panel.$(".history-drop-target").remove()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"},mainTemplate:_.template(['<div class="header flex-column-container">','<div class="control-column control-column-left flex-column">','<button class="create-new btn btn-default" tabindex="4">',_l("Create new"),"</button> ",'<div id="search-histories" class="search-control"></div>','<div id="search-datasets" class="search-control"></div>','<a class="open-more-options btn btn-default" tabindex="3">','<span class="fa fa-ellipsis-h"></span>',"</a>","</div>",'<div class="control-column control-column-center flex-column">','<div class="header-info">',"</div>","</div>",'<div class="control-column control-column-right flex-column">','<button class="done btn btn-default" tabindex="1">',_l("Done"),"</button>","</div>","</div>",'<div class="outer-middle flex-row flex-row-container">','<div class="middle flex-column-container flex-row"></div>',"</div>",'<div class="footer flex-column-container">',"</div>"].join(""),{variable:"view"}),optionsPopoverTemplate:_.template(['<div class="more-options">','<div class="order btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',_l("Order histories by")+" ",'<span class="current-order"><%= view.sortOrders[ view.order ].text %></span> ','<span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">',"<% _.each( view.sortOrders, function( order, key ){ %>",'<li><a href="javascript:void(0);" class="set-order" data-order="<%= key %>">',"<%= order.text %>","</a></li>","<% }); %>","</ul>","</div>",'<div class="checkbox"><label><input id="include-deleted" type="checkbox"','<%= view.collection.includeDeleted? " checked" : "" %>>',_l("Include deleted histories"),"</label></div>","<hr />",'<div class="checkbox"><label><input id="toggle-deleted" type="checkbox">',_l("Include deleted datasets"),"</label></div>",'<div class="checkbox"><label><input id="toggle-hidden" type="checkbox">',_l("Include hidden datasets"),"</label></div>","</div>"].join(""),{variable:"view"})});return{MultiPanelColumns:m}});
\ 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
16 Feb '15
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: c67cfe08e93b2d3eb14ef227c47ada5e6f3ed7cb
https://github.com/galaxyproject/usegalaxy-playbook/commit/c67cfe08e93b2d3e…
Author: martenson <cech.marten(a)gmail.com>
Date: 2015-02-16 (Mon, 16 Feb 2015)
Changed paths:
M files/galaxy/test.galaxyproject.org/var/integrated_tool_panel.xml
M stage/group_vars/all.yml
Log Message:
-----------
update test and mutable configs
1
0
commit/galaxy-central: guerler: Parameters: Fix late validation criteria
by commits-noreply@bitbucket.org 16 Feb '15
by commits-noreply@bitbucket.org 16 Feb '15
16 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/1fb4f358624f/
Changeset: 1fb4f358624f
User: guerler
Date: 2015-02-16 22:26:09+00:00
Summary: Parameters: Fix late validation criteria
Affected #: 1 file
diff -r 0155ac3c87edc23a2edefa54aca7a7d694fb9f33 -r 1fb4f358624fbc34472c63991db8a93d690f37af lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -965,7 +965,7 @@
# Old style dynamic options, no dependency information so there isn't
# a lot we can do: if we're dealing with workflows, have to assume
# late validation no matter what.
- if (self.dynamic_options is not None or self.is_dynamic is not None) and ( trans is None or trans.workflow_building_mode ):
+ if self.dynamic_options is not None and ( trans is None or trans.workflow_building_mode ):
return True
# If we got this far, we can actually look at the dependencies
# to see if their values will not be available until runtime.
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: carlfeberhard: API, configuration: use getattr instead of config.get since get is limited
by commits-noreply@bitbucket.org 16 Feb '15
by commits-noreply@bitbucket.org 16 Feb '15
16 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/0155ac3c87ed/
Changeset: 0155ac3c87ed
User: carlfeberhard
Date: 2015-02-16 21:40:24+00:00
Summary: API, configuration: use getattr instead of config.get since get is limited
Affected #: 1 file
diff -r e001809f8d6e28607162e558ece72f5590fad6ab -r 0155ac3c87edc23a2edefa54aca7a7d694fb9f33 lib/galaxy/webapps/galaxy/api/configuration.py
--- a/lib/galaxy/webapps/galaxy/api/configuration.py
+++ b/lib/galaxy/webapps/galaxy/api/configuration.py
@@ -63,11 +63,11 @@
self.add_view( 'all', self.serializers.keys() )
def default_serializer( self, trans, config, key ):
- return config.get( key, None )
+ return getattr( config, key, None )
def add_serializers( self ):
def _defaults_to( default ):
- return lambda t, i, k: i.get( k, default )
+ return lambda t, i, k: getattr( i, k, default )
self.serializers = {
#TODO: this is available from user data, remove
@@ -90,7 +90,6 @@
'biostar_url_redirect' : lambda *a: self.url_for( controller='biostar', action='biostar_redirect',
qualified=True ),
- 'allow_user_creation' : _defaults_to( False ),
'use_remote_user' : _defaults_to( None ),
'remote_user_logout_href' : _defaults_to( '' ),
'enable_cloud_launch' : _defaults_to( False ),
@@ -111,7 +110,7 @@
def add_serializers( self ):
super( AdminConfigSerializer, self ).add_serializers()
def _defaults_to( default ):
- return lambda t, i, k: i.get( k, default )
+ return lambda t, i, k: getattr( i, k, default )
self.serializers.update({
#TODO: this is available from user data, remove
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