1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/0aa4dd8af7cf/ Changeset: 0aa4dd8af7cf User: natefoo Date: 2015-04-22 19:35:19+00:00 Summary: Merge stable to default Affected #: 61 files diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca .hgtags --- a/.hgtags +++ b/.hgtags @@ -25,4 +25,5 @@ 5cdf5dc395f16f47e88a5567775dcd21b4906f08 latest_2015.01.13 738f4ad0eb62d5e4bcf0d22a2722ee6c570382b9 v15.03 9f40ff3e3fe1f7fed7e055d4269fe83199cf5ed2 v15.03.1 -9f40ff3e3fe1f7fed7e055d4269fe83199cf5ed2 latest_15.03 +bfd4635011e39aa210b2b1498dd65831dd2a365e v15.03.2 +bfd4635011e39aa210b2b1498dd65831dd2a365e latest_15.03 diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca 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 @@ -257,7 +257,7 @@ setAsCurrent : function(){ var history = this, - xhr = jQuery.getJSON( '/history/set_as_current?id=' + this.id ); + xhr = jQuery.getJSON( galaxy_config.root + 'history/set_as_current?id=' + this.id ); xhr.done( function(){ history.trigger( 'set-as-current', history ); @@ -361,7 +361,7 @@ var HistoryCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).extend( /** @lends HistoryCollection.prototype */{ model : History, - + /** logger used to record this.log messages, commonly set to console */ //logger : console, diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca client/galaxy/scripts/mvc/library/library-dataset-view.js --- a/client/galaxy/scripts/mvc/library/library-dataset-view.js +++ b/client/galaxy/scripts/mvc/library/library-dataset-view.js @@ -116,7 +116,7 @@ }, downloadDataset: function(){ - var url = '/api/libraries/datasets/download/uncompressed'; + var url = ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/download/uncompressed'; var data = {'ld_ids' : this.id}; this.processDownload(url, data); }, @@ -232,7 +232,7 @@ var self = this; if (this.options.fetched_permissions === undefined){ - $.get( "/api/libraries/datasets/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { + $.get( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { self.prepareSelectBoxes({fetched_permissions:fetched_permissions, is_admin:is_admin}); }).fail(function(){ mod_toastr.error('An error occurred while attempting to fetch dataset permissions.'); @@ -273,7 +273,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#access_perm'), ajax: { - url: "/api/libraries/datasets/" + self.id + "/permissions?scope=available", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=available", dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -320,7 +320,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#modify_perm'), ajax: { - url: "/api/libraries/datasets/" + self.id + "/permissions?scope=available", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=available", dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -367,7 +367,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#manage_perm'), ajax: { - url: "/api/libraries/datasets/" + self.id + "/permissions?scope=available", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=available", dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -413,7 +413,7 @@ self.manageSelectObject = new mod_select.View(manage_select_options); } else { // Non-admins have select with pre-loaded options var template = self.templateAccessSelect(); - $.get( "/api/libraries/datasets/" + self.id + "/permissions?scope=available", function( data ) { + $.get( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=available", function( data ) { $('.access_perm').html(template({options:data.roles})); self.accessSelectObject = $('#access_select').select2(); }).fail(function() { @@ -436,7 +436,7 @@ makeDatasetPrivate: function(){ var self = this; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=make_private").done(function(fetched_permissions) { + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=make_private").done(function(fetched_permissions) { self.model.set({is_unrestricted:false}); self.showPermissions({fetched_permissions:fetched_permissions}) mod_toastr.success('The dataset is now private to you.'); @@ -447,7 +447,7 @@ removeDatasetRestrictions: function(){ var self = this; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=remove_restrictions") + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=remove_restrictions") .done(function(fetched_permissions) { self.model.set({is_unrestricted:true}); self.showPermissions({fetched_permissions:fetched_permissions}) @@ -478,7 +478,7 @@ modify_ids.push(modify_roles[i].id); }; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=set_permissions", { 'access_ids[]': access_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=set_permissions", { 'access_ids[]': access_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) .done(function(fetched_permissions){ //fetch dataset again self.showPermissions({fetched_permissions:fetched_permissions}) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca client/galaxy/scripts/mvc/library/library-folder-view.js --- a/client/galaxy/scripts/mvc/library/library-folder-view.js +++ b/client/galaxy/scripts/mvc/library/library-folder-view.js @@ -81,7 +81,7 @@ var self = this; if (this.options.fetched_permissions === undefined){ - $.get( "/api/folders/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { + $.get( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/folders/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { self.prepareSelectBoxes({fetched_permissions:fetched_permissions}); }).fail(function(){ mod_toastr.error('An error occurred while attempting to fetch folder permissions.'); @@ -125,7 +125,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#' + id), ajax: { - url: "/api/folders/" + self.id + "/permissions?scope=available", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/folders/" + self.id + "/permissions?scope=available", dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -195,7 +195,7 @@ var manage_ids = this._extractIds(this.manageSelectObject.$el.select2('data')); var modify_ids = this._extractIds(this.modifySelectObject.$el.select2('data')); - $.post("/api/folders/" + self.id + "/permissions?action=set_permissions", { 'add_ids[]': add_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/folders/" + self.id + "/permissions?action=set_permissions", { 'add_ids[]': add_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) .done(function(fetched_permissions){ //fetch dataset again self.showPermissions({fetched_permissions:fetched_permissions}) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca client/galaxy/scripts/mvc/library/library-foldertoolbar-view.js --- a/client/galaxy/scripts/mvc/library/library-foldertoolbar-view.js +++ b/client/galaxy/scripts/mvc/library/library-foldertoolbar-view.js @@ -294,7 +294,7 @@ dataset_ids.push( this.parentElement.parentElement.id ); } } ); - var url = '/api/libraries/datasets/download/' + format; + var url = ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/download/' + format; var data = { 'ld_ids' : dataset_ids }; this.processDownload( url, data, 'get' ); }, @@ -386,7 +386,7 @@ fetchExtAndGenomes: function(){ var that = this; mod_utils.get({ - url : galaxy_config.root + "api/datatypes?extension_only=False", + url : ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/datatypes?extension_only=False", success : function( datatypes ) { for (key in datatypes) { that.list_extensions.push({ @@ -403,7 +403,7 @@ } }); mod_utils.get({ - url: galaxy_config.root + "api/genomes", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/genomes", success: function( genomes ) { for ( key in genomes ) { that.list_genomes.push({ @@ -689,7 +689,7 @@ for ( var i = history_dataset_ids.length - 1; i >= 0; i-- ) { history_dataset_id = history_dataset_ids[i]; var folder_item = new mod_library_model.Item(); - folder_item.url = '/api/folders/' + this.options.id + '/contents'; + folder_item.url = ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders/' + this.options.id + '/contents'; folder_item.set( { 'from_hda_id':history_dataset_id } ); hdas_to_add.push( folder_item ); } @@ -749,7 +749,7 @@ } return true; } - var promise = $.when( $.post( '/api/libraries/datasets?encoded_folder_id=' + that.id + + var promise = $.when( $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets?encoded_folder_id=' + that.id + '&source=' + options.source + '&path=' + popped_item + '&file_type=' + options.file_type + @@ -788,7 +788,7 @@ } return true; } - var promise = $.when( $.post( '/api/libraries/datasets?encoded_folder_id=' + that.id + + var promise = $.when( $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets?encoded_folder_id=' + that.id + '&source=' + options.source + '&path=' + popped_item + '&preserve_dirs=' + options.preserve_dirs + diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca client/galaxy/scripts/mvc/library/library-library-view.js --- a/client/galaxy/scripts/mvc/library/library-library-view.js +++ b/client/galaxy/scripts/mvc/library/library-library-view.js @@ -87,7 +87,7 @@ var self = this; if (this.options.fetched_permissions === undefined){ - $.get( "/api/libraries/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { + $.get( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { self.prepareSelectBoxes({fetched_permissions:fetched_permissions}); }).fail(function(){ mod_toastr.error('An error occurred while attempting to fetch library permissions.'); @@ -134,7 +134,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#' + id), ajax: { - url: "/api/libraries/" + self.id + "/permissions?scope=available&is_library_access=" + is_library_access, + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/" + self.id + "/permissions?scope=available&is_library_access=" + is_library_access, dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -193,7 +193,7 @@ makeDatasetPrivate: function(){ var self = this; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=make_private").done(function(fetched_permissions) { + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=make_private").done(function(fetched_permissions) { self.model.set({is_unrestricted:false}); self.showPermissions({fetched_permissions:fetched_permissions}) mod_toastr.success('The dataset is now private to you.'); @@ -204,7 +204,7 @@ removeDatasetRestrictions: function(){ var self = this; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=remove_restrictions") + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=remove_restrictions") .done(function(fetched_permissions) { self.model.set({is_unrestricted:true}); self.showPermissions({fetched_permissions:fetched_permissions}) @@ -230,7 +230,7 @@ var manage_ids = this._extractIds(this.manageSelectObject.$el.select2('data')); var modify_ids = this._extractIds(this.modifySelectObject.$el.select2('data')); - $.post("/api/libraries/" + self.id + "/permissions?action=set_permissions", { 'access_ids[]': access_ids, 'add_ids[]': add_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/" + self.id + "/permissions?action=set_permissions", { 'access_ids[]': access_ids, 'add_ids[]': add_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) .done(function(fetched_permissions){ //fetch dataset again self.showPermissions({fetched_permissions:fetched_permissions}) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca client/galaxy/scripts/mvc/library/library-model.js --- a/client/galaxy/scripts/mvc/library/library-model.js +++ b/client/galaxy/scripts/mvc/library/library-model.js @@ -4,7 +4,7 @@ // LIBRARY RELATED MODELS var Library = Backbone.Model.extend({ - urlRoot: '/api/libraries/', + urlRoot: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/', /** based on show_deleted would this lib show in the list of lib's? * @param {Boolean} show_deleted are we including deleted libraries? @@ -19,7 +19,7 @@ }); var Libraries = Backbone.Collection.extend({ - url: '/api/libraries', + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries', model: Library, @@ -84,15 +84,15 @@ // FOLDER RELATED MODELS var Item = Backbone.Model.extend({ - urlRoot : '/api/libraries/datasets/' + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/' }); var Ldda = Backbone.Model.extend({ - urlRoot : '/api/libraries/datasets/' + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/' }); var FolderAsModel = Backbone.Model.extend({ - urlRoot: '/api/folders' + urlRoot: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders' }); var Folder = Backbone.Collection.extend({ @@ -152,7 +152,7 @@ var FolderContainer = Backbone.Model.extend({ defaults : { folder : new Folder(), - urlRoot : "/api/folders/", + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders/', id : "unknown" }, parse : function(obj) { @@ -169,11 +169,11 @@ // TODO UNITE var HistoryItem = Backbone.Model.extend({ - urlRoot : '/api/histories/' + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/histories/' }); var HistoryContents = Backbone.Collection.extend({ - urlRoot : '/api/histories/', + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/histories/', initialize: function(options){ this.id = options.id; }, @@ -184,11 +184,11 @@ }); var GalaxyHistory = Backbone.Model.extend({ - urlRoot : '/api/histories/' + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/histories/' }); var GalaxyHistories = Backbone.Collection.extend({ - url : '/api/histories', + url : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/histories', model : GalaxyHistory }); @@ -199,7 +199,7 @@ */ var Jstree = Backbone.Model.extend({ - urlRoot: '/api/remote_files' + urlRoot: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/remote_files' }); return { diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca client/galaxy/scripts/mvc/tools/tools-parameters.js --- a/client/galaxy/scripts/mvc/tools/tools-parameters.js +++ b/client/galaxy/scripts/mvc/tools/tools-parameters.js @@ -145,6 +145,7 @@ data : options, error_text : input_def.error_text || 'No options available', multiple : input_def.multiple, + optional : input_def.optional, searchable : input_def.searchable, onchange : function() { self.app.trigger('refresh'); diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca client/galaxy/scripts/viz/circster.js --- a/client/galaxy/scripts/viz/circster.js +++ b/client/galaxy/scripts/viz/circster.js @@ -1,16 +1,20 @@ // load required libraries -require( -[ +require([ 'utils/utils', - 'mvc/ui/icon-button', - 'libs/farbtastic', -], function(mod_utils, mod_icon_btn) +], function(mod_utils) { // load css mod_utils.cssLoadFile("static/style/circster.css"); }); -define(["libs/underscore", "libs/d3", "viz/visualization", "utils/config"], function(_, d3, visualization, config) { +define([ + "libs/underscore", + "libs/d3", + "viz/visualization", + "utils/config", + 'mvc/ui/icon-button', + 'libs/farbtastic' +], function(_, d3, visualization, config, mod_icon_btn) { /** * Utility class for working with SVG. @@ -71,7 +75,7 @@ else { tick_coords = [1, 0, 4, 0]; text_coords = [0, 4, ".35em", ""]; - + } ticks.append("line") @@ -80,7 +84,7 @@ .attr("x2", tick_coords[2]) .attr("y1", tick_coords[3]) .style("stroke", "#000"); - + return ticks.append("text") .attr("x", text_coords[0]) .attr("y", text_coords[1]) @@ -98,11 +102,11 @@ // Use default of 2 sig. digits. if (sigDigits === undefined) sigDigits = 2; - + // Verify input number if (num === null) return null; - + // Calculate return value var rval = null; if (Math.abs(num) < 1) { @@ -141,7 +145,7 @@ */ var CircsterView = Backbone.View.extend({ className: 'circster', - + initialize: function(options) { this.genome = options.genome; this.label_arc_height = 50; @@ -188,7 +192,7 @@ track_gap = this.model.get('config').get_value('track_gap'), // Subtract 20 to make sure chrom labels are on screen. min_dimension = Math.min(this.$el.width(), this.$el.height()) - 20, - // Compute radius start based on model, will be centered + // Compute radius start based on model, will be centered // and fit entirely inside element by default. radius_start = min_dimension / 2 - circular_tracks.length * (dataset_arc_height + track_gap) + @@ -198,14 +202,14 @@ // Compute range of track starting radii. tracks_start_radii = d3.range(radius_start, min_dimension / 2, dataset_arc_height + track_gap); - + // Map from track start to bounds. var self = this; return _.map(tracks_start_radii, function(radius) { return [radius, radius + dataset_arc_height]; }); }, - + /** * Renders circular tracks, chord tracks, and label tracks. */ @@ -254,7 +258,7 @@ })) .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .append('svg:g').attr('class', 'tracks'); - + // -- Render circular tracks. -- // Create a view for each track in the visualization and render. @@ -266,12 +270,12 @@ genome: self.genome, total_gap: total_gap }); - + view.render(); - + return view; }); - + // -- Render chords tracks. -- this.chords_views = chords_tracks.map(function(track) { @@ -289,10 +293,10 @@ }); // -- Render label track. -- - + // Track bounds are: // (a) outer radius of last circular track; - // (b) + // (b) var outermost_radius = this.circular_views[this.circular_views.length-1].radius_bounds[1], track_bounds = [ outermost_radius, @@ -305,7 +309,7 @@ genome: self.genome, total_gap: total_gap }); - + this.label_track_view.render(); }, @@ -356,7 +360,7 @@ // Update label track. /* - FIXME: should never have to update label track because vis always expands to fit area + FIXME: should never have to update label track because vis always expands to fit area within label track. var track_bounds = new_track_bounds[ new_track_bounds.length-1 ]; track_bounds[1] = track_bounds[0]; @@ -373,7 +377,7 @@ var track_view = this.circular_views[options.index]; this.circular_views.splice(options.index, 1); track_view.$el.remove(); - + // Recompute and update track bounds. var new_track_bounds = this.get_tracks_bounds(); _.each(this.circular_views, function(track_view, i) { @@ -392,7 +396,7 @@ _.each(this.chords_views, function(track_view) { track_view.update_radius_bounds(new_track_bounds[0]); }); - + } }); @@ -455,7 +459,7 @@ // Append titles to paths. chroms_paths.append("title").text(function(d) { return d.data.chrom; }); - + // -- Render track data and, when track data is rendered, apply preferences and update chrom_elts fill. -- var self = this, @@ -490,7 +494,7 @@ var new_d = d3.svg.arc() .innerRadius(this.radius_bounds[0]) .outerRadius(this.radius_bounds[1]); - + this.parent_elt.selectAll('g>path.chrom-background').transition().duration(1000).attr('d', new_d); this._transition_chrom_data(); @@ -511,7 +515,7 @@ } // -- Scale increased, so render visible data with more detail. -- - + var self = this, utils = new SVGUtils(); @@ -539,7 +543,7 @@ $.when(data_deferred).then(function(data) { // Remove current data path. path_elt.remove(); - + // Update data bounds with new data. self._update_data_bounds(); @@ -598,12 +602,12 @@ _transition_labels: function() {}, /** - * Update data bounds. If there are new_bounds, use them; otherwise use + * Update data bounds. If there are new_bounds, use them; otherwise use * default data bounds. */ _update_data_bounds: function(new_bounds) { var old_bounds = this.data_bounds; - this.data_bounds = new_bounds || + this.data_bounds = new_bounds || this.get_data_bounds(this.track.get('data_manager').get_genome_wide_data(this.genome)); this._transition_chrom_data(); }, @@ -624,7 +628,7 @@ // Set min, max value in config so that they can be adjusted. Make this silent // because these attributes are watched for changes and the viz is updated - // accordingly (set up in initialize). Because we are setting up, we don't want + // accordingly (set up in initialize). Because we are setting up, we don't want // the watch to trigger events here. track.get('config').set_value('min_value', self.data_bounds[0], {silent: true}); track.get('config').set_value('max_value', self.data_bounds[1], {silent: true}); @@ -660,7 +664,7 @@ _get_path_function: function(chrom_arc, chrom_data) {}, /** - * Returns arc layouts for genome's chromosomes/contigs. Arcs are arranged in a circle + * Returns arc layouts for genome's chromosomes/contigs. Arcs are arranged in a circle * separated by gaps. */ _chroms_layout: function() { @@ -700,14 +704,14 @@ * Render labels. */ _render_data: function(svg) { - // -- Add chromosome label where it will fit; an alternative labeling mechanism + // -- Add chromosome label where it will fit; an alternative labeling mechanism // would be nice for small chromosomes. -- var self = this, chrom_arcs = svg.selectAll('g'); chrom_arcs.selectAll('path') .attr('id', function(d) { return 'label-' + d.data.chrom; }); - + chrom_arcs.append("svg:text") .filter(function(d) { return d.endAngle - d.startAngle > self.min_arc_len; @@ -857,12 +861,12 @@ return "rotate(90)"; }; - // FIXME: + // FIXME: // (1) using min_max class below is needed for _update_min_max, which could be improved. // (2) showing config on tick click should be replaced by proper track config icon. // Draw min, max on first chrom only. - var ticks = this.drawTicks(this.parent_elt, [ this.chroms_layout[0] ], + var ticks = this.drawTicks(this.parent_elt, [ this.chroms_layout[0] ], this._data_bounds_ticks_fn(), textTransform, true) .classed('min_max', true); @@ -872,7 +876,7 @@ var view = new config.ConfigSettingCollectionView({ collection: self.track.get('config') }); - view.render_in_modal('Configure Track'); + view.render_in_modal('Configure Track'); }); }); @@ -951,7 +955,7 @@ var CircsterBigWigTrackView = CircsterQuantitativeTrackView.extend({ get_data_bounds: function(data) { - // Set max across dataset by extracting all values, flattening them into a + // Set max across dataset by extracting all values, flattening them into a // single array, and getting third quartile. var values = _.flatten( _.map(data, function(d) { if (d) { @@ -965,8 +969,8 @@ return 0; } }) ); - - // For max, use 98% quantile in attempt to avoid very large values. However, this max may be 0 + + // For max, use 98% quantile in attempt to avoid very large values. However, this max may be 0 // for sparsely populated data, so use max in that case. return [ _.min(values), this._quantile(values, 0.98) || _.max(values) ]; } @@ -1068,13 +1072,13 @@ genome : genome, model : vis }); - + // Render vizualization viz_view.render(); - + // setup title $('#center .unified-panel-header-inner').append(galaxy_config.app.viz_config.title + " " + galaxy_config.app.viz_config.dbkey); - + // setup menu var menu = mod_icon_btn.create_icon_buttons_menu([ { @@ -1100,7 +1104,7 @@ { // show saving dialog box Galaxy.modal.show({title: "Saving...", body: "progress" }); - + // send to server $.ajax({ url: galaxy_config.root + "visualization/save", @@ -1132,11 +1136,11 @@ window.location = galaxy_config.root + "visualization/list"; } }], { tooltip_config: { placement: 'bottom' } }); - + // add menu menu.$el.attr("style", "float: right"); $("#center .unified-panel-header-inner").append(menu.$el); - + // manual tooltip config because default gravity is S and cannot be changed $(".menu-button").tooltip( { placement: 'bottom' } ); } diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca config/galaxy.ini.sample --- a/config/galaxy.ini.sample +++ b/config/galaxy.ini.sample @@ -580,6 +580,13 @@ # requests. #nginx_upload_path = False +# Galaxy can also use nginx_upload_module to receive files staged out upon job +# completion by remote job runners (i.e. Pulsar) that initiate staging +# operations on the remote end. See the Galaxy nginx documentation for the +# corresponding nginx configuration. +#nginx_upload_job_files_store = False +#nginx_upload_job_files_path = False + # Have Galaxy manage dynamic proxy component for routing requests to other # services based on Galaxy's session cookie. It will attempt to do this by # default though you do need to install node+npm and do an npm install from @@ -960,6 +967,17 @@ # always, onsuccess, never #cleanup_job = always +# For sites where all users in Galaxy match users on the system on which Galaxy +# runs, the DRMAA job runner can be configured to submit jobs to the DRM as the +# actual user instead of as the user running the Galaxy server process. For +# details on these options, see the documentation at: +# +# http://galaxyproject.org/wiki/Admin/Config/Performance/Cluster +# +#drmaa_external_runjob_script = scripts/drmaa_external_runner.py +#drmaa_external_killjob_script = scripts/drmaa_external_killer.py +#external_chown_script = scripts/external_chown_script.py + # File to source to set up the environment when running jobs. By default, the # environment in which the Galaxy server starts is used when running jobs # locally, and the environment set up per the DRM's submission method and diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca config/job_conf.xml.sample_advanced --- a/config/job_conf.xml.sample_advanced +++ b/config/job_conf.xml.sample_advanced @@ -252,10 +252,7 @@ --></destination><destination id="real_user_cluster" runner="drmaa"> - <!-- TODO: The real user options should maybe not be considered runner params. --> - <param id="galaxy_external_runjob_script">scripts/drmaa_external_runner.py</param> - <param id="galaxy_external_killjob_script">scripts/drmaa_external_killer.py</param> - <param id="galaxy_external_chown_script">scripts/external_chown_script.py</param> + <!-- Make sure to setup 3 real user parameters in galaxy.ini. --></destination><destination id="dynamic" runner="dynamic"><!-- A destination that represents a method in the dynamic runner. --> diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/config.py --- a/lib/galaxy/config.py +++ b/lib/galaxy/config.py @@ -293,6 +293,8 @@ self.nginx_x_archive_files_base = kwargs.get( 'nginx_x_archive_files_base', False ) self.nginx_upload_store = kwargs.get( 'nginx_upload_store', False ) self.nginx_upload_path = kwargs.get( 'nginx_upload_path', False ) + self.nginx_upload_job_files_store = kwargs.get( 'nginx_upload_job_files_store', False ) + self.nginx_upload_job_files_path = kwargs.get( 'nginx_upload_job_files_path', False ) if self.nginx_upload_store: self.nginx_upload_store = os.path.abspath( self.nginx_upload_store ) self.object_store = kwargs.get( 'object_store', 'disk' ) @@ -466,7 +468,7 @@ datatypes_config_file=[ 'config/datatypes_conf.xml', 'datatypes_conf.xml', 'config/datatypes_conf.xml.sample' ], external_service_type_config_file=[ 'config/external_service_types_conf.xml', 'external_service_types_conf.xml', 'config/external_service_types_conf.xml.sample' ], job_config_file=[ 'config/job_conf.xml', 'job_conf.xml' ], - job_metrics_config_file=[ 'config/job_metrics_conf.xml', 'job_metrics_conf.xml' ], + job_metrics_config_file=[ 'config/job_metrics_conf.xml', 'job_metrics_conf.xml','config/job_metrics_conf.xml.sample' ], dependency_resolvers_config_file=[ 'config/dependency_resolvers_conf.xml', 'dependency_resolvers_conf.xml' ], job_resource_params_file=[ 'config/job_resource_params_conf.xml', 'job_resource_params_conf.xml' ], migrated_tools_config=[ 'migrated_tools_conf.xml', 'config/migrated_tools_conf.xml' ], diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -962,12 +962,11 @@ job.set_state( job.states.PAUSED ) self.sa_session.add( job ) - def mark_as_resubmitted( self ): + def mark_as_resubmitted( self, info=None ): job = self.get_job() self.sa_session.refresh( job ) - for dataset in [ dataset_assoc.dataset for dataset_assoc in job.output_datasets + job.output_library_datasets ]: - dataset._state = model.Dataset.states.RESUBMITTED - self.sa_session.add( dataset ) + if info is not None: + job.info = info job.set_state( model.Job.states.RESUBMITTED ) self.sa_session.add( job ) self.sa_session.flush() @@ -1251,6 +1250,16 @@ if job.user: job.user.total_disk_usage += bytes + # Emperically, we need to update job.user and + # job.workflow_invocation_step.workflow_invocation in separate + # transactions. Best guess as to why is that the workflow_invocation + # may or may not exist when the job is first loaded by the handler - + # and depending on whether it is or not sqlalchemy orders the updates + # differently and deadlocks can occur (one thread updates user and + # waits on invocation and the other updates invocation and waits on + # user). + self.sa_session.flush() + # fix permissions for path in [ dp.real_path for dp in self.get_mutable_output_fnames() ]: util.umask_fix_perms( path, self.app.config.umask, 0666, self.app.config.gid ) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/jobs/runners/__init__.py --- a/lib/galaxy/jobs/runners/__init__.py +++ b/lib/galaxy/jobs/runners/__init__.py @@ -341,8 +341,8 @@ except: log.exception('Caught exception in runner state handler:') - def mark_as_resubmitted( self, job_state ): - job_state.job_wrapper.mark_as_resubmitted() + def mark_as_resubmitted( self, job_state, info=None ): + job_state.job_wrapper.mark_as_resubmitted( info=info ) if not self.app.config.track_jobs_in_database: job_state.job_wrapper.change_state( model.Job.states.QUEUED ) self.app.job_manager.job_handler.dispatcher.put( job_state.job_wrapper ) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/jobs/runners/pulsar.py --- a/lib/galaxy/jobs/runners/pulsar.py +++ b/lib/galaxy/jobs/runners/pulsar.py @@ -342,7 +342,12 @@ encoded_job_id = self.app.security.encode_id(job_id) job_key = self.app.security.encode_id( job_id, kind="jobs_files" ) - files_endpoint = "%s/api/jobs/%s/files?job_key=%s" % ( + endpoint_base = "%s/api/jobs/%s?job_key=%s" + if self.app.config.nginx_upload_job_files_path: + endpoint_base = "%s" + \ + self.app.config.nginx_upload_job_files_path + \ + "?job_id=%s&job_key=%s" + files_endpoint = endpoint_base % ( self.galaxy_url, encoded_job_id, job_key diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/jobs/runners/state_handlers/resubmit.py --- a/lib/galaxy/jobs/runners/state_handlers/resubmit.py +++ b/lib/galaxy/jobs/runners/state_handlers/resubmit.py @@ -1,4 +1,5 @@ import logging + from galaxy import model @@ -13,31 +14,45 @@ def failure(app, job_runner, job_state): - if getattr( job_state, 'runner_state', None ) and job_state.runner_state in ( job_state.runner_states.WALLTIME_REACHED, job_state.runner_states.MEMORY_LIMIT_REACHED ): - # Intercept jobs that hit the walltime and have a walltime or nonspecific resubmit destination configured + if (getattr(job_state, 'runner_state', None) + and job_state.runner_state in + (job_state.runner_states.WALLTIME_REACHED, + job_state.runner_states.MEMORY_LIMIT_REACHED)): + # Intercept jobs that hit the walltime and have a walltime or + # nonspecific resubmit destination configured for resubmit in job_state.job_destination.get('resubmit'): - if resubmit.get('condition', None) and resubmit['condition'] != job_state.runner_state: - continue # There is a resubmit defined for the destination but its condition is not for walltime_reached - log.info("(%s/%s) Job will be resubmitted to '%s' because %s at the '%s' destination", - job_state.job_wrapper.job_id, - job_state.job_id, - resubmit['destination'], - MESSAGES[job_state.runner_state], - job_state.job_wrapper.job_destination.id ) + if (resubmit.get('condition', None) and resubmit['condition'] != + job_state.runner_state): + # There is a resubmit defined for the destination but + # its condition is not for walltime_reached + continue + log.info("(%s/%s) Job will be resubmitted to '%s' because %s at " + "the '%s' destination", + job_state.job_wrapper.job_id, + job_state.job_id, + resubmit['destination'], + MESSAGES[job_state.runner_state], + job_state.job_wrapper.job_destination.id ) # fetch JobDestination for the id or tag - new_destination = app.job_config.get_destination(resubmit['destination']) + new_destination = app.job_config.get_destination( + resubmit['destination']) # Resolve dynamic if necessary - new_destination = job_state.job_wrapper.job_runner_mapper.cache_job_destination( new_destination ) + new_destination = (job_state.job_wrapper.job_runner_mapper + .cache_job_destination(new_destination)) # Reset job state job = job_state.job_wrapper.get_job() if resubmit.get('handler', None): - log.debug('(%s/%s) Job reassigned to handler %s', job_state.job_wrapper.job_id, job_state.job_id, resubmit['handler']) + log.debug('(%s/%s) Job reassigned to handler %s', + job_state.job_wrapper.job_id, job_state.job_id, + resubmit['handler']) job.set_handler(resubmit['handler']) job_runner.sa_session.add( job ) # Is this safe to do here? job_runner.sa_session.flush() - # Cache the destination to prevent rerunning dynamic after resubmit - job_state.job_wrapper.job_runner_mapper.cached_job_destination = new_destination + # Cache the destination to prevent rerunning dynamic after + # resubmit + job_state.job_wrapper.job_runner_mapper \ + .cached_job_destination = new_destination job_state.job_wrapper.set_job_destination(new_destination) # Clear external ID (state change below flushes the change) job.job_runner_external_id = None @@ -45,5 +60,7 @@ if job.params is None: job.params = {} job_state.runner_state_handled = True - job_runner.mark_as_resubmitted( job_state ) + info = "This job was resubmitted to the queue because %s on its " \ + "compute resource." % MESSAGES[job_state.runner_state] + job_runner.mark_as_resubmitted(job_state, info=info) return diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/managers/base.py --- a/lib/galaxy/managers/base.py +++ b/lib/galaxy/managers/base.py @@ -700,8 +700,8 @@ setattr( item, key, val ) return val - def deserialize_basestring( self, trans, item, key, val ): - val = self.validate.basestring( key, val ) + def deserialize_basestring( self, trans, item, key, val, convert_none_to_empty=False ): + val = '' if ( convert_none_to_empty and val is None ) else self.validate.basestring( key, val ) return self.default_deserializer( trans, item, key, val ) def deserialize_bool( self, trans, item, key, val ): diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/managers/hdas.py --- a/lib/galaxy/managers/hdas.py +++ b/lib/galaxy/managers/hdas.py @@ -154,8 +154,9 @@ # error here if disallowed - before jobs are stopped #TODO: poss. move to DatasetAssociationManager self.dataset_manager.error_unless_dataset_purge_allowed( trans, hda ) + if trans.user: + trans.user.total_disk_usage -= hda.quota_amount( trans.user ) super( HDAManager, self ).purge( trans, hda, flush=flush ) - if hda.creating_job_associations: job = hda.creating_job_associations[0].job if not job.finished: @@ -195,6 +196,32 @@ break return job + def _job_state_history_query( self, hda ): + """ + Return a query of the job's state history for the job that created this hda. + """ + session = self.app.model.context + JobToOutputDatasetAssociation = model.JobToOutputDatasetAssociation + JobStateHistory = model.JobStateHistory + + # TODO: this does not play well with copied hdas + # NOTE: don't eagerload (JODA will load the hda were using!) + hda_id = hda.id + query = ( session.query( JobToOutputDatasetAssociation, JobStateHistory ) + .filter( JobToOutputDatasetAssociation.dataset_id == hda_id ) + .filter( JobStateHistory.job_id == JobToOutputDatasetAssociation.job_id ) + .enable_eagerloads( False ) ) + return query + + def has_been_resubmitted( self, hda ): + """ + Return True if the hda's job was resubmitted at any point. + """ + job_states = model.Job.states + query = ( self._job_state_history_query( hda ) + .filter( model.JobStateHistory.state == job_states.RESUBMITTED ) ) + return self.app.model.context.query( query.exists() ).scalar() + # .... serialization def get_display_apps( self, trans, hda ): """ @@ -324,7 +351,7 @@ 'history_content_type', 'dataset_id', 'state', 'extension', - 'deleted', 'purged', 'visible', 'resubmitted', + 'deleted', 'purged', 'visible', 'type', 'url' ]) self.add_view( 'detailed', [ @@ -340,7 +367,8 @@ 'file_ext', 'file_size', 'create_time', 'update_time', - 'metadata', 'meta_files', 'data_type', + 'resubmitted', + 'metadata', 'meta_files', 'data_type', 'peek', #TODO: why is this named uuid!? The hda doesn't have a uuid - it's the underlying dataset's uuid! @@ -388,7 +416,7 @@ 'hda_ldda' : lambda *a: 'hda', # remapped - 'info' : lambda t, i, k: i.info.strip() if isinstance( i.info, basestring ) else i.info, + 'info' : lambda t, i, k: i.info.strip() if isinstance( i.info, basestring ) else '', 'misc_info' : lambda t, i, k: self.serializers[ 'info' ]( t, i, k ), 'misc_blurb' : lambda t, i, k: i.blurb, 'genome_build' : lambda t, i, k: i.dbkey, @@ -400,7 +428,7 @@ 'copied_from_history_dataset_association_id' : self.serialize_id, 'copied_from_library_dataset_dataset_association_id': self.serialize_id, - 'resubmitted' : lambda t, i, k: i._state == t.app.model.Dataset.states.RESUBMITTED, + 'resubmitted' : lambda t, i, k: self.hda_manager.has_been_resubmitted( i ), 'meta_files' : self.serialize_meta_files, 'file_path' : self.serialize_file_path, @@ -583,7 +611,8 @@ # remapped 'genome_build' : lambda t, i, k, v: self.deserialize_genome_build( t, i, 'dbkey', v ), - 'misc_info' : lambda t, i, k, v: self.deserialize_basestring( t, i, 'info', v ), + 'misc_info' : lambda t, i, k, v: ( + self.deserialize_basestring( t, i, 'info', v, convert_none_to_empty=True ) ), #TODO: mixin: deletable 'deleted' : self.deserialize_bool, diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/managers/workflows.py --- a/lib/galaxy/managers/workflows.py +++ b/lib/galaxy/managers/workflows.py @@ -569,7 +569,7 @@ for step_index in step_indices: step_dict = supplied_steps[ step_index ] uuid = step_dict.get("uuid", None) - if uuid: + if uuid and uuid != "None": if uuid in discovered_uuids: raise exceptions.DuplicatedIdentifierException("Duplicate step UUID in request.") discovered_uuids.add(uuid) @@ -586,10 +586,9 @@ type-specific functionality from the incoming dicitionary. """ step = model.WorkflowStep() - # TODO: Consider handling position inside module. step.position = step_dict['position'] - if "uuid" in step_dict: + if "uuid" in step_dict and step_dict['uuid'] != "None": step.uuid = step_dict["uuid"] if "label" in step_dict: step.label = step_dict["label"] diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -1335,9 +1335,8 @@ DISCARDED = 'discarded', PAUSED = 'paused', SETTING_METADATA = 'setting_metadata', - FAILED_METADATA = 'failed_metadata', - RESUBMITTED = 'resubmitted' ) - # failed_metadata and resubmitted are only valid as DatasetInstance states currently + FAILED_METADATA = 'failed_metadata') + # failed_metadata is only valid as DatasetInstance state currently non_ready_states = ( states.UPLOAD, diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/model/orm/logging_connection_proxy.py --- a/lib/galaxy/model/orm/logging_connection_proxy.py +++ b/lib/galaxy/model/orm/logging_connection_proxy.py @@ -2,7 +2,7 @@ import inspect import os -from galaxy.model.orm import * +from galaxy.model.orm import ConnectionProxy import logging diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -417,13 +417,14 @@ dict_collection_visible_keys = ( 'id', 'name', 'version', 'description' ) default_template = 'tool_form.mako' - def __init__( self, config_file, tool_source, app, guid=None, repository_id=None ): + def __init__( self, config_file, tool_source, app, guid=None, repository_id=None, allow_code_files=True ): """Load a tool from the config named by `config_file`""" # Determine the full path of the directory where the tool config is self.config_file = config_file self.tool_dir = os.path.dirname( config_file ) self.app = app self.repository_id = repository_id + self._allow_code_files = allow_code_files #setup initial attribute values self.inputs = odict() self.stdio_exit_codes = list() @@ -704,14 +705,15 @@ # Load any tool specific code (optional) Edit: INS 5/29/2007, # allow code files to have access to the individual tool's # "module" if it has one. Allows us to reuse code files, etc. - for code_elem in root.findall("code"): - for hook_elem in code_elem.findall("hook"): - for key, value in hook_elem.items(): - # map hook to function - self.hook_map[key] = value - file_name = code_elem.get("file") - code_path = os.path.join( self.tool_dir, file_name ) - execfile( code_path, self.code_namespace ) + if self._allow_code_files: + for code_elem in root.findall("code"): + for hook_elem in code_elem.findall("hook"): + for key, value in hook_elem.items(): + # map hook to function + self.hook_map[key] = value + file_name = code_elem.get("file") + code_path = os.path.join( self.tool_dir, file_name ) + execfile( code_path, self.code_namespace ) # User interface hints uihints_elem = root.find( "uihints" ) @@ -2433,7 +2435,7 @@ continue # state for subsection/group - group_state = state_inputs[input.name] + group_state = state_inputs.get(input.name, {}) # iterate and update values if input.type == 'repeat': @@ -2444,10 +2446,12 @@ elif input.type == 'conditional': if 'test_param' in tool_dict: test_param = tool_dict['test_param'] - test_param['value'] = jsonify(group_state[test_param['name']]) - if '__current_case__' in group_state: - i = group_state['__current_case__'] - iterate(tool_dict['cases'][i]['inputs'], input.cases[i].inputs, group_state, other_values) + test_param['value'] = jsonify(group_state.get(test_param['name'], None)) + for i in range (len ( tool_dict['cases'] ) ): + current_state = {} + if i == group_state.get('__current_case__', None): + current_state = group_state + iterate(tool_dict['cases'][i]['inputs'], input.cases[i].inputs, current_state, other_values) else: # create input dictionary, try to pass other_values if to_dict function supports it e.g. dynamic options try: @@ -2459,11 +2463,15 @@ input_name = tool_dict.get('name') if input_name: # backup default value - tool_dict['default_value'] = input.get_initial_value(trans, other_values) + try: + tool_dict['default_value'] = input.get_initial_value(trans, other_values) + except Exception: + # get initial value failed due to improper late validation + tool_dict['default_value'] = None + pass # update input value from tool state - if input_name in state_inputs: - tool_dict['value'] = state_inputs[input_name] + tool_dict['value'] = state_inputs.get(input_name, None) # sanitize values sanitize(tool_dict, 'value') @@ -2584,28 +2592,44 @@ # dataset used; parameter should be the analygous dataset in the # current history. history = trans.get_history() - hda_source_dict = {} # Mapping from HDA in history to source HDAs. + + # Create index for hdas. + hda_source_dict = {} for hda in history.datasets: - source_hda = hda.copied_from_history_dataset_association - while source_hda: - if source_hda.dataset.id not in hda_source_dict or source_hda.hid == hda.hid: - hda_source_dict[ source_hda.dataset.id ] = hda - source_hda = source_hda.copied_from_history_dataset_association + key = '%s_%s' % (hda.hid, hda.dataset.id) + hda_source_dict[ hda.dataset.id ] = hda_source_dict[ key ] = hda # Ditto for dataset collections. hdca_source_dict = {} for hdca in history.dataset_collections: - source_hdca = hdca.copied_from_history_dataset_collection_association - while source_hdca: - if source_hdca.collection.id not in hdca_source_dict or source_hdca.hid == hdca.hid: - hdca_source_dict[ source_hdca.collection.id ] = hdca - source_hdca = source_hdca.copied_from_history_dataset_collection_association + key = '%s_%s' % (hdca.hid, hdca.collection.id) + hdca_source_dict[ hdca.collection.id ] = hdca_source_dict[ key ] = hdca + + # Map dataset or collection to current history + def map_to_history(value): + id = None + source = None + if isinstance(value, trans.app.model.HistoryDatasetAssociation): + id = value.dataset.id + source = hda_source_dict + elif isinstance(value, trans.app.model.HistoryDatasetCollectionAssociation): + id = value.collection.id + source = hdca_source_dict + else: + return None + key = '%s_%s' % (value.hid, id) + if key in source: + return source[ key ] + elif id in source: + return source[ id ] + else: + return None # Unpack unvalidated values to strings, they'll be validated when the # form is submitted (this happens when re-running a job that was # initially run by a workflow) #This needs to be done recursively through grouping parameters - def rerun_callback( input, value, prefixed_name, prefixed_label ): + def mapping_callback( input, value, prefixed_name, prefixed_label ): if isinstance( value, UnvalidatedValue ): try: return input.to_html_value( value.value, trans.app ) @@ -2617,22 +2641,17 @@ if isinstance(value,list): values = [] for val in value: - if isinstance(val, trans.app.model.HistoryDatasetAssociation): - if val.dataset.id in hda_source_dict: - values.append( hda_source_dict[ val.dataset.id ] ) - else: - values.append( val ) + new_val = map_to_history( val ) + if new_val: + values.append( new_val ) + else: + values.append( val ) return values - if isinstance(value, trans.app.model.HistoryDatasetAssociation): - if value.dataset.id in hda_source_dict: - return hda_source_dict[ value.dataset.id ] - if isinstance(value, trans.app.model.HistoryDatasetCollectionAssociation): - if value.collection.id in hdca_source_dict: - return hdca_source_dict[ value.collection.id ] + else: + return map_to_history( value ) elif isinstance( input, DataCollectionToolParameter ): - if value.collection.id in hdca_source_dict: - return hdca_source_dict[ value.collection.id ] - visit_input_values( tool_inputs, params, rerun_callback ) + return map_to_history( value ) + visit_input_values( tool_inputs, params, mapping_callback ) def _compare_tool_version( self, trans, job ): """ diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/tools/parameters/basic.py --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -15,6 +15,7 @@ from galaxy.util import string_as_bool, sanitize_param, unicodify from galaxy.util import listify from galaxy.util.odict import odict +from galaxy.util.expressions import ExpressionContext from sanitize import ToolParameterSanitizer import validation import dynamic_options @@ -802,8 +803,9 @@ self.is_dynamic = ( ( self.dynamic_options is not None ) or ( self.options is not None ) ) def _get_dynamic_options_call_other_values( self, trans, other_values ): - call_other_values = { "__trans__": trans } + call_other_values = ExpressionContext({ "__trans__": trans }) if other_values: + call_other_values.parent = other_values.parent call_other_values.update( other_values.dict ) return call_other_values @@ -1505,8 +1507,9 @@ def _get_options_from_code( self, trans=None, value=None, other_values=None ): assert self.dynamic_options, Exception( "dynamic_options was not specifed" ) - call_other_values = { '__trans__': trans, '__value__': value } + call_other_values = ExpressionContext({ '__trans__': trans, '__value__': value }) if other_values: + call_other_values.parent = other_values.parent call_other_values.update( other_values.dict ) try: return eval( self.dynamic_options, self.tool.code_namespace, call_other_values ) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/tools/toolbox/base.py --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -978,7 +978,9 @@ if tool_key in val.elems: self._tool_panel[ key ].elems[ tool_key ] = new_tool break - self._tools_by_id[ tool_id ] = new_tool + # (Re-)Register the reloaded tool, this will handle + # _tools_by_id and _tool_versions_by_id + self.register_tool( new_tool ) message = "Reloaded the tool:<br/>" message += "<b>name:</b> %s<br/>" % old_tool.name message += "<b>id:</b> %s<br/>" % old_tool.id diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/util/dbkeys.py --- a/lib/galaxy/util/dbkeys.py +++ b/lib/galaxy/util/dbkeys.py @@ -38,7 +38,7 @@ for dataset in datasets: rval.append( ( dataset.dbkey, "%s (%s) [History]" % ( dataset.name, dataset.dbkey ) ) ) user = trans.user - if user and 'dbkeys' in user.preferences: + if user and hasattr( user, 'preferences' ) and 'dbkeys' in user.preferences: user_keys = loads( user.preferences['dbkeys'] ) for key, chrom_dict in user_keys.iteritems(): rval.append( ( key, "%s (%s) [Custom]" % ( chrom_dict['name'], key ) ) ) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/version.py --- a/lib/galaxy/version.py +++ b/lib/galaxy/version.py @@ -1,3 +1,3 @@ VERSION_MAJOR = "15.03" -VERSION_MINOR = "1" +VERSION_MINOR = "2" VERSION = VERSION_MAJOR + ('.' + VERSION_MINOR if VERSION_MINOR else '') diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/web/framework/webapp.py --- a/lib/galaxy/web/framework/webapp.py +++ b/lib/galaxy/web/framework/webapp.py @@ -668,7 +668,8 @@ """ history = None if self.galaxy_session: - history = self.galaxy_session.current_history + if hasattr( self.galaxy_session, 'current_history' ): + history = self.galaxy_session.current_history if not history and util.string_as_bool( create ): history = self.new_history() return history diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/galaxy/api/job_files.py --- a/lib/galaxy/webapps/galaxy/api/job_files.py +++ b/lib/galaxy/webapps/galaxy/api/job_files.py @@ -83,9 +83,21 @@ self.__check_job_can_write_to_path( trans, job, path ) # Is this writing an unneeded file? Should this just copy in Python? - input_file = payload.get( "file", payload.get( "__file", None ) ).file + if '__file_path' in payload: + file_path = payload.get( '__file_path' ) + upload_store = trans.app.config.nginx_upload_job_files_store + assert upload_store, ( "Request appears to have been processed by" + " nginx_upload_module but Galaxy is not" + " configured to recognize it" ) + assert file_path.startswith( upload_store ), \ + ( "Filename provided by nginx (%s) is not in correct" + " directory (%s)" % ( file_path, upload_store ) ) + input_file = open( file_path ) + else: + input_file = payload.get( "file", + payload.get( "__file", None ) ).file try: - shutil.copyfile( input_file.name, path ) + shutil.move( input_file.name, path ) finally: input_file.close() return {"message": "ok"} diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/galaxy/api/tools.py --- a/lib/galaxy/webapps/galaxy/api/tools.py +++ b/lib/galaxy/webapps/galaxy/api/tools.py @@ -145,7 +145,6 @@ if success: trans.response.set_content_type( 'application/x-gzip' ) download_file = open( tool_tarball ) - os.unlink( tool_tarball ) tarball_path, filename = os.path.split( tool_tarball ) trans.response.headers[ "Content-Disposition" ] = 'attachment; filename="%s.tgz"' % ( id ) return download_file @@ -332,7 +331,7 @@ # job's previous parameters and incoming parameters. Incoming parameters # have priority. # - original_job = self.hda_manager.creating_job( original_dataset ) + original_job = self.hda_manager.creating_job( trans, original_dataset ) tool = trans.app.toolbox.get_tool( original_job.tool_id ) if not tool or not tool.allow_user_access( trans.user ): return trans.app.model.Dataset.conversion_messages.NO_TOOL diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/galaxy/buildapp.py --- a/lib/galaxy/webapps/galaxy/buildapp.py +++ b/lib/galaxy/webapps/galaxy/buildapp.py @@ -106,13 +106,13 @@ pack_scripts() # Close any pooled database connections before forking try: - galaxy.model.mapping.metadata.engine.connection_provider._pool.dispose() + galaxy.model.mapping.metadata.bind.dispose() except: - pass + log.exception("Unable to dispose of pooled galaxy model database connections.") try: - galaxy.model.tool_shed_install.mapping.metadata.engine.connection_provider._pool.dispose() + galaxy.model.tool_shed_install.mapping.metadata.bind.dispose() except: - pass + log.exception("Unable to dispose of pooled toolshed install model database connections.") if not app.config.is_uwsgi: postfork_setup() diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/galaxy/controllers/dataset.py --- a/lib/galaxy/webapps/galaxy/controllers/dataset.py +++ b/lib/galaxy/webapps/galaxy/controllers/dataset.py @@ -852,22 +852,24 @@ status = 'done' try: id = trans.app.security.decode_id( dataset_id ) - history = trans.get_history() user = trans.get_user() hda = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id ) # Invalid HDA assert hda, 'Invalid history dataset ID' + # Walk up parent datasets to find the containing history + history = trans.get_history() topmost_parent = hda while topmost_parent.parent: topmost_parent = topmost_parent.parent - assert topmost_parent in history.datasets, "Data does not belong to current history" # If the user is anonymous, make sure the HDA is owned by the current session. if not user: - assert trans.galaxy_session.current_history_id == trans.history.id, 'Invalid history dataset ID' + current_history_id = trans.galaxy_session.current_history_id + assert topmost_parent.history.id == current_history_id, 'Data does not belong to current user' # If the user is known, make sure the HDA is owned by the current user. else: - assert topmost_parent.history.user == trans.user, 'Invalid history dataset ID' + assert topmost_parent.history.user == user, 'Data does not belong to current user' + # Ensure HDA is deleted hda.deleted = True # HDA is purgeable @@ -890,8 +892,8 @@ except: log.exception( 'Unable to purge dataset (%s) on purge of HDA (%s):' % ( hda.dataset.id, hda.id ) ) trans.sa_session.flush() - except Exception: - msg = 'HDA purge failed (encoded: %s, decoded: %s)' % ( dataset_id, id ) + except Exception, exc: + msg = 'HDA purge failed (encoded: %s, decoded: %s): %s' % ( dataset_id, id, exc ) log.exception( msg ) trans.log_event( msg ) message = 'Dataset removal from disk failed' diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/galaxy/controllers/history.py --- a/lib/galaxy/webapps/galaxy/controllers/history.py +++ b/lib/galaxy/webapps/galaxy/controllers/history.py @@ -605,9 +605,13 @@ except Exception, exc: user_id = str( trans.user.id ) if trans.user else '(anonymous)' - log.exception( 'Error bootstrapping history for user %s: %s', user_id, str( exc ) ) - history_dictionary[ 'error' ] = ( 'An error occurred getting the history data from the server. ' - + 'Please contact a Galaxy administrator if the problem persists.' ) + log.exception( 'Error bootstrapping history for user %s: %s', user_id, exc ) + if isinstance( exc, exceptions.ItemAccessibilityException ): + error_msg = 'You do not have permission to view this history.' + else: + error_msg = ( 'An error occurred getting the history data from the server. ' + + 'Please contact a Galaxy administrator if the problem persists.' ) + return trans.show_error_message( error_msg, use_panels=use_panels ) return trans.fill_template_mako( "history/view.mako", history=history_dictionary, hdas=hda_dictionaries, user_is_owner=user_is_owner, diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca 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 @@ -1136,7 +1136,7 @@ def make_library_uploaded_dataset( self, trans, cntrller, params, name, path, type, library_bunch, in_folder=None ): link_data_only = params.get( 'link_data_only', 'copy_files' ) uuid_str = params.get( 'uuid', None ) - file_type = params.get( 'file_type' ) + file_type = params.get( 'file_type', None ) library_bunch.replace_dataset = None # not valid for these types of upload uploaded_dataset = util.bunch.Bunch() new_name = name @@ -1152,8 +1152,8 @@ uploaded_dataset.type = type uploaded_dataset.ext = None uploaded_dataset.file_type = file_type - uploaded_dataset.dbkey = params.get( 'dbkey' ) - uploaded_dataset.space_to_tab = params.get( 'space_to_tab' ) + uploaded_dataset.dbkey = params.get( 'dbkey', None ) + uploaded_dataset.space_to_tab = params.get( 'space_to_tab', None ) if in_folder: uploaded_dataset.in_folder = in_folder uploaded_dataset.data = upload_common.new_upload( trans, cntrller, uploaded_dataset, library_bunch ) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/galaxy/controllers/tag.py --- a/lib/galaxy/webapps/galaxy/controllers/tag.py +++ b/lib/galaxy/webapps/galaxy/controllers/tag.py @@ -42,7 +42,7 @@ # Apply tag. item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) ) user = trans.user - self.get_tag_handler( trans ).apply_item_tags( trans, user, item, new_tag.encode( 'utf-8' ) ) + self.get_tag_handler( trans ).apply_item_tags( user, item, new_tag.encode( 'utf-8' ) ) trans.sa_session.flush() # Log. params = dict( item_id=item.id, item_class=item_class, tag=new_tag ) @@ -57,7 +57,7 @@ # Remove tag. item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) ) user = trans.user - self.get_tag_handler( trans ).remove_item_tag( trans, user, item, tag_name.encode( 'utf-8' ) ) + self.get_tag_handler( trans ).remove_item_tag( user, item, tag_name.encode( 'utf-8' ) ) trans.sa_session.flush() # Log. params = dict( item_id=item.id, item_class=item_class, tag=tag_name ) @@ -73,8 +73,8 @@ # Apply tags. item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) ) user = trans.user - self.get_tag_handler( trans ).delete_item_tags( trans, user, item ) - self.get_tag_handler( trans ).apply_item_tags( trans, user, item, new_tags.encode( 'utf-8' ) ) + self.get_tag_handler( trans ).delete_item_tags( user, item ) + self.get_tag_handler( trans ).apply_item_tags( user, item, new_tags.encode( 'utf-8' ) ) trans.sa_session.flush() @web.expose diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/galaxy/controllers/visualization.py --- a/lib/galaxy/webapps/galaxy/controllers/visualization.py +++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py @@ -985,7 +985,7 @@ else: # Loading new visualization. dataset = self.get_hda_or_ldda( trans, hda_ldda, dataset_id ) - job = self.hda_manager.creating_job( dataset ) + job = self.hda_manager.creating_job( trans, dataset ) viz_config = { 'dataset_id': dataset_id, 'tool_id': job.tool_id, @@ -1017,7 +1017,7 @@ if dataset_id: decoded_id = self.decode_id( dataset_id ) hda = self.hda_manager.get_accessible( trans, decoded_id, trans.user ) - hda = self.hda_manager.error_if_uploading( hda ) + hda = self.hda_manager.error_if_uploading( trans, hda ) else: return trans.show_message( "Phyloviz couldn't find a dataset_id" ) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/reports/buildapp.py --- a/lib/galaxy/webapps/reports/buildapp.py +++ b/lib/galaxy/webapps/reports/buildapp.py @@ -70,12 +70,13 @@ webapp = wrap_in_static( webapp, global_conf, **kwargs ) # Close any pooled database connections before forking try: - galaxy.model.mapping.metadata.engine.connection_provider._pool.dispose() + galaxy.model.mapping.metadata.bind.dispose() except: - pass + log.exception("Unable to dispose of pooled galaxy model database connections.") # Return return webapp + def wrap_in_middleware( app, global_conf, **local_conf ): """Based on the configuration wrap `app` in a set of common and useful middleware.""" # Merge the global and local configurations diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/galaxy/webapps/tool_shed/buildapp.py --- a/lib/galaxy/webapps/tool_shed/buildapp.py +++ b/lib/galaxy/webapps/tool_shed/buildapp.py @@ -134,13 +134,28 @@ # Wrap the webapp in some useful middleware if kwargs.get( 'middleware', True ): webapp = wrap_in_middleware( webapp, global_conf, **kwargs ) - if asbool( kwargs.get( 'static_enabled', True ) ): - webapp = wrap_in_static( webapp, global_conf, **kwargs ) + # TEST FOR UWSGI -- TODO save this somewhere so we only have to do it once. + is_uwsgi = False + try: + # The uwsgi module is automatically injected by the parent uwsgi + # process and only exists that way. If anything works, this is a + # uwsgi-managed process. + import uwsgi + is_uwsgi = uwsgi.numproc + is_uwsgi = True + except ImportError: + # This is not a uwsgi process, or something went horribly wrong. + pass + if asbool( kwargs.get( 'static_enabled', True) ): + if is_uwsgi: + log.error("Static middleware is enabled in your configuration but this is a uwsgi process. Refusing to wrap in static middleware.") + else: + webapp = wrap_in_static( webapp, global_conf, **kwargs ) # Close any pooled database connections before forking try: - galaxy.webapps.tool_shed.model.mapping.metadata.engine.connection_provider._pool.dispose() + galaxy.webapps.tool_shed.model.mapping.metadata.bind.dispose() except: - pass + log.exception("Unable to dispose of pooled tool_shed model database connections.") # Return return webapp diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/tool_shed/metadata/metadata_generator.py --- a/lib/tool_shed/metadata/metadata_generator.py +++ b/lib/tool_shed/metadata/metadata_generator.py @@ -456,8 +456,8 @@ try: exported_workflow_dict = json.loads( workflow_text ) except Exception, e: - log.exception( "Skipping file %s since it does not seem to be a valid exported Galaxy workflow: %s" \ - % str( relative_path ), str( e ) ) + log.exception( "Skipping file %s since it does not seem to be a valid exported Galaxy workflow: %s" + % ( str( relative_path ), str( e ) ) ) valid_exported_galaxy_workflow = False if valid_exported_galaxy_workflow and \ 'a_galaxy_workflow' in exported_workflow_dict and \ diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/tool_shed/tools/tool_validator.py --- a/lib/tool_shed/tools/tool_validator.py +++ b/lib/tool_shed/tools/tool_validator.py @@ -292,7 +292,7 @@ def load_tool_from_config( self, repository_id, full_path ): try: - tool = self.app.toolbox.load_tool( full_path, repository_id=repository_id ) + tool = self.app.toolbox.load_tool( full_path, repository_id=repository_id, allow_code_files=False ) valid = True error_message = None except KeyError, e: diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca lib/tool_shed/util/tool_util.py --- a/lib/tool_shed/util/tool_util.py +++ b/lib/tool_shed/util/tool_util.py @@ -237,12 +237,19 @@ if invalid: # We're attempting to display a tool in the tool shed that has been determined to have errors, so is invalid. return state + try: + # Attempt to generate the tool state using the standard Galaxy-side code + return tool.new_state( trans ) + except Exception, e: + # Fall back to building tool state as below + log.debug( 'Failed to build tool state for tool "%s" using standard method, will try to fall back on custom method: %s', tool.id, e ) inputs = tool.inputs_by_page[ 0 ] context = ExpressionContext( state.inputs, parent=None ) for input in inputs.itervalues(): try: state.inputs[ input.name ] = input.get_initial_value( trans, context ) except: + # FIXME: not all values should be an empty list state.inputs[ input.name ] = [] return state diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/mvc/history/history-model.js --- a/static/scripts/mvc/history/history-model.js +++ b/static/scripts/mvc/history/history-model.js @@ -257,7 +257,7 @@ setAsCurrent : function(){ var history = this, - xhr = jQuery.getJSON( '/history/set_as_current?id=' + this.id ); + xhr = jQuery.getJSON( galaxy_config.root + 'history/set_as_current?id=' + this.id ); xhr.done( function(){ history.trigger( 'set-as-current', history ); @@ -361,7 +361,7 @@ var HistoryCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).extend( /** @lends HistoryCollection.prototype */{ model : History, - + /** logger used to record this.log messages, commonly set to console */ //logger : console, diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/mvc/library/library-dataset-view.js --- a/static/scripts/mvc/library/library-dataset-view.js +++ b/static/scripts/mvc/library/library-dataset-view.js @@ -116,7 +116,7 @@ }, downloadDataset: function(){ - var url = '/api/libraries/datasets/download/uncompressed'; + var url = ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/download/uncompressed'; var data = {'ld_ids' : this.id}; this.processDownload(url, data); }, @@ -232,7 +232,7 @@ var self = this; if (this.options.fetched_permissions === undefined){ - $.get( "/api/libraries/datasets/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { + $.get( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { self.prepareSelectBoxes({fetched_permissions:fetched_permissions, is_admin:is_admin}); }).fail(function(){ mod_toastr.error('An error occurred while attempting to fetch dataset permissions.'); @@ -273,7 +273,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#access_perm'), ajax: { - url: "/api/libraries/datasets/" + self.id + "/permissions?scope=available", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=available", dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -320,7 +320,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#modify_perm'), ajax: { - url: "/api/libraries/datasets/" + self.id + "/permissions?scope=available", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=available", dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -367,7 +367,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#manage_perm'), ajax: { - url: "/api/libraries/datasets/" + self.id + "/permissions?scope=available", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=available", dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -413,7 +413,7 @@ self.manageSelectObject = new mod_select.View(manage_select_options); } else { // Non-admins have select with pre-loaded options var template = self.templateAccessSelect(); - $.get( "/api/libraries/datasets/" + self.id + "/permissions?scope=available", function( data ) { + $.get( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?scope=available", function( data ) { $('.access_perm').html(template({options:data.roles})); self.accessSelectObject = $('#access_select').select2(); }).fail(function() { @@ -436,7 +436,7 @@ makeDatasetPrivate: function(){ var self = this; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=make_private").done(function(fetched_permissions) { + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=make_private").done(function(fetched_permissions) { self.model.set({is_unrestricted:false}); self.showPermissions({fetched_permissions:fetched_permissions}) mod_toastr.success('The dataset is now private to you.'); @@ -447,7 +447,7 @@ removeDatasetRestrictions: function(){ var self = this; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=remove_restrictions") + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=remove_restrictions") .done(function(fetched_permissions) { self.model.set({is_unrestricted:true}); self.showPermissions({fetched_permissions:fetched_permissions}) @@ -478,7 +478,7 @@ modify_ids.push(modify_roles[i].id); }; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=set_permissions", { 'access_ids[]': access_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=set_permissions", { 'access_ids[]': access_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) .done(function(fetched_permissions){ //fetch dataset again self.showPermissions({fetched_permissions:fetched_permissions}) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/mvc/library/library-folder-view.js --- a/static/scripts/mvc/library/library-folder-view.js +++ b/static/scripts/mvc/library/library-folder-view.js @@ -81,7 +81,7 @@ var self = this; if (this.options.fetched_permissions === undefined){ - $.get( "/api/folders/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { + $.get( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/folders/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { self.prepareSelectBoxes({fetched_permissions:fetched_permissions}); }).fail(function(){ mod_toastr.error('An error occurred while attempting to fetch folder permissions.'); @@ -125,7 +125,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#' + id), ajax: { - url: "/api/folders/" + self.id + "/permissions?scope=available", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/folders/" + self.id + "/permissions?scope=available", dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -195,7 +195,7 @@ var manage_ids = this._extractIds(this.manageSelectObject.$el.select2('data')); var modify_ids = this._extractIds(this.modifySelectObject.$el.select2('data')); - $.post("/api/folders/" + self.id + "/permissions?action=set_permissions", { 'add_ids[]': add_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/folders/" + self.id + "/permissions?action=set_permissions", { 'add_ids[]': add_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) .done(function(fetched_permissions){ //fetch dataset again self.showPermissions({fetched_permissions:fetched_permissions}) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/mvc/library/library-foldertoolbar-view.js --- a/static/scripts/mvc/library/library-foldertoolbar-view.js +++ b/static/scripts/mvc/library/library-foldertoolbar-view.js @@ -294,7 +294,7 @@ dataset_ids.push( this.parentElement.parentElement.id ); } } ); - var url = '/api/libraries/datasets/download/' + format; + var url = ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/download/' + format; var data = { 'ld_ids' : dataset_ids }; this.processDownload( url, data, 'get' ); }, @@ -386,7 +386,7 @@ fetchExtAndGenomes: function(){ var that = this; mod_utils.get({ - url : galaxy_config.root + "api/datatypes?extension_only=False", + url : ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/datatypes?extension_only=False", success : function( datatypes ) { for (key in datatypes) { that.list_extensions.push({ @@ -403,7 +403,7 @@ } }); mod_utils.get({ - url: galaxy_config.root + "api/genomes", + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/genomes", success: function( genomes ) { for ( key in genomes ) { that.list_genomes.push({ @@ -689,7 +689,7 @@ for ( var i = history_dataset_ids.length - 1; i >= 0; i-- ) { history_dataset_id = history_dataset_ids[i]; var folder_item = new mod_library_model.Item(); - folder_item.url = '/api/folders/' + this.options.id + '/contents'; + folder_item.url = ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders/' + this.options.id + '/contents'; folder_item.set( { 'from_hda_id':history_dataset_id } ); hdas_to_add.push( folder_item ); } @@ -749,7 +749,7 @@ } return true; } - var promise = $.when( $.post( '/api/libraries/datasets?encoded_folder_id=' + that.id + + var promise = $.when( $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets?encoded_folder_id=' + that.id + '&source=' + options.source + '&path=' + popped_item + '&file_type=' + options.file_type + @@ -788,7 +788,7 @@ } return true; } - var promise = $.when( $.post( '/api/libraries/datasets?encoded_folder_id=' + that.id + + var promise = $.when( $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets?encoded_folder_id=' + that.id + '&source=' + options.source + '&path=' + popped_item + '&preserve_dirs=' + options.preserve_dirs + diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/mvc/library/library-library-view.js --- a/static/scripts/mvc/library/library-library-view.js +++ b/static/scripts/mvc/library/library-library-view.js @@ -87,7 +87,7 @@ var self = this; if (this.options.fetched_permissions === undefined){ - $.get( "/api/libraries/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { + $.get( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/" + self.id + "/permissions?scope=current").done(function(fetched_permissions) { self.prepareSelectBoxes({fetched_permissions:fetched_permissions}); }).fail(function(){ mod_toastr.error('An error occurred while attempting to fetch library permissions.'); @@ -134,7 +134,7 @@ placeholder: 'Click to select a role', container: self.$el.find('#' + id), ajax: { - url: "/api/libraries/" + self.id + "/permissions?scope=available&is_library_access=" + is_library_access, + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/" + self.id + "/permissions?scope=available&is_library_access=" + is_library_access, dataType: 'json', quietMillis: 100, data: function (term, page) { // page is the one-based page number tracked by Select2 @@ -193,7 +193,7 @@ makeDatasetPrivate: function(){ var self = this; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=make_private").done(function(fetched_permissions) { + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=make_private").done(function(fetched_permissions) { self.model.set({is_unrestricted:false}); self.showPermissions({fetched_permissions:fetched_permissions}) mod_toastr.success('The dataset is now private to you.'); @@ -204,7 +204,7 @@ removeDatasetRestrictions: function(){ var self = this; - $.post("/api/libraries/datasets/" + self.id + "/permissions?action=remove_restrictions") + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/datasets/" + self.id + "/permissions?action=remove_restrictions") .done(function(fetched_permissions) { self.model.set({is_unrestricted:true}); self.showPermissions({fetched_permissions:fetched_permissions}) @@ -230,7 +230,7 @@ var manage_ids = this._extractIds(this.manageSelectObject.$el.select2('data')); var modify_ids = this._extractIds(this.modifySelectObject.$el.select2('data')); - $.post("/api/libraries/" + self.id + "/permissions?action=set_permissions", { 'access_ids[]': access_ids, 'add_ids[]': add_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) + $.post( ( window.galaxy_config ? galaxy_config.root : '/' ) + "api/libraries/" + self.id + "/permissions?action=set_permissions", { 'access_ids[]': access_ids, 'add_ids[]': add_ids, 'manage_ids[]': manage_ids, 'modify_ids[]': modify_ids, } ) .done(function(fetched_permissions){ //fetch dataset again self.showPermissions({fetched_permissions:fetched_permissions}) diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/mvc/library/library-model.js --- a/static/scripts/mvc/library/library-model.js +++ b/static/scripts/mvc/library/library-model.js @@ -4,7 +4,7 @@ // LIBRARY RELATED MODELS var Library = Backbone.Model.extend({ - urlRoot: '/api/libraries/', + urlRoot: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/', /** based on show_deleted would this lib show in the list of lib's? * @param {Boolean} show_deleted are we including deleted libraries? @@ -19,7 +19,7 @@ }); var Libraries = Backbone.Collection.extend({ - url: '/api/libraries', + url: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries', model: Library, @@ -84,15 +84,15 @@ // FOLDER RELATED MODELS var Item = Backbone.Model.extend({ - urlRoot : '/api/libraries/datasets/' + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/' }); var Ldda = Backbone.Model.extend({ - urlRoot : '/api/libraries/datasets/' + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/' }); var FolderAsModel = Backbone.Model.extend({ - urlRoot: '/api/folders' + urlRoot: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders' }); var Folder = Backbone.Collection.extend({ @@ -152,7 +152,7 @@ var FolderContainer = Backbone.Model.extend({ defaults : { folder : new Folder(), - urlRoot : "/api/folders/", + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders/', id : "unknown" }, parse : function(obj) { @@ -169,11 +169,11 @@ // TODO UNITE var HistoryItem = Backbone.Model.extend({ - urlRoot : '/api/histories/' + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/histories/' }); var HistoryContents = Backbone.Collection.extend({ - urlRoot : '/api/histories/', + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/histories/', initialize: function(options){ this.id = options.id; }, @@ -184,11 +184,11 @@ }); var GalaxyHistory = Backbone.Model.extend({ - urlRoot : '/api/histories/' + urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/histories/' }); var GalaxyHistories = Backbone.Collection.extend({ - url : '/api/histories', + url : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/histories', model : GalaxyHistory }); @@ -199,7 +199,7 @@ */ var Jstree = Backbone.Model.extend({ - urlRoot: '/api/remote_files' + urlRoot: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/remote_files' }); return { diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/mvc/tools/tools-parameters.js --- a/static/scripts/mvc/tools/tools-parameters.js +++ b/static/scripts/mvc/tools/tools-parameters.js @@ -145,6 +145,7 @@ data : options, error_text : input_def.error_text || 'No options available', multiple : input_def.multiple, + optional : input_def.optional, searchable : input_def.searchable, onchange : function() { self.app.trigger('refresh'); diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca 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)},purge:function(j){if(this.get("purged")){return jQuery.when()}return this.save({deleted:true,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 +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({deleted:true,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(galaxy_config.root+"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 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/packed/mvc/library/library-dataset-view.js --- a/static/scripts/packed/mvc/library/library-dataset-view.js +++ b/static/scripts/packed/mvc/library/library-dataset-view.js @@ -1,1 +1,1 @@ -define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,b){var a=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_modify_dataset":"enableModification","click .toolbtn_cancel_modifications":"render","click .toolbtn-download-dataset":"downloadDataset","click .toolbtn-import-dataset":"importIntoHistory","click .toolbtn-share-dataset":"shareDataset","click .btn-copy-link-to-clipboard":"copyToClipboard","click .btn-make-private":"makeDatasetPrivate","click .btn-remove-restrictions":"removeDatasetRestrictions","click .toolbtn_save_permissions":"savePermissions","click .toolbtn_save_modifications":"comingSoon",},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchDataset()}},fetchDataset:function(e){this.options=_.extend(this.options,e);this.model=new c.Item({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{if(f.options.show_version){f.fetchVersion()}else{f.render()}}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){this.options=_.extend(this.options,e);$(".tooltip").remove();var f=this.templateDataset();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},fetchVersion:function(e){this.options=_.extend(this.options,e);that=this;if(!this.options.ldda_id){this.render();d.error("Library dataset version requested but no id provided.")}else{this.ldda=new c.Ldda({id:this.options.ldda_id});this.ldda.url=this.ldda.urlRoot+this.model.id+"/versions/"+this.ldda.id;this.ldda.fetch({success:function(){that.renderVersion()},error:function(g,f){if(typeof f.responseJSON!=="undefined"){d.error(f.responseJSON.err_msg)}else{d.error("An error ocurred.")}}})}},renderVersion:function(){$(".tooltip").remove();var e=this.templateVersion();this.$el.html(e({item:this.model,ldda:this.ldda}));$(".peek").html(this.ldda.get("peek"))},enableModification:function(){$(".tooltip").remove();var e=this.templateModifyDataset();this.$el.html(e({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},downloadDataset:function(){var e="/api/libraries/datasets/download/uncompressed";var f={ld_ids:this.id};this.processDownload(e,f)},processDownload:function(f,g,h){if(f&&g){g=typeof g=="string"?g:$.param(g);var e="";$.each(g.split("&"),function(){var i=this.split("=");e+='<input type="hidden" name="'+i[0]+'" value="'+i[1]+'" />'});$('<form action="'+f+'" method="'+(h||"post")+'">'+e+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon.")}},importIntoHistory:function(){this.refreshUserHistoriesList(function(e){var f=e.templateBulkImportInModal();e.modal=Galaxy.modal;e.modal.show({closing_events:true,title:"Import into History",body:f({histories:e.histories.models}),buttons:{Import:function(){e.importCurrentIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})},refreshUserHistoriesList:function(f){var e=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(g){if(g.length===0){d.warning("You have to create history first. Click this to do so.","",{onclick:function(){window.location="/"}})}else{f(e)}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg)}else{d.error("An error ocurred.")}}})},importCurrentIntoHistory:function(){var e=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();var f=new c.HistoryItem();f.url=f.urlRoot+e+"/contents";jQuery.getJSON(galaxy_config.root+"history/set_as_current?id="+e);f.save({content:this.id,source:"library"},{success:function(){Galaxy.modal.hide();d.success("Dataset imported. Click this to start analysing it.","",{onclick:function(){window.location="/"}})},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error("Dataset not imported. "+g.responseJSON.err_msg)}else{d.error("An error occured. Dataset not imported. Please try again.")}}})},shareDataset:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(f){this.options=_.extend(this.options,f);$(".tooltip").remove();if(this.options.fetched_permissions!==undefined){if(this.options.fetched_permissions.access_dataset_roles.length===0){this.model.set({is_unrestricted:true})}else{this.model.set({is_unrestricted:false})}}var h=false;if(Galaxy.currUser){h=Galaxy.currUser.isAdmin()}var g=this.templateDatasetPermissions();this.$el.html(g({item:this.model,is_admin:h}));var e=this;if(this.options.fetched_permissions===undefined){$.get("/api/libraries/datasets/"+e.id+"/permissions?scope=current").done(function(i){e.prepareSelectBoxes({fetched_permissions:i,is_admin:h})}).fail(function(){d.error("An error occurred while attempting to fetch dataset permissions.")})}else{this.prepareSelectBoxes({is_admin:h})}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},prepareSelectBoxes:function(r){this.options=_.extend(this.options,r);var s=this.options.fetched_permissions;var k=this.options.is_admin;var q=this;var m=[];for(var h=0;h<s.access_dataset_roles.length;h++){m.push(s.access_dataset_roles[h]+":"+s.access_dataset_roles[h])}var f=[];for(var h=0;h<s.modify_item_roles.length;h++){f.push(s.modify_item_roles[h]+":"+s.modify_item_roles[h])}var g=[];for(var h=0;h<s.manage_dataset_roles.length;h++){g.push(s.manage_dataset_roles[h]+":"+s.manage_dataset_roles[h])}if(k){var o={minimumInputLength:0,css:"access_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#access_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:m.join(","),dropdownCssClass:"bigdrop"};var l={minimumInputLength:0,css:"modify_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#modify_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:f.join(","),dropdownCssClass:"bigdrop"};var p={minimumInputLength:0,css:"manage_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#manage_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:g.join(","),dropdownCssClass:"bigdrop"};q.accessSelectObject=new b.View(o);q.modifySelectObject=new b.View(l);q.manageSelectObject=new b.View(p)}else{var n=q.templateAccessSelect();$.get("/api/libraries/datasets/"+q.id+"/permissions?scope=available",function(i){$(".access_perm").html(n({options:i.roles}));q.accessSelectObject=$("#access_select").select2()}).fail(function(){d.error("An error occurred while attempting to fetch dataset permissions.")})}},comingSoon:function(){d.warning("Feature coming soon.")},copyToClipboard:function(){var e=Backbone.history.location.href;if(e.lastIndexOf("/permissions")!==-1){e=e.substr(0,e.lastIndexOf("/permissions"))}window.prompt("Copy to clipboard: Ctrl+C, Enter",e)},makeDatasetPrivate:function(){var e=this;$.post("/api/libraries/datasets/"+e.id+"/permissions?action=make_private").done(function(f){e.model.set({is_unrestricted:false});e.showPermissions({fetched_permissions:f});d.success("The dataset is now private to you.")}).fail(function(){d.error("An error occurred while attempting to make dataset private.")})},removeDatasetRestrictions:function(){var e=this;$.post("/api/libraries/datasets/"+e.id+"/permissions?action=remove_restrictions").done(function(f){e.model.set({is_unrestricted:true});e.showPermissions({fetched_permissions:f});d.success("Access to this dataset is now unrestricted.")}).fail(function(){d.error("An error occurred while attempting to make dataset unrestricted.")})},savePermissions:function(e){var n=this;var k=this.accessSelectObject.$el.select2("data");var f=this.manageSelectObject.$el.select2("data");var m=this.modifySelectObject.$el.select2("data");var g=[];var j=[];var l=[];for(var h=k.length-1;h>=0;h--){g.push(k[h].id)}for(var h=f.length-1;h>=0;h--){j.push(f[h].id)}for(var h=m.length-1;h>=0;h--){l.push(m[h].id)}$.post("/api/libraries/datasets/"+n.id+"/permissions?action=set_permissions",{"access_ids[]":g,"manage_ids[]":j,"modify_ids[]":l,}).done(function(i){n.showPermissions({fetched_permissions:i});d.success("Permissions saved.")}).fail(function(){d.error("An error occurred while attempting to set dataset permissions.")})},templateDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');e.push(' <% if (item.get("can_user_modify")) { %>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library item" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(" <% } %>");e.push(' <% if (item.get("can_user_manage")) { %>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Manage permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(" <% } %>");e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<% if (item.get("is_unrestricted")) { %>');e.push(' <div class="alert alert-info">');e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"></span> To Clipboard</span></button> ');e.push(" </div>");e.push("<% } %>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push(' <% if (item.get("has_versions")) { %>');e.push(" <div>");e.push(" <h3>Expired versions:</h3>");e.push(" <ul>");e.push(' <% _.each(item.get("expired_versions"), function(version) { %>');e.push(' <li><a title="See details of this version" href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/versions/<%- version[0] %>"><%- version[1] %></a></li>');e.push(" <% }) %>");e.push(" <ul>");e.push(" </div>");e.push(" <% } %>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateVersion:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go to latest dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-caret-left fa-lg"></span> Latest dataset</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push(' <div class="alert alert-warning">This is an expired version of the library dataset: <%= _.escape(item.get("name")) %></div>');e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(ldda.id) %>">Name</th>');e.push(' <td><%= _.escape(ldda.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (ldda.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(ldda.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(ldda.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(ldda.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(ldda.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(ldda.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateModifyDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push('<p>For more editing options please import the dataset to history and use "Edit attributes" on it.</p>');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><input class="input_dataset_name form-control" type="text" placeholder="name" value="<%= _.escape(item.get("name")) %>"></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(' <tr scope="row">');e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <% if (item.get("metadata_comment_lines") === "") { %>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" <% } else { %>");e.push(' <td scope="row">unknown</td>');e.push(" <% } %>");e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" </table>");e.push("<div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push("</div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateDatasetPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to containing folder" class="btn btn-default primary-button" type="button"><span class="fa fa-folder-open-o"></span> Containing Folder</span></button></a>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go back to dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-file-o"></span> Dataset Details</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<h1>Dataset: <%= _.escape(item.get("name")) %></h1>');e.push('<div class="alert alert-warning">');e.push("<% if (is_admin) { %>");e.push("You are logged in as an <strong>administrator</strong> therefore you can manage any dataset on this Galaxy instance. Please make sure you understand the consequences.");e.push("<% } else { %>");e.push("You can assign any number of roles to any of the following permission types. However please read carefully the implications of such actions.");e.push("<% } %>");e.push("</div>");e.push('<div class="dataset_table">');e.push("<h2>Library-related permissions</h2>");e.push("<h4>Roles that can modify the library item</h4>");e.push('<div id="modify_perm" class="modify_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can modify name, metadata, and other information about this library item.</div>');e.push("<hr/>");e.push("<h2>Dataset-related permissions</h2>");e.push('<div class="alert alert-warning">Changes made below will affect <strong>every</strong> library item that was created from this dataset and also every history this dataset is part of.</div>');e.push('<% if (!item.get("is_unrestricted")) { %>');e.push(" <p>You can remove all access restrictions on this dataset. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Everybody will be able to access the dataset." class="btn btn-default btn-remove-restrictions primary-button" type="button">');e.push(' <span class="fa fa-globe"> Remove restrictions</span>');e.push(" </button>");e.push(" </p>");e.push("<% } else { %>");e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page.");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"> To Clipboard</span></button> ');e.push(" <p>You can make this dataset private to you. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Only you will be able to access the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"> Make Private</span></button>');e.push(" </p>");e.push("<% } %>");e.push("<h4>Roles that can access the dataset</h4>");e.push('<div id="access_perm" class="access_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User has to have <strong>all these roles</strong> in order to access this dataset. Users without access permission <strong>cannot</strong> have other permissions on this dataset. If there are no access roles set on the dataset it is considered <strong>unrestricted</strong>.</div>');e.push("<h4>Roles that can manage permissions on the dataset</h4>");e.push('<div id="manage_perm" class="manage_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can manage permissions of this dataset. If you remove yourself you will loose the ability manage this dataset unless you are an admin.</div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications made on this page" class="btn btn-default toolbtn_save_permissions primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateBulkImportInModal:function(){var e=[];e.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');e.push("Select history: ");e.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');e.push(" <% _.each(histories, function(history) { %>");e.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');e.push(" <% }); %>");e.push("</select>");e.push("</span>");return _.template(e.join(""))},templateAccessSelect:function(){var e=[];e.push('<select id="access_select" multiple>');e.push(" <% _.each(options, function(option) { %>");e.push(' <option value="<%- option.name %>"><%- option.name %></option>');e.push(" <% }); %>");e.push("</select>");return _.template(e.join(""))}});return{LibraryDatasetView:a}}); \ No newline at end of file +define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,b){var a=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_modify_dataset":"enableModification","click .toolbtn_cancel_modifications":"render","click .toolbtn-download-dataset":"downloadDataset","click .toolbtn-import-dataset":"importIntoHistory","click .toolbtn-share-dataset":"shareDataset","click .btn-copy-link-to-clipboard":"copyToClipboard","click .btn-make-private":"makeDatasetPrivate","click .btn-remove-restrictions":"removeDatasetRestrictions","click .toolbtn_save_permissions":"savePermissions","click .toolbtn_save_modifications":"comingSoon",},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchDataset()}},fetchDataset:function(e){this.options=_.extend(this.options,e);this.model=new c.Item({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{if(f.options.show_version){f.fetchVersion()}else{f.render()}}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){this.options=_.extend(this.options,e);$(".tooltip").remove();var f=this.templateDataset();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},fetchVersion:function(e){this.options=_.extend(this.options,e);that=this;if(!this.options.ldda_id){this.render();d.error("Library dataset version requested but no id provided.")}else{this.ldda=new c.Ldda({id:this.options.ldda_id});this.ldda.url=this.ldda.urlRoot+this.model.id+"/versions/"+this.ldda.id;this.ldda.fetch({success:function(){that.renderVersion()},error:function(g,f){if(typeof f.responseJSON!=="undefined"){d.error(f.responseJSON.err_msg)}else{d.error("An error ocurred.")}}})}},renderVersion:function(){$(".tooltip").remove();var e=this.templateVersion();this.$el.html(e({item:this.model,ldda:this.ldda}));$(".peek").html(this.ldda.get("peek"))},enableModification:function(){$(".tooltip").remove();var e=this.templateModifyDataset();this.$el.html(e({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},downloadDataset:function(){var e=(window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/download/uncompressed";var f={ld_ids:this.id};this.processDownload(e,f)},processDownload:function(f,g,h){if(f&&g){g=typeof g=="string"?g:$.param(g);var e="";$.each(g.split("&"),function(){var i=this.split("=");e+='<input type="hidden" name="'+i[0]+'" value="'+i[1]+'" />'});$('<form action="'+f+'" method="'+(h||"post")+'">'+e+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon.")}},importIntoHistory:function(){this.refreshUserHistoriesList(function(e){var f=e.templateBulkImportInModal();e.modal=Galaxy.modal;e.modal.show({closing_events:true,title:"Import into History",body:f({histories:e.histories.models}),buttons:{Import:function(){e.importCurrentIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})},refreshUserHistoriesList:function(f){var e=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(g){if(g.length===0){d.warning("You have to create history first. Click this to do so.","",{onclick:function(){window.location="/"}})}else{f(e)}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg)}else{d.error("An error ocurred.")}}})},importCurrentIntoHistory:function(){var e=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();var f=new c.HistoryItem();f.url=f.urlRoot+e+"/contents";jQuery.getJSON(galaxy_config.root+"history/set_as_current?id="+e);f.save({content:this.id,source:"library"},{success:function(){Galaxy.modal.hide();d.success("Dataset imported. Click this to start analysing it.","",{onclick:function(){window.location="/"}})},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error("Dataset not imported. "+g.responseJSON.err_msg)}else{d.error("An error occured. Dataset not imported. Please try again.")}}})},shareDataset:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(f){this.options=_.extend(this.options,f);$(".tooltip").remove();if(this.options.fetched_permissions!==undefined){if(this.options.fetched_permissions.access_dataset_roles.length===0){this.model.set({is_unrestricted:true})}else{this.model.set({is_unrestricted:false})}}var h=false;if(Galaxy.currUser){h=Galaxy.currUser.isAdmin()}var g=this.templateDatasetPermissions();this.$el.html(g({item:this.model,is_admin:h}));var e=this;if(this.options.fetched_permissions===undefined){$.get((window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/"+e.id+"/permissions?scope=current").done(function(i){e.prepareSelectBoxes({fetched_permissions:i,is_admin:h})}).fail(function(){d.error("An error occurred while attempting to fetch dataset permissions.")})}else{this.prepareSelectBoxes({is_admin:h})}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},prepareSelectBoxes:function(r){this.options=_.extend(this.options,r);var s=this.options.fetched_permissions;var k=this.options.is_admin;var q=this;var m=[];for(var h=0;h<s.access_dataset_roles.length;h++){m.push(s.access_dataset_roles[h]+":"+s.access_dataset_roles[h])}var f=[];for(var h=0;h<s.modify_item_roles.length;h++){f.push(s.modify_item_roles[h]+":"+s.modify_item_roles[h])}var g=[];for(var h=0;h<s.manage_dataset_roles.length;h++){g.push(s.manage_dataset_roles[h]+":"+s.manage_dataset_roles[h])}if(k){var o={minimumInputLength:0,css:"access_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#access_perm"),ajax:{url:(window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:m.join(","),dropdownCssClass:"bigdrop"};var l={minimumInputLength:0,css:"modify_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#modify_perm"),ajax:{url:(window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:f.join(","),dropdownCssClass:"bigdrop"};var p={minimumInputLength:0,css:"manage_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#manage_perm"),ajax:{url:(window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:g.join(","),dropdownCssClass:"bigdrop"};q.accessSelectObject=new b.View(o);q.modifySelectObject=new b.View(l);q.manageSelectObject=new b.View(p)}else{var n=q.templateAccessSelect();$.get((window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/"+q.id+"/permissions?scope=available",function(i){$(".access_perm").html(n({options:i.roles}));q.accessSelectObject=$("#access_select").select2()}).fail(function(){d.error("An error occurred while attempting to fetch dataset permissions.")})}},comingSoon:function(){d.warning("Feature coming soon.")},copyToClipboard:function(){var e=Backbone.history.location.href;if(e.lastIndexOf("/permissions")!==-1){e=e.substr(0,e.lastIndexOf("/permissions"))}window.prompt("Copy to clipboard: Ctrl+C, Enter",e)},makeDatasetPrivate:function(){var e=this;$.post((window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/"+e.id+"/permissions?action=make_private").done(function(f){e.model.set({is_unrestricted:false});e.showPermissions({fetched_permissions:f});d.success("The dataset is now private to you.")}).fail(function(){d.error("An error occurred while attempting to make dataset private.")})},removeDatasetRestrictions:function(){var e=this;$.post((window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/"+e.id+"/permissions?action=remove_restrictions").done(function(f){e.model.set({is_unrestricted:true});e.showPermissions({fetched_permissions:f});d.success("Access to this dataset is now unrestricted.")}).fail(function(){d.error("An error occurred while attempting to make dataset unrestricted.")})},savePermissions:function(e){var n=this;var k=this.accessSelectObject.$el.select2("data");var f=this.manageSelectObject.$el.select2("data");var m=this.modifySelectObject.$el.select2("data");var g=[];var j=[];var l=[];for(var h=k.length-1;h>=0;h--){g.push(k[h].id)}for(var h=f.length-1;h>=0;h--){j.push(f[h].id)}for(var h=m.length-1;h>=0;h--){l.push(m[h].id)}$.post((window.galaxy_config?galaxy_config.root:"/")+"api/libraries/datasets/"+n.id+"/permissions?action=set_permissions",{"access_ids[]":g,"manage_ids[]":j,"modify_ids[]":l,}).done(function(i){n.showPermissions({fetched_permissions:i});d.success("Permissions saved.")}).fail(function(){d.error("An error occurred while attempting to set dataset permissions.")})},templateDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');e.push(' <% if (item.get("can_user_modify")) { %>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library item" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(" <% } %>");e.push(' <% if (item.get("can_user_manage")) { %>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Manage permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(" <% } %>");e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<% if (item.get("is_unrestricted")) { %>');e.push(' <div class="alert alert-info">');e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"></span> To Clipboard</span></button> ');e.push(" </div>");e.push("<% } %>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push(' <% if (item.get("has_versions")) { %>');e.push(" <div>");e.push(" <h3>Expired versions:</h3>");e.push(" <ul>");e.push(' <% _.each(item.get("expired_versions"), function(version) { %>');e.push(' <li><a title="See details of this version" href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/versions/<%- version[0] %>"><%- version[1] %></a></li>');e.push(" <% }) %>");e.push(" <ul>");e.push(" </div>");e.push(" <% } %>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateVersion:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go to latest dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-caret-left fa-lg"></span> Latest dataset</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push(' <div class="alert alert-warning">This is an expired version of the library dataset: <%= _.escape(item.get("name")) %></div>');e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(ldda.id) %>">Name</th>');e.push(' <td><%= _.escape(ldda.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (ldda.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(ldda.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(ldda.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(ldda.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(ldda.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(ldda.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateModifyDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push('<p>For more editing options please import the dataset to history and use "Edit attributes" on it.</p>');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><input class="input_dataset_name form-control" type="text" placeholder="name" value="<%= _.escape(item.get("name")) %>"></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(' <tr scope="row">');e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <% if (item.get("metadata_comment_lines") === "") { %>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" <% } else { %>");e.push(' <td scope="row">unknown</td>');e.push(" <% } %>");e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" </table>");e.push("<div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push("</div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateDatasetPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to containing folder" class="btn btn-default primary-button" type="button"><span class="fa fa-folder-open-o"></span> Containing Folder</span></button></a>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go back to dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-file-o"></span> Dataset Details</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<h1>Dataset: <%= _.escape(item.get("name")) %></h1>');e.push('<div class="alert alert-warning">');e.push("<% if (is_admin) { %>");e.push("You are logged in as an <strong>administrator</strong> therefore you can manage any dataset on this Galaxy instance. Please make sure you understand the consequences.");e.push("<% } else { %>");e.push("You can assign any number of roles to any of the following permission types. However please read carefully the implications of such actions.");e.push("<% } %>");e.push("</div>");e.push('<div class="dataset_table">');e.push("<h2>Library-related permissions</h2>");e.push("<h4>Roles that can modify the library item</h4>");e.push('<div id="modify_perm" class="modify_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can modify name, metadata, and other information about this library item.</div>');e.push("<hr/>");e.push("<h2>Dataset-related permissions</h2>");e.push('<div class="alert alert-warning">Changes made below will affect <strong>every</strong> library item that was created from this dataset and also every history this dataset is part of.</div>');e.push('<% if (!item.get("is_unrestricted")) { %>');e.push(" <p>You can remove all access restrictions on this dataset. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Everybody will be able to access the dataset." class="btn btn-default btn-remove-restrictions primary-button" type="button">');e.push(' <span class="fa fa-globe"> Remove restrictions</span>');e.push(" </button>");e.push(" </p>");e.push("<% } else { %>");e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page.");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"> To Clipboard</span></button> ');e.push(" <p>You can make this dataset private to you. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Only you will be able to access the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"> Make Private</span></button>');e.push(" </p>");e.push("<% } %>");e.push("<h4>Roles that can access the dataset</h4>");e.push('<div id="access_perm" class="access_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User has to have <strong>all these roles</strong> in order to access this dataset. Users without access permission <strong>cannot</strong> have other permissions on this dataset. If there are no access roles set on the dataset it is considered <strong>unrestricted</strong>.</div>');e.push("<h4>Roles that can manage permissions on the dataset</h4>");e.push('<div id="manage_perm" class="manage_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can manage permissions of this dataset. If you remove yourself you will loose the ability manage this dataset unless you are an admin.</div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications made on this page" class="btn btn-default toolbtn_save_permissions primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateBulkImportInModal:function(){var e=[];e.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');e.push("Select history: ");e.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');e.push(" <% _.each(histories, function(history) { %>");e.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');e.push(" <% }); %>");e.push("</select>");e.push("</span>");return _.template(e.join(""))},templateAccessSelect:function(){var e=[];e.push('<select id="access_select" multiple>');e.push(" <% _.each(options, function(option) { %>");e.push(' <option value="<%- option.name %>"><%- option.name %></option>');e.push(" <% }); %>");e.push("</select>");return _.template(e.join(""))}});return{LibraryDatasetView:a}}); \ No newline at end of file diff -r 6395e70351435911f7ab75863c1b48b54e20a919 -r 0aa4dd8af7cf8303ef9dd9af95c2e2676854ecca static/scripts/packed/mvc/library/library-folder-view.js --- a/static/scripts/packed/mvc/library/library-folder-view.js +++ b/static/scripts/packed/mvc/library/library-folder-view.js @@ -1,1 +1,1 @@ -define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,a){var b=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_save_permissions":"savePermissions"},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchFolder()}},fetchFolder:function(e){this.options=_.extend(this.options,e);this.model=new c.FolderAsModel({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{f.render()}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){$(".tooltip").remove();this.options=_.extend(this.options,e);var f=this.templateFolder();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},shareFolder:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(f){this.options=_.extend(this.options,f);$(".tooltip").remove();var h=false;if(Galaxy.currUser){h=Galaxy.currUser.isAdmin()}var g=this.templateFolderPermissions();this.$el.html(g({folder:this.model,is_admin:h}));var e=this;if(this.options.fetched_permissions===undefined){$.get("/api/folders/"+e.id+"/permissions?scope=current").done(function(i){e.prepareSelectBoxes({fetched_permissions:i})}).fail(function(){d.error("An error occurred while attempting to fetch folder permissions.")})}else{this.prepareSelectBoxes({})}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},_serializeRoles:function(g){var e=[];for(var f=0;f<g.length;f++){e.push(g[f]+":"+g[f])}return e},prepareSelectBoxes:function(h){this.options=_.extend(this.options,h);var f=this.options.fetched_permissions;var g=this;var i=this._serializeRoles(f.add_library_item_role_list);var j=this._serializeRoles(f.manage_folder_role_list);var e=this._serializeRoles(f.modify_folder_role_list);g.addSelectObject=new a.View(this._createSelectOptions(this,"add_perm",i,false));g.manageSelectObject=new a.View(this._createSelectOptions(this,"manage_perm",j,false));g.modifySelectObject=new a.View(this._createSelectOptions(this,"modify_perm",e,false))},_createSelectOptions:function(e,j,h){var i={minimumInputLength:0,css:j,multiple:true,placeholder:"Click to select a role",container:e.$el.find("#"+j),ajax:{url:"/api/folders/"+e.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(k,l){return{q:k,page_limit:10,page:l}},results:function(m,l){var k=(l*10)<m.total;return{results:m.roles,more:k}}},formatResult:function f(k){return k.name+" type: "+k.type},formatSelection:function g(k){return k.name},initSelection:function(k,m){var l=[];$(k.val().split(",")).each(function(){var n=this.split(":");l.push({id:n[1],name:n[1]})});m(l)},initialData:h.join(","),dropdownCssClass:"bigdrop"};return i},comingSoon:function(){d.warning("Feature coming soon.")},copyToClipboard:function(){var e=Backbone.history.location.href;if(e.lastIndexOf("/permissions")!==-1){e=e.substr(0,e.lastIndexOf("/permissions"))}window.prompt("Copy to clipboard: Ctrl+C, Enter",e)},_extractIds:function(e){ids_list=[];for(var f=e.length-1;f>=0;f--){ids_list.push(e[f].id)}return ids_list},savePermissions:function(h){var g=this;var e=this._extractIds(this.addSelectObject.$el.select2("data"));var i=this._extractIds(this.manageSelectObject.$el.select2("data"));var f=this._extractIds(this.modifySelectObject.$el.select2("data"));$.post("/api/folders/"+g.id+"/permissions?action=set_permissions",{"add_ids[]":e,"manage_ids[]":i,"modify_ids[]":f,}).done(function(j){g.showPermissions({fetched_permissions:j});d.success("Permissions saved.")}).fail(function(){d.error("An error occurred while attempting to set folder permissions.")})},templateFolder:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library item" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Manage permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push(" </div>");e.push(" <p>");e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"></span> To Clipboard</span></button> ');e.push(" </p>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateFolderPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#/folders/<%= folder.get("parent_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to the parent folder" class="btn btn-default primary-button" type="button"><span class="fa fa-caret-left fa-lg"></span> Parent folder</span></button></a>');e.push(" </div>");e.push('<h1>Folder: <%= _.escape(folder.get("name")) %></h1>');e.push('<div class="alert alert-warning">');e.push("<% if (is_admin) { %>");e.push("You are logged in as an <strong>administrator</strong> therefore you can manage any folder on this Galaxy instance. Please make sure you understand the consequences.");e.push("<% } else { %>");e.push("You can assign any number of roles to any of the following permission types. However please read carefully the implications of such actions.");e.push("<% }%>");e.push("</div>");e.push('<div class="dataset_table">');e.push("<h2>Folder permissions</h2>");e.push("<h4>Roles that can manage permissions on this folder</h4>");e.push('<div id="manage_perm" class="manage_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can manage permissions on this folder.</div>');e.push("<h4>Roles that can add items to this folder</h4>");e.push('<div id="add_perm" class="add_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can add items to this folder (folders and datasets).</div>');e.push("<h4>Roles that can modify this folder</h4>");e.push('<div id="modify_perm" class="modify_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can modify this folder (name, etc.).</div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_permissions primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("</div>");e.push("</div>");return _.template(e.join(""))}});return{FolderView:b}}); \ No newline at end of file +define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,a){var b=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_save_permissions":"savePermissions"},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchFolder()}},fetchFolder:function(e){this.options=_.extend(this.options,e);this.model=new c.FolderAsModel({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{f.render()}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){$(".tooltip").remove();this.options=_.extend(this.options,e);var f=this.templateFolder();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},shareFolder:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(f){this.options=_.extend(this.options,f);$(".tooltip").remove();var h=false;if(Galaxy.currUser){h=Galaxy.currUser.isAdmin()}var g=this.templateFolderPermissions();this.$el.html(g({folder:this.model,is_admin:h}));var e=this;if(this.options.fetched_permissions===undefined){$.get((window.galaxy_config?galaxy_config.root:"/")+"api/folders/"+e.id+"/permissions?scope=current").done(function(i){e.prepareSelectBoxes({fetched_permissions:i})}).fail(function(){d.error("An error occurred while attempting to fetch folder permissions.")})}else{this.prepareSelectBoxes({})}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},_serializeRoles:function(g){var e=[];for(var f=0;f<g.length;f++){e.push(g[f]+":"+g[f])}return e},prepareSelectBoxes:function(h){this.options=_.extend(this.options,h);var f=this.options.fetched_permissions;var g=this;var i=this._serializeRoles(f.add_library_item_role_list);var j=this._serializeRoles(f.manage_folder_role_list);var e=this._serializeRoles(f.modify_folder_role_list);g.addSelectObject=new a.View(this._createSelectOptions(this,"add_perm",i,false));g.manageSelectObject=new a.View(this._createSelectOptions(this,"manage_perm",j,false));g.modifySelectObject=new a.View(this._createSelectOptions(this,"modify_perm",e,false))},_createSelectOptions:function(e,j,h){var i={minimumInputLength:0,css:j,multiple:true,placeholder:"Click to select a role",container:e.$el.find("#"+j),ajax:{url:(window.galaxy_config?galaxy_config.root:"/")+"api/folders/"+e.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(k,l){return{q:k,page_limit:10,page:l}},results:function(m,l){var k=(l*10)<m.total;return{results:m.roles,more:k}}},formatResult:function f(k){return k.name+" type: "+k.type},formatSelection:function g(k){return k.name},initSelection:function(k,m){var l=[];$(k.val().split(",")).each(function(){var n=this.split(":");l.push({id:n[1],name:n[1]})});m(l)},initialData:h.join(","),dropdownCssClass:"bigdrop"};return i},comingSoon:function(){d.warning("Feature coming soon.")},copyToClipboard:function(){var e=Backbone.history.location.href;if(e.lastIndexOf("/permissions")!==-1){e=e.substr(0,e.lastIndexOf("/permissions"))}window.prompt("Copy to clipboard: Ctrl+C, Enter",e)},_extractIds:function(e){ids_list=[];for(var f=e.length-1;f>=0;f--){ids_list.push(e[f].id)}return ids_list},savePermissions:function(h){var g=this;var e=this._extractIds(this.addSelectObject.$el.select2("data"));var i=this._extractIds(this.manageSelectObject.$el.select2("data"));var f=this._extractIds(this.modifySelectObject.$el.select2("data"));$.post((window.galaxy_config?galaxy_config.root:"/")+"api/folders/"+g.id+"/permissions?action=set_permissions",{"add_ids[]":e,"manage_ids[]":i,"modify_ids[]":f,}).done(function(j){g.showPermissions({fetched_permissions:j});d.success("Permissions saved.")}).fail(function(){d.error("An error occurred while attempting to set folder permissions.")})},templateFolder:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library item" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Manage permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push(" </div>");e.push(" <p>");e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"></span> To Clipboard</span></button> ');e.push(" </p>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateFolderPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#/folders/<%= folder.get("parent_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to the parent folder" class="btn btn-default primary-button" type="button"><span class="fa fa-caret-left fa-lg"></span> Parent folder</span></button></a>');e.push(" </div>");e.push('<h1>Folder: <%= _.escape(folder.get("name")) %></h1>');e.push('<div class="alert alert-warning">');e.push("<% if (is_admin) { %>");e.push("You are logged in as an <strong>administrator</strong> therefore you can manage any folder on this Galaxy instance. Please make sure you understand the consequences.");e.push("<% } else { %>");e.push("You can assign any number of roles to any of the following permission types. However please read carefully the implications of such actions.");e.push("<% }%>");e.push("</div>");e.push('<div class="dataset_table">');e.push("<h2>Folder permissions</h2>");e.push("<h4>Roles that can manage permissions on this folder</h4>");e.push('<div id="manage_perm" class="manage_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can manage permissions on this folder.</div>');e.push("<h4>Roles that can add items to this folder</h4>");e.push('<div id="add_perm" class="add_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can add items to this folder (folders and datasets).</div>');e.push("<h4>Roles that can modify this folder</h4>");e.push('<div id="modify_perm" class="modify_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can modify this folder (name, etc.).</div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_permissions primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("</div>");e.push("</div>");return _.template(e.join(""))}});return{FolderView:b}}); \ No newline at end of file This diff is so big that we needed to truncate the remainder. Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.