2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/737f78bb4a45/
Changeset: 737f78bb4a45
User: carlfeberhard
Date: 2014-08-26 18:59:15
Summary: UI, Dataset choice control: add DatasetChoiceModal for choosing single or
multiple datasets, add DatasetChoice and MultiDatasetChoice for displaying and activating
selection modal from within a page; correct lookup of galaxy_config in dataset-model; add
ListPanel for displaying collections of ListViews; add DatasetListPanel for displaying
collections of generic datasets; add default no-op localizer (_l) to ui.js until that file
is AMD; factor out icon-btn.less from history.less; remove make_popup_menus in default
expandable behaviors
Affected #: 17 files
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/mvc/base-mvc.js
--- a/static/scripts/mvc/base-mvc.js
+++ b/static/scripts/mvc/base-mvc.js
@@ -1,6 +1,7 @@
define([
- 'utils/add-logging'
-], function( addLogging ){
+ 'utils/add-logging',
+ 'utils/localization'
+], function( addLogging, _l ){
//ASSUMES: backbone
//==============================================================================
/** @class Mixin to add logging capabilities to an object.
@@ -390,6 +391,7 @@
/** are the details of this view expanded/shown or not? */
this.expanded = attributes.expanded || false;
//this.log( '\t expanded:', this.expanded );
+ this.fxSpeed = attributes.fxSpeed || this.fxSpeed;
},
// ........................................................................ render
main
@@ -451,7 +453,7 @@
_setUpBehaviors : function( $where ){
$where = $where || this.$el;
// set up canned behavior on children (bootstrap, popupmenus, editable_text,
etc.)
- make_popup_menus( $where );
+ //make_popup_menus( $where );
$where.find( '[title]' ).tooltip({ placement : 'bottom' });
},
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/mvc/dataset/dataset-choice.js
--- /dev/null
+++ b/static/scripts/mvc/dataset/dataset-choice.js
@@ -0,0 +1,442 @@
+define([
+ 'mvc/dataset/dataset-model',
+ 'mvc/dataset/dataset-list',
+ 'mvc/ui/ui-modal',
+ 'mvc/base-mvc',
+ 'utils/localization'
+], function( DATASET, DATASET_LIST, MODAL, BASE_MVC, _l ){
+/* ============================================================================
+TODO:
+ does this really work with mixed contents?
+ Single dataset choice: allow none?
+ tooltips rendered *behind* modal
+ collection selector
+ better handling when no results returned from filterDatasetJSON
+ pass optional subtitle from choice display to modal
+ onfirstclick
+ drop target
+ return modal with promise?
+
+ auto showing the modal may not be best
+
+ add hidden inputs
+ // cut1 on single dataset (17 in the list)
+ __switch_default__ select_single
+ input 17
+
+ // cut1 on two datasets
+ __switch_default__ select_single
+ input|__multirun__ 13
+ input|__multirun__ 15
+
+ // cut1 on a collection
+ __switch_default__ select_collection
+ input|__collection_multirun__ f2db41e1fa331b3e
+
+============================================================================ */
+/** Filters an array of dataset plain JSON objs.
+ */
+function _filterDatasetJSON( datasetJSON, where, datasetsOnly ){
+//TODO: replace with _.matches (underscore 1.6.0)
+ function matches( obj, toMatch ){
+ for( var key in toMatch ){
+ if( toMatch.hasOwnProperty( key ) ){
+ if( obj[ key ] !== toMatch[ key ] ){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ return datasetJSON.filter( function( json ){
+ return ( !json.deleted && json.visible )
+ && ( !datasetsOnly || json.collection_type === undefined )
+ && ( matches( json, where ) );
+ });
+}
+
+// ============================================================================
+/** Given an array of plain JSON objs rep. datasets, show a modal allowing a choice
+ * of one or more of those datasets.
+ *
+ * Pass:
+ * an array of plain JSON objects representing allowed dataset choices
+ * a map of options (see below)
+ *
+ * Options:
+ * datasetsOnly: T: display only datasets, F: datasets + dataset collections
+ * where: a map of attributes available choices *must have* (defaults to {
state: 'ok' })
+ * multiselect: T: user can select more than one, F: only one
+ * selected: array of dataset ids to make them selected by default
+ *
+ * @example:
+ * var datasetJSON = // from ajax or bootstrap
+ * // returns a jQuery promise (that 'fail's only if no datasets are found
matching 'where' below)
+ * var choice = new DatasetChoiceModal( datasetJSON, {
+ * datasetsOnly : false,
+ * where : { state: 'ok', data_type: 'bed', ... },
+ * multiselect : true,
+ * selected : [ 'df7a1f0c02a5b08e', 'abcdef0123456789' ]
+ *
+ * }).done( function( json ){
+ * if( json ){
+ * console.debug( json );
+ * // returned choice will always be an array (single or multi)
+ * // [{ <selected dataset JSON 1>, <selected dataset JSON 2>,
... }]
+ * // ... do stuff
+ * } else {
+ * // json will === null if the user cancelled selection
+ * console.debug( 'cancelled' );
+ * }
+ * });
+ */
+var DatasetChoiceModal = function( datasetJSON, options ){
+
+ // option defaults
+ options = _.defaults( options || {}, {
+ // show datasets or datasets and collections
+ datasetsOnly : true,
+ // map of attributes to filter datasetJSON by
+ where : { state: 'ok' },
+ // select more than one dataset?
+ multiselect : false,
+ // any dataset ids that will display as already selected
+ selected : []
+ });
+ // default title should depend on multiselect
+ options.title = options.title ||
+ ( options.multiselect? _l( 'Choose datasets:' ): _l( 'Choose a
dataset:' ) );
+
+ var modal, list, buttons,
+ promise = jQuery.Deferred(),
+ filterFn = options.filter || _filterDatasetJSON;
+
+ // filter the given datasets and if none left return a rejected promise for use with
fail()
+ datasetJSON = filterFn( datasetJSON, options.where, options.datasetsOnly );
+ if( !datasetJSON.length ){
+ return promise.reject( 'No matches found' );
+ }
+
+ // resolve the returned promise with the json of the selected datasets
+ function resolveWithSelected(){
+ promise.resolve( list.getSelectedModels().map( function( model ){
+ return model.toJSON();
+ }));
+ }
+ // if multiselect - add a button for the user to complete the changes
+ if( options.multiselect ){
+ buttons = {};
+ buttons[ _l( 'Ok' ) ] = resolveWithSelected;
+ }
+
+ // create a full-height modal that's cancellable, remove unneeded elements and
styles
+ modal = new MODAL.View({
+ height : 'auto',
+ buttons : buttons,
+ closing_events : true,
+ closing_callback : function(){ promise.resolve( null ); },
+ body : [
+ '<div class="list-panel"></div>'
+ ].join('')
+ });
+ modal.$( '.modal-header' ).remove();
+ modal.$( '.modal-footer' ).css( 'margin-top', '0px' );
+
+ // attach a dataset list (of the filtered datasets) to that modal that's
selectable
+ list = new DATASET_LIST.DatasetList({
+ title : options.title,
+ subtitle : options.subtitle || _l([
+//TODO: as option
+ 'Click the checkboxes on the right to select datasets. ',
+ 'Click the datasets names to see their details. '
+ ].join('')),
+ el : modal.$body.find( '.list-panel' ),
+ selecting : true,
+ selected : options.selected,
+ collection : new DATASET.DatasetAssociationCollection( datasetJSON )
+ });
+
+ // when the list is rendered, show the modal (also add a specifying class for css)
+ list.once( 'rendered:initial', function(){
+ modal.show();
+ modal.$el.addClass( 'dataset-choice-modal' );
+ });
+ if( !options.multiselect ){
+ // if single select, remove the all/none list actions from the panel
+ list.on( 'rendered', function(){
+ list.$( '.list-actions' ).hide();
+ });
+ // if single select, immediately resolve on a single selection
+ list.on( 'view:selected', function( view ){
+ promise.resolve([ view.model.toJSON() ]);
+ });
+ }
+ list.render( 0 );
+
+ // return the promise, and on any resolution close the modal
+ return promise.always( function(){
+ modal.hide();
+ });
+};
+
+
+// ============================================================================
+/** Activator for single dataset selection modal and display of the selected dataset.
+ * The activator/display will show as a single div and, when a dataset is selected,
+ * show the name and details of the selected dataset.
+ *
+ * When clicked the div will generate a DatasetChoiceModal of the available
choices.
+ *
+ * Options:
+ * datasetJSON: array of plain json objects representing allowed choices
+ * datasetsOnly: T: only show datasets in the allowed choices, F: datasets +
collections
+ * where: map of attributes to filter datasetJSON by (e.g. { data_type:
'bed' })
+ * label: the label/prompt displayed
+ * selected: array of dataset ids that will show as already selected in the
control
+ *
+ * @example:
+ * var choice1 = new DATASET_CHOICE.DatasetChoice({
+ * datasetJSON : datasetJSON,
+ * label : 'Input dataset',
+ * selected : [ 'df7a1f0c02a5b08e' ]
+ * });
+ * $( 'body' ).append( choice1.render().$el )
+ *
+ * Listen to the DatasetChoice to react to changes in the user's choice/selection:
+ * @example:
+ * choice1.on( 'selected', function( chooser, selectionJSONArray ){
+ * // ... do stuff with new selections
+ * });
+ */
+var DatasetChoice = Backbone.View.extend( BASE_MVC.LoggableMixin ).extend({
+
+ //logger : console,
+
+ className : 'dataset-choice',
+
+ /** set up defaults, options, and listeners */
+ initialize : function( attributes ){
+ this.debug( this + '(DatasetChoice).initialize:', attributes );
+
+ this.label = attributes.label !== undefined? _l( attributes.label ) :
'';
+ this.where = attributes.where;
+ this.datasetsOnly = attributes.datasetsOnly !== undefined?
attributes.datasetsOnly: true;
+
+ this.datasetJSON = attributes.datasetJSON || [];
+ this.selected = attributes.selected || [];
+
+ this._setUpListeners();
+ },
+
+ /** add any (bbone) listeners */
+ _setUpListeners : function(){
+ //this.on( 'all', function(){
+ // this.log( this + '', arguments );
+ //});
+ },
+
+ /** render the view */
+ render : function(){
+ var json = this.toJSON();
+ this.$el.html( this._template( json ) );
+ this.$( '.selected' ).replaceWith( this._renderSelected( json ) );
+ return this;
+ },
+
+ /** return plain html for the overall control */
+ _template : function( json ){
+ return _.template([
+ '<label>',
+ '<span class="prompt"><%= json.label
%></span>',
+ '<div class="selected"></div>',
+ '</label>'
+ ].join(''), { json: json });
+ },
+
+ /** return jQ DOM for the selected dataset (only one) */
+ _renderSelected : function( json ){
+ if( json.selected.length ){
+//TODO: break out?
+ return $( _.template([
+ '<div class="selected">',
+ '<span class="title"><%= selected.hid %>:
<%= selected.name %></span>',
+ '<span class="subtitle">',
+ '<i><%= selected.misc_blurb %></i>',
+ '<i>', _l( 'format' ) + ': ',
'<%= selected.data_type %></i>',
+ '<i><%= selected.misc_info %></i>',
+ '</span>',
+ '</div>'
+ ].join( '' ), { selected: json.selected[0] }));
+ }
+ return $([
+ '<span class="none-selected-msg">(',
+ _l( 'click to select a dataset' ),
+ ')</span>'
+ ].join( '' ));
+ },
+
+//TODO:?? why not just pass in view?
+ /** return a plain JSON object with both the view and dataset attributes */
+ toJSON : function(){
+ var chooser = this;
+ return {
+ label : chooser.label,
+ datasets : chooser.datasetJSON,
+ selected : _.compact( _.map( chooser.selected, function( id ){
+ return _.findWhere( chooser.datasetJSON, { id: id });
+ }))
+ };
+ },
+
+ /** event map: when to open the modal */
+ events : {
+ // the whole thing functions as a button
+ 'click' : 'chooseWithModal'
+ },
+
+//TODO:?? modal to prop of this?
+//TODO:?? should be able to handle 'none selectable' on initialize
+ /** open the modal and handle the promise representing the user's choice
+ * @fires 'selected' when the user selects dataset(s) - passed full json of
the selected datasets
+ * @fires 'cancelled' when the user clicks away/closes the modal (no
selection made) - passed this
+ * @fires 'error' if the modal has no selectable datasets based on
this.where - passed this and other args
+ */
+ chooseWithModal : function(){
+ var chooser = this;
+
+ return this._createModal()
+ .done( function( json ){
+ if( json ){
+ chooser.selected = _.pluck( json, 'id' );
+ chooser.trigger( 'selected', chooser, json );
+ chooser.render();
+
+ } else {
+ chooser.trigger( 'cancelled', chooser );
+ }
+ })
+
+ .fail( function(){
+ chooser.trigger( 'error', chooser, arguments );
+ });
+ },
+
+ /** create and return the modal to use for choosing */
+ _createModal : function(){
+ return new DatasetChoiceModal( this.datasetJSON, this._getModalOptions() );
+ },
+
+ /** return a plain JSON containing the options to pass to the modal */
+ _getModalOptions : function(){
+ return {
+ title : this.label,
+ multiselect : false,
+ selected : this.selected,
+ where : this.where,
+ datasetsOnly : this.datasetsOnly
+ };
+ },
+
+ // ------------------------------------------------------------------------ misc
+ /** string rep */
+ toString : function(){
+ return 'DatasetChoice(' + this.selected + ')';
+ }
+});
+
+
+// ============================================================================
+/** Activator for multiple dataset selection modal and display of the selected datasets.
+ * The activator/display will show as a table of all choices.
+ *
+ * See DatasetChoice (above) for example usage.
+ *
+ * Additional options:
+ * showHeaders: T: show headers for selected dataset attributes in the display
table
+ * cells: map of attribute keys -> Human readable/localized column
headers
+ * (e.g. { data_type: _l( 'Format' ) }) - defaults are listed below
+ */
+var MultiDatasetChoice = DatasetChoice.extend({
+
+ className : DatasetChoice.prototype.className + ' multi',
+
+ /** default (dataset attribute key -> table header text) map of what cells to
display in the table */
+ cells : {
+ hid : _l( 'History #' ),
+ name : _l( 'Name' ),
+ misc_blurb : _l( 'Summary' ),
+ data_type : _l( 'Format' ),
+ genome_build : _l( 'Genome' ),
+ tags : _l( 'Tags' ),
+ annotation : _l( 'Annotation' )
+ },
+
+ /** in this override, add the showHeaders and cells options */
+ initialize : function( attributes ){
+ this.showHeaders = attributes.showHeaders !== undefined? attributes.showHeaders :
true;
+ this.cells = attributes.cells || this.cells;
+ DatasetChoice.prototype.initialize.call( this, attributes );
+ },
+
+ /** in this override, display the selected datasets as a table with optional headers
*/
+ _renderSelected : function( json ){
+ if( json.selected.length ){
+ return $( _.template([
+ '<table class="selected">',
+ '<% if( json.showHeaders ){ %>',
+ '<thead><tr>',
+ '<% _.map( json.cells, function( val, key ){
%>',
+ '<th><%= val %></th>',
+ '<% }); %>',
+ '</tr></thead>',
+ '<% } %>',
+ '<tbody>',
+ '<% _.map( json.selected, function( selected ){
%>',
+ '<tr>',
+ '<% _.map( json.cells, function( val, key ){
%>',
+ '<td class="cell-<%= key
%>"><%= selected[ key ] %></td>',
+ '<% }) %>',
+ '</tr>',
+ '<% }); %>',
+ '</tbody>',
+ '</table>'
+ ].join( '' ), { json: json }));
+ }
+ return $([
+ '<span class="none-selected-msg">(',
+ _l( 'click to select a dataset' ),
+ ')</span>'
+ ].join( '' ));
+ },
+
+ /** in this override, send the showHeaders and cells options as well */
+ toJSON : function(){
+ return _.extend( DatasetChoice.prototype.toJSON.call( this ), {
+ showHeaders : this.showHeaders,
+ cells : this.cells
+ });
+ },
+
+ /** in this override, set multiselect to true */
+ _getModalOptions : function(){
+ return _.extend( DatasetChoice.prototype._getModalOptions.call( this ), {
+ multiselect : true
+ });
+ },
+
+ // ------------------------------------------------------------------------ misc
+ /** string rep */
+ toString : function(){
+ return 'DatasetChoice(' + this.selected + ')';
+ }
+});
+
+
+// ============================================================================
+ return {
+ DatasetChoiceModal : DatasetChoiceModal,
+ DatasetChoice : DatasetChoice,
+ MultiDatasetChoice : MultiDatasetChoice
+ };
+});
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/mvc/dataset/dataset-li.js
--- a/static/scripts/mvc/dataset/dataset-li.js
+++ b/static/scripts/mvc/dataset/dataset-li.js
@@ -42,14 +42,14 @@
/** event listeners */
_setUpListeners : function(){
//TODO:?? may want to move this to ListItemView (although this is only needed in the
*narrow* panel views (current))
- // hide the primary actions in the title bar when selectable
+ // hide the primary actions in the title bar when selectable and narrow
this.on( 'selectable', function( isSelectable ){
if( isSelectable ){
this.$( '.primary-actions' ).hide();
} else {
this.$( '.primary-actions' ).show();
}
- });
+ }, this );
// re-rendering on any model changes
this.model.on( 'change', function( model, options ){
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/mvc/dataset/dataset-list.js
--- /dev/null
+++ b/static/scripts/mvc/dataset/dataset-list.js
@@ -0,0 +1,45 @@
+define([
+ "mvc/dataset/list-panel",
+ "mvc/dataset/dataset-li",
+ "mvc/base-mvc",
+ "utils/localization"
+], function( LIST_PANEL, DATASET_LI, BASE_MVC, _l ){
+/* =============================================================================
+TODO:
+
+============================================================================= */
+var _super = LIST_PANEL.ListPanel;
+/** @class non-editable, read-only View/Controller for a list of datasets.
+ */
+var DatasetList = _super.extend(
+/** @lends DatasetList.prototype */{
+
+ /** logger used to record this.log messages, commonly set to console */
+ //logger : console,
+
+ /** class to use for constructing the sub-views */
+ viewClass : DATASET_LI.DatasetListItemView,
+ className : _super.prototype.className + ' dataset-list',
+
+ /** string to no hdas match the search terms */
+ noneFoundMsg : _l( 'No matching datasets found' ),
+
+ // ......................................................................... SET UP
+ /** Set up the view, set up storage, bind listeners to HistoryContents events
+ * @param {Object} attributes optional settings for the panel
+ */
+ initialize : function( attributes ){
+ _super.prototype.initialize.call( this, attributes );
+ },
+
+ /** Return a string rep of the history */
+ toString : function(){
+ return 'DatasetList(' + this.collection + ')';
+ }
+});
+
+//==============================================================================
+ return {
+ DatasetList : DatasetList
+ };
+});
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/mvc/dataset/dataset-model.js
--- a/static/scripts/mvc/dataset/dataset-model.js
+++ b/static/scripts/mvc/dataset/dataset-model.js
@@ -75,7 +75,7 @@
'meta_download' : 'dataset/get_metadata_file?hda_id=' + id +
'&metadata_name='
};
//TODO: global
- var root = ( galaxy_config && galaxy_config.root )?( galaxy_config.root
):( '/' );
+ var root = ( window.galaxy_config && galaxy_config.root )?(
galaxy_config.root ):( '/' );
_.each( urls, function( value, key ){
urls[ key ] = root + value;
});
@@ -229,7 +229,210 @@
//==============================================================================
+/** @class Backbone collection for dataset associations.
+ */
+var DatasetAssociationCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin
).extend(
+/** @lends HistoryContents.prototype */{
+ model : DatasetAssociation,
+
+ /** logger used to record this.log messages, commonly set to console */
+ //logger : console,
+
+ /** root api url */
+ urlRoot : (( window.galaxy_config && galaxy_config.root )?(
galaxy_config.root ):( '/' ))
+ + 'api/datasets',
+
+ // ........................................................................ common
queries
+ /** Get the ids of every item in this collection
+ * @returns array of encoded ids
+ */
+ ids : function(){
+ return this.map( function( item ){ return item.get('id'); });
+ },
+
+ /** Get contents that are not ready
+ * @returns array of content models
+ */
+ notReady : function(){
+ return this.filter( function( content ){
+ return !content.inReadyState();
+ });
+ },
+
+// /** Get the id of every model in this collection not in a 'ready' state
(running).
+// * @returns an array of model ids
+// */
+// running : function(){
+// var idList = [];
+// this.each( function( item ){
+// var isRunning = !item.inReadyState();
+// if( isRunning ){
+////TODO: is this still correct since type_id
+// idList.push( item.get( 'id' ) );
+// }
+// });
+// return idList;
+// },
+
+ /** return true if any datasets don't have details */
+ haveDetails : function(){
+ return this.all( function( dataset ){ return dataset.hasDetails(); });
+ },
+
+ // ........................................................................ ajax
+ ///** fetch detailed model data for all datasets in this collection */
+ //fetchAllDetails : function( options ){
+ // options = options || {};
+ // var detailsFlag = { details: 'all' };
+ // options.data = ( options.data )?( _.extend( options.data, detailsFlag ) ):(
detailsFlag );
+ // return this.fetch( options );
+ //},
+
+ /** using a queue, perform ajaxFn on each of the models in this collection */
+ ajaxQueue : function( ajaxFn, options ){
+ var deferred = jQuery.Deferred(),
+ startingLength = this.length,
+ responses = [];
+
+ if( !startingLength ){
+ deferred.resolve([]);
+ return deferred;
+ }
+
+ // use reverse order (stylistic choice)
+ var ajaxFns = this.chain().reverse().map( function( dataset, i ){
+ return function(){
+ var xhr = ajaxFn.call( dataset, options );
+ // if successful, notify using the deferred to allow tracking progress
+ xhr.done( function( response ){
+ deferred.notify({ curr: i, total: startingLength, response: response,
model: dataset });
+ });
+ // (regardless of previous error or success) if not last ajax call, shift
and call the next
+ // if last fn, resolve deferred
+ xhr.always( function( response ){
+ responses.push( response );
+ if( ajaxFns.length ){
+ ajaxFns.shift()();
+ } else {
+ deferred.resolve( responses );
+ }
+ });
+ };
+ }).value();
+ // start the queue
+ ajaxFns.shift()();
+
+ return deferred;
+ },
+
+ // ........................................................................
sorting/filtering
+ /** return a new collection of datasets whose attributes contain the substring
matchesWhat */
+ matches : function( matchesWhat ){
+ return this.filter( function( dataset ){
+ return dataset.matches( matchesWhat );
+ });
+ },
+
+ // ........................................................................ misc
+ /** override to get a correct/smarter merge when incoming data is partial */
+ set : function( models, options ){
+ // arrrrrrrrrrrrrrrrrg...
+ // (e.g. stupid backbone)
+ // w/o this partial models from the server will fill in missing data with model
defaults
+ // and overwrite existing data on the client
+ // see Backbone.Collection.set and _prepareModel
+ var collection = this;
+ models = _.map( models, function( model ){
+ if( !collection.get( model.id ) ){ return model; }
+
+ // merge the models _BEFORE_ calling the superclass version
+ var merged = existing.toJSON();
+ _.extend( merged, model );
+ return merged;
+ });
+ // now call superclass when the data is filled
+ Backbone.Collection.prototype.set.call( this, models, options );
+ },
+
+// /** Convert this ad-hoc collection of hdas to a formal collection tracked
+// by the server.
+// **/
+// promoteToHistoryDatasetCollection : function _promote( history, collection_type,
options ){
+////TODO: seems like this would be better in mvc/collections
+// options = options || {};
+// options.url = this.url();
+// options.type = "POST";
+// var full_collection_type = collection_type;
+// var element_identifiers = [],
+// name = null;
+//
+// // This mechanism is rough - no error handling, allows invalid selections, no
way
+// // for user to pick/override element identifiers. This is only really meant
+// if( collection_type === "list" ) {
+// this.chain().each( function( hda ) {
+// // TODO: Handle duplicate names.
+// var name = hda.attributes.name;
+// var id = hda.get('id');
+// var content_type = hda.attributes.history_content_type;
+// if( content_type === "dataset" ) {
+// if( full_collection_type !== "list" ) {
+// this.log( "Invalid collection type" );
+// }
+// element_identifiers.push( { name: name, src: "hda", id:
id } );
+// } else {
+// if( full_collection_type === "list" ) {
+// full_collection_type = "list:" +
hda.attributes.collection_type;
+// } else {
+// if( full_collection_type !== "list:" +
hda.attributes.collection_type ) {
+// this.log( "Invalid collection type" );
+// }
+// }
+// element_identifiers.push( { name: name, src: "hdca", id:
id } );
+// }
+// });
+// name = "New Dataset List";
+// } else if( collection_type === "paired" ) {
+// var ids = this.ids();
+// if( ids.length !== 2 ){
+// // TODO: Do something...
+// }
+// element_identifiers.push( { name: "forward", src:
"hda", id: ids[ 0 ] } );
+// element_identifiers.push( { name: "reverse", src:
"hda", id: ids[ 1 ] } );
+// name = "New Dataset Pair";
+// }
+// options.data = {
+// type: "dataset_collection",
+// name: name,
+// collection_type: full_collection_type,
+// element_identifiers: JSON.stringify( element_identifiers )
+// };
+//
+// var xhr = jQuery.ajax( options );
+// xhr.done( function( message, status, responseObj ){
+// history.refresh( );
+// });
+// xhr.fail( function( xhr, status, message ){
+// if( xhr.responseJSON && xhr.responseJSON.error ){
+// error = xhr.responseJSON.error;
+// } else {
+// error = xhr.responseJSON;
+// }
+// xhr.responseText = error;
+// // Do something?
+// });
+// return xhr;
+// },
+
+ /** String representation. */
+ toString : function(){
+ return ([ 'DatasetAssociationCollection(', this.length, ')'
].join( '' ));
+ }
+});
+
+
+//==============================================================================
return {
- DatasetAssociation : DatasetAssociation
+ DatasetAssociation : DatasetAssociation,
+ DatasetAssociationCollection : DatasetAssociationCollection
};
});
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/mvc/dataset/list-panel.js
--- /dev/null
+++ b/static/scripts/mvc/dataset/list-panel.js
@@ -0,0 +1,687 @@
+define([
+ "mvc/base-mvc",
+ "utils/localization"
+], function( BASE_MVC, _l ){
+/* =============================================================================
+TODO:
+
+============================================================================= */
+/** @class List that contains ListItemViews.
+ */
+var ListPanel = Backbone.View.extend( BASE_MVC.LoggableMixin ).extend(
+/** @lends ReadOnlyHistoryPanel.prototype */{
+
+ /** logger used to record this.log messages, commonly set to console */
+ //logger : console,
+
+ /** class to use for constructing the sub-views */
+ viewClass : BASE_MVC.ListItemView,
+
+ tagName : 'div',
+ className : 'list-panel',
+
+ /** (in ms) that jquery effects will use */
+ fxSpeed : 'fast',
+
+ /** string to display when the model has no hdas */
+ emptyMsg : _l( 'This list is empty' ),
+ /** string to no hdas match the search terms */
+ noneFoundMsg : _l( 'No matching items found' ),
+
+ // ......................................................................... SET UP
+ /** Set up the view, set up storage, bind listeners to HistoryContents events
+ * @param {Object} attributes optional settings for the list
+ */
+ initialize : function( attributes, options ){
+ attributes = attributes || {};
+ // set the logger if requested
+ if( attributes.logger ){
+ this.logger = attributes.logger;
+ }
+ this.log( this + '.initialize:', attributes );
+
+ // ---- instance vars
+ /** how quickly should jquery fx run? */
+ this.fxSpeed = _.has( attributes, 'fxSpeed' )?( attributes.fxSpeed ):(
this.fxSpeed );
+
+ /** filters for displaying subviews */
+ this.filters = [];
+ /** current search terms */
+ this.searchFor = attributes.searchFor || '';
+
+ /** loading indicator */
+ this.indicator = new LoadingIndicator( this.$el );
+
+ /** currently showing selectors on items? */
+ this.selecting = ( attributes.selecting !== undefined )? attributes.selecting :
true;
+ //this.selecting = false;
+
+ /** cached selected item.model.ids to persist btwn renders */
+ this.selected = attributes.selected || [];
+ /** the last selected item.model.id */
+ this.lastSelected = null;
+
+ /** list item view class (when passed models) */
+ this.viewClass = attributes.viewClass || this.viewClass;
+
+ /** list item views */
+ this.views = [];
+ /** list item models */
+ this.collection = attributes.collection || ( new Backbone.Collection([]) );
+
+ /** filter fns run over collection items to see if they should show in the list
*/
+ this.filters = attributes.filters || [];
+
+//TODO: remove
+ this.title = attributes.title || '';
+ this.subtitle = attributes.subtitle || '';
+
+ this._setUpListeners();
+ },
+
+ /** create any event listeners for the list
+ */
+ _setUpListeners : function(){
+ this.on( 'error', function( model, xhr, options, msg, details ){
+ //this.errorHandler( model, xhr, options, msg, details );
+ console.error( model, xhr, options, msg, details );
+ }, this );
+
+ // show hide the loading indicator
+ this.on( 'loading', function(){
+ this._showLoadingIndicator( 'loading...', 40 );
+ }, this );
+ this.on( 'loading-done', function(){
+ this._hideLoadingIndicator( 40 );
+ }, this );
+
+ // throw the first render up as a diff namespace using once (for outside
consumption)
+ this.once( 'rendered', function(){
+ this.trigger( 'rendered:initial', this );
+ }, this );
+
+ // debugging
+ if( this.logger ){
+ this.on( 'all', function( event ){
+ this.log( this + '', arguments );
+ }, this );
+ }
+
+ this._setUpCollectionListeners();
+ this._setUpViewListeners();
+ return this;
+ },
+
+ /** free any sub-views the list has */
+ freeViews : function(){
+//TODO: stopListening? remove?
+ this.views = [];
+ return this;
+ },
+
+ // ------------------------------------------------------------------------ item
listeners
+ /** listening for history and HDA events */
+ _setUpCollectionListeners : function(){
+
+ this.collection.on( 'reset', function(){
+ this.renderItems();
+ }, this );
+
+ this.collection.on( 'add', this.addItemView, this );
+ this.collection.on( 'remove', this.removeItemView, this );
+
+ // debugging
+ if( this.logger ){
+ this.collection.on( 'all', function( event ){
+ this.info( this + '(collection)', arguments );
+ }, this );
+ }
+ return this;
+ },
+
+ /** listening for history and HDA events */
+ _setUpViewListeners : function(){
+
+ // shift to select a range
+ this.on( 'view:selected', function( view, ev ){
+ if( ev && ev.shiftKey && this.lastSelected ){
+ var lastSelectedView = _.find( this.views, function( view ){
+ return view.model.id === this.lastSelected;
+ });
+ if( lastSelectedView ){
+ this.selectRange( view, lastSelectedView );
+ }
+ }
+ this.selected.push( view.model.id );
+ this.lastSelected = view.model.id;
+ }, this );
+ },
+
+ // ------------------------------------------------------------------------
rendering
+ /** Render this content, set up ui.
+ * @param {Number or String} speed the speed of the render
+ */
+ render : function( speed ){
+ var $newRender = this._buildNewRender();
+ this._setUpBehaviors( $newRender );
+ this._queueNewRender( $newRender, speed );
+ return this;
+ },
+
+ /** Build a temp div containing the new children for the view's $el.
+ */
+ _buildNewRender : function(){
+ // create a new render using a skeleton template, render title buttons, render
body, and set up events, etc.
+ var json = this.model? this.model.toJSON() : {},
+ $newRender = $( this.templates.el( json, this ) );
+ this._renderTitle( $newRender );
+ this._renderSubtitle( $newRender );
+ this._renderSearch( $newRender );
+ this.renderItems( $newRender );
+ return $newRender;
+ },
+
+ /**
+ */
+ _renderTitle : function( $where ){
+ //$where = $where || this.$el;
+ //$where.find( '.title' ).replaceWith( ... )
+ },
+
+ /**
+ */
+ _renderSubtitle : function( $where ){
+ //$where = $where || this.$el;
+ //$where.find( '.title' ).replaceWith( ... )
+ },
+
+ /** Fade out the old el, swap in the new contents, then fade in.
+ * @param {Number or String} speed jq speed to use for rendering effects
+ * @fires rendered when rendered
+ */
+ _queueNewRender : function( $newRender, speed ) {
+ speed = ( speed === undefined )?( this.fxSpeed ):( speed );
+ var view = this;
+
+ $( view ).queue( 'fx', [
+ function( next ){ this.$el.fadeOut( speed, next ); },
+ function( next ){
+ view._swapNewRender( $newRender );
+ next();
+ },
+ function( next ){ this.$el.fadeIn( speed, next ); },
+ function( next ){
+ view.trigger( 'rendered', view );
+ next();
+ }
+ ]);
+ },
+
+ /** empty out the current el, move the $newRender's children in */
+ _swapNewRender : function( $newRender ){
+ this.$el.empty().attr( 'class', this.className ).append(
$newRender.children() );
+ if( this.selecting ){ this.showSelectors( 0 ); }
+ return this;
+ },
+
+ /** */
+ _setUpBehaviors : function( $where ){
+ $where = $where || this.$el;
+ $where.find( '.controls [title]' ).tooltip({ placement: 'bottom'
});
+ return this;
+ },
+
+ // ------------------------------------------------------------------------
sub-$element shortcuts
+ /** the scroll container for this panel - can be $el, $el.parent(), or grandparent
depending on context */
+ $scrollContainer : function(){
+ // override
+ return this.$el.parent().parent();
+ },
+ /** */
+ $list : function( $where ){
+ return ( $where || this.$el ).find( '.list-items' );
+ },
+ /** container where list messages are attached */
+ $messages : function( $where ){
+ return ( $where || this.$el ).find( '.message-container' );
+ },
+ /** the message displayed when no views can be shown (no views, none matching search)
*/
+ $emptyMessage : function( $where ){
+ return ( $where || this.$el ).find( '.empty-message' );
+ },
+
+ // ------------------------------------------------------------------------ hda
sub-views
+ /**
+ * @param {jQuery} $whereTo what dom element to prepend the HDA views to
+ * @returns the visible item views
+ */
+ renderItems : function( $whereTo ){
+ $whereTo = $whereTo || this.$el;
+ var list = this,
+ newViews = [];
+
+ var $list = this.$list( $whereTo ),
+ item$els = this._filterCollection().map( function( itemModel ){
+//TODO: creates views each time - not neccessarily good
+ var view = list._createItemView( itemModel );
+ newViews.push( view );
+ return view.render( 0 ).$el;
+ });
+ this.debug( item$els );
+ this.debug( newViews );
+
+ $list.empty();
+ if( item$els.length ){
+ $list.append( item$els );
+ this.$emptyMessage( $whereTo ).hide();
+
+ } else {
+ this._renderEmptyMessage( $whereTo ).show();
+ }
+
+ this.views = newViews;
+ return newViews;
+ },
+
+ /**
+ */
+ _filterCollection : function(){
+ // override this
+ var list = this;
+ return list.collection.filter( _.bind( list._filterItem, list ) );
+ },
+
+ /**
+ */
+ _filterItem : function( model ){
+ // override this
+ var list = this;
+ return ( _.every( list.filters.map( function( fn ){ return fn.call( model ); }) )
)
+ && ( !list.searchFor || model.matchesAll( list.searchFor ) );
+ },
+
+ /**
+ */
+ _createItemView : function( model ){
+ var ViewClass = this._getItemViewClass( model ),
+ options = _.extend( this._getItemViewOptions( model ), {
+ model : model
+ }),
+ view = new ViewClass( options );
+ this._setUpItemViewListeners( view );
+ return view;
+ },
+
+ _getItemViewClass : function( model ){
+ // override this
+ return this.viewClass;
+ },
+
+ _getItemViewOptions : function( model ){
+ // override this
+ return {
+ //logger : this.logger,
+ fxSpeed : this.fxSpeed,
+ expanded : false,
+ selectable : this.selecting,
+ selected : _.contains( this.selected, model.id ),
+ draggable : this.dragging
+ };
+ },
+
+ /**
+ */
+ _setUpItemViewListeners : function( view ){
+ var list = this;
+ view.on( 'all', function(){
+ var args = Array.prototype.slice.call( arguments, 0 );
+ args[0] = 'view:' + args[0];
+ list.trigger.apply( list, args );
+ });
+
+ // debugging
+ //if( this.logger ){
+ // view.on( 'all', function( event ){
+ // this.log( this + '(view)', arguments );
+ // }, this );
+ //}
+ return this;
+ },
+
+ /** render the empty/none-found message */
+ _renderEmptyMessage : function( $whereTo ){
+ //this.debug( '_renderEmptyMessage', $whereTo, this.searchFor );
+ var text = this.searchFor? this.noneFoundMsg : this.emptyMsg;
+ return this.$emptyMessage( $whereTo ).text( text );
+ },
+
+ /** collapse all item views */
+ expandAll : function(){
+ _.each( this.views, function( view ){
+ view.expand();
+ });
+ },
+
+ /** collapse all item views */
+ collapseAll : function(){
+ _.each( this.views, function( view ){
+ view.collapse();
+ });
+ },
+
+ // ------------------------------------------------------------------------
collection/views syncing
+ /**
+ */
+ addItemView : function( model, collection, options ){
+ this.log( this + '.addItemView:', model );
+ var list = this;
+ if( !this._filterItem( model ) ){ return undefined; }
+
+//TODO: sorted? position?
+ var view = list._createItemView( model );
+ this.views.push( view );
+
+ $( view ).queue( 'fx', [
+ function( next ){ list.$emptyMessage().fadeOut( list.fxSpeed, next ); },
+ function( next ){
+//TODO: auto render?
+ list.$list().append( view.render().$el );
+ next();
+ }
+ ]);
+ return view;
+ },
+
+ /**
+ */
+ removeItemView : function( model, collection, options ){
+ this.log( this + '.removeItemView:', model );
+ var list = this,
+ view = list.viewFromModel( model );
+ if( !view ){ return undefined; }
+
+ this.views = _.without( this.views, view );
+ view.remove();
+ if( !this.views.length ){
+ list._renderEmptyMessage().fadeIn( list.fxSpeed );
+ }
+ return view;
+ },
+
+ /** get views based on model properties
+ */
+ viewFromModel : function( model ){
+ for( var i=0; i<this.views.length; i++ ){
+ var view = this.views[i];
+ if( view.model === model ){
+ return view;
+ }
+ }
+ return undefined;
+ },
+
+ /** get views based on model properties
+ */
+ viewsWhereModel : function( properties ){
+ return this.views.filter( function( view ){
+ //return view.model.matches( properties );
+//TODO: replace with _.matches (underscore 1.6.0)
+ var json = view.model.toJSON();
+ //console.debug( '\t', json, properties );
+ for( var key in properties ){
+ if( properties.hasOwnPropery( key ) ){
+ //console.debug( '\t\t', json[ key ], view.model.properties[
key ] );
+ if( json[ key ] !== view.model.properties[ key ] ){
+ return false;
+ }
+ }
+ }
+ return true;
+ });
+ },
+
+ /**
+ */
+ viewRange : function( viewA, viewB ){
+ if( viewA === viewB ){ return ( viewA )?( [ viewA ] ):( [] ); }
+
+ var indexA = this.views.indexOf( viewA ),
+ indexB = this.views.indexOf( viewB );
+
+ // handle not found
+ if( indexA === -1 || indexB === -1 ){
+ if( indexA === indexB ){ return []; }
+ return ( indexA === -1 )?( [ viewB ] ):( [ viewA ] );
+ }
+ // reverse if indeces are
+ //note: end inclusive
+ return ( indexA < indexB )?
+ this.views.slice( indexA, indexB + 1 ) :
+ this.views.slice( indexB, indexA + 1 );
+ },
+
+ // ------------------------------------------------------------------------
searching
+ /** render a search input for filtering datasets shown
+ * (see the search section in the HDA model for implementation of the actual
searching)
+ * return will start the search
+ * esc will clear the search
+ * clicking the clear button will clear the search
+ * uses searchInput in ui.js
+ */
+ _renderSearch : function( $where ){
+ $where.find( '.controls .search-input' ).searchInput({
+ placeholder : 'search',
+ initialVal : this.searchFor,
+ onfirstsearch : _.bind( this._firstSearch, this ),
+ onsearch : _.bind( this.searchItems, this ),
+ onclear : _.bind( this.clearSearch, this )
+ });
+ return $where;
+ },
+
+ _firstSearch : function( searchFor ){
+ this.log( 'onFirstSearch', searchFor );
+ return this.searchItems( searchFor );
+ },
+
+ /** filter view list to those that contain the searchFor terms */
+ searchItems : function( searchFor ){
+ this.searchFor = searchFor;
+ this.trigger( 'search:searching', searchFor, this );
+ this.renderItems();
+ return this;
+ },
+
+ /** clear the search filters and show all views that are normally shown */
+ clearSearch : function( searchFor ){
+ //this.log( 'onSearchClear', this );
+ this.searchFor = '';
+ this.trigger( 'search:clear', this );
+ this.renderItems();
+ return this;
+ },
+
+ // ------------------------------------------------------------------------
selection
+ /** show selectors on all visible hdas and associated controls */
+ showSelectors : function( speed ){
+ speed = ( speed !== undefined )?( speed ):( this.fxSpeed );
+ this.selecting = true;
+ this.$( '.list-actions' ).slideDown( speed );
+ _.each( this.views, function( view ){
+ view.showSelector( speed );
+ });
+ this.selected = [];
+ this.lastSelected = null;
+ },
+
+ /** hide selectors on all visible hdas and associated controls */
+ hideSelectors : function( speed ){
+ speed = ( speed !== undefined )?( speed ):( this.fxSpeed );
+ this.selecting = false;
+ this.$( '.list-actions' ).slideUp( speed );
+ _.each( this.views, function( view ){
+ view.hideSelector( speed );
+ });
+ this.selected = [];
+ this.lastSelected = null;
+ },
+
+ /** show or hide selectors on all visible hdas and associated controls */
+ toggleSelectors : function(){
+ if( !this.selecting ){
+ this.showSelectors();
+ } else {
+ this.hideSelectors();
+ }
+ },
+
+ /** select all visible hdas */
+ selectAll : function( event ){
+ _.each( this.views, function( view ){
+ view.select( event );
+ });
+ },
+
+ /** deselect all visible hdas */
+ deselectAll : function( event ){
+ this.lastSelected = null;
+ _.each( this.views, function( view ){
+ view.deselect( event );
+ });
+ },
+
+ /** select a range of datasets between A and B */
+ selectRange : function( viewA, viewB ){
+ var range = this.viewRange( viewA, viewB );
+ _.each( range, function( view ){
+ view.select();
+ });
+ return range;
+ },
+
+ /** return an array of all currently selected hdas */
+ getSelectedViews : function(){
+ return _.filter( this.views, function( v ){
+ return v.selected;
+ });
+ },
+
+ /** return an collection of the models of all currenly selected hdas */
+ getSelectedModels : function(){
+ return new this.collection.constructor( _.map( this.getSelectedViews(), function(
view ){
+ return view.model;
+ }));
+ },
+
+ // ------------------------------------------------------------------------ loading
indicator
+//TODO: questionable
+ /** hide the $el and display a loading indicator (in the $el's parent) when
loading new data */
+ _showLoadingIndicator : function( msg, speed, callback ){
+ speed = ( speed !== undefined )?( speed ):( this.fxSpeed );
+ if( !this.indicator ){
+ this.indicator = new LoadingIndicator( this.$el, this.$el.parent() );
+ }
+ if( !this.$el.is( ':visible' ) ){
+ this.indicator.show( 0, callback );
+ } else {
+ this.$el.fadeOut( speed );
+ this.indicator.show( msg, speed, callback );
+ }
+ },
+
+ /** hide the loading indicator */
+ _hideLoadingIndicator : function( speed, callback ){
+ speed = ( speed !== undefined )?( speed ):( this.fxSpeed );
+ if( this.indicator ){
+ this.indicator.hide( speed, callback );
+ }
+ },
+
+ // ------------------------------------------------------------------------
scrolling
+ /** get the current scroll position of the panel in its parent */
+ scrollPosition : function(){
+ return this.$scrollContainer().scrollTop();
+ },
+
+ /** set the current scroll position of the panel in its parent */
+ scrollTo : function( pos ){
+ this.$scrollContainer().scrollTop( pos );
+ return this;
+ },
+
+ /** Scrolls the panel to the top. */
+ scrollToTop : function(){
+ this.$scrollContainer().scrollTop( 0 );
+ return this;
+ },
+
+ /** */
+ scrollToItem : function( view ){
+ if( !view ){ return; }
+ var itemTop = view.$el.offset().top;
+ this.$scrollContainer().scrollTop( itemTop );
+ },
+
+ // ------------------------------------------------------------------------ panel
events
+ /** event map */
+ events : {
+ 'click .select-all' : 'selectAll',
+ 'click .deselect-all' : 'deselectAll'
+ },
+
+ // ------------------------------------------------------------------------ misc
+ /** Return a string rep of the history */
+ toString : function(){
+ return 'ListPanel(' + this.collection + ')';
+ }
+});
+
+// ............................................................................
TEMPLATES
+/** underscore templates */
+ListPanel.prototype.templates = (function(){
+//TODO: move to require text! plugin
+
+ var elTemplate = BASE_MVC.wrapTemplate([
+ // temp container
+ '<div>',
+ '<div class="controls">',
+ '<div class="title">',
+ '<div class="name"><%= model.name ||
view.title %></div>',
+ '</div>',
+ '<div class="subtitle"><%= view.subtitle
%></div>',
+ '<div class="actions"></div>',
+ '<div class="messages"></div>',
+
+ '<div class="search">',
+ '<div class="search-input"></div>',
+ '</div>',
+
+ '<div class="list-actions">',
+ '<div class="btn-group">',
+ '<button class="select-all btn
btn-default"',
+ 'data-mode="select">', _l(
'All' ), '</button>',
+ '<button class="deselect-all btn
btn-default"',
+ 'data-mode="select">', _l(
'None' ), '</button>',
+ '</div>',
+ //'<button class="action-popup-btn btn
btn-default">',
+ // _l( 'For all selected' ), '...',
+ //'</button>',
+ '</div>',
+ '</div>',
+ '<div class="list-items"></div>',
+ '<div class="empty-message
infomessagesmall"></div>',
+ '</div>'
+ ]);
+
+ return {
+ el : elTemplate
+ };
+}());
+
+
+
+//==============================================================================
+ return {
+ ListPanel: ListPanel
+ };
+});
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/mvc/ui.js
--- a/static/scripts/mvc/ui.js
+++ b/static/scripts/mvc/ui.js
@@ -610,6 +610,7 @@
* of characters, a callback is called. Pressing ESC when the input
* is focused will clear the input and call a separate callback.
*/
+ var _l = window._l || function( s ){ return s; }
// contructor
function searchInput( parentNode, options ){
@@ -670,6 +671,11 @@
})
// attach behaviors to esc, return if desired, search on some min len
string
.keyup( function( event ){
+ event.preventDefault();
+ event.stopPropagation();
+//TODO: doesn't work
+ if( !$( this ).val() ){ $( this ).blur(); }
+
// esc key will clear if desired
if( event.which === KEYCODE_ESC && options.escWillClear ){
clearSearchInput.call( this, event );
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/packed/mvc/base-mvc.js
--- a/static/scripts/packed/mvc/base-mvc.js
+++ b/static/scripts/packed/mvc/base-mvc.js
@@ -1,1 +1,1 @@
-define(["utils/add-logging"],function(i){var
j={logger:null,_logNamespace:"?",log:function(){if(this.logger){var
l=this.logger.log;if(typeof
this.logger.log==="object"){l=Function.prototype.bind.call(this.logger.log,this.logger)}return
l.apply(this.logger,arguments)}return undefined}};i(j);var
a=Backbone.Model.extend({initialize:function(m){this._checkEnabledSessionStorage();if(!m.id){throw
new Error("SessionStorageModel requires an id in the initial
attributes")}this.id=m.id;var
l=(!this.isNew())?(this._read(this)):({});this.clear({silent:true});this.save(_.extend({},this.defaults,l,m),{silent:true});this.on("change",function(){this.save()})},_checkEnabledSessionStorage:function(){try{return
sessionStorage.length}catch(l){alert("Please enable cookies in your browser for this
Galaxy site");return
false}},sync:function(o,m,l){if(!l.silent){m.trigger("request",m,{},l)}var
n;switch(o){case"create":n=this._create(m);break;case"read":n=this._read(m);break;case"update":n=this._update(m);break;case"delete":n=this._delete(m);break}if(n!==undefined||n!==null){if(l.success){l.success()}}else{if(l.error){l.error()}}return
n},_create:function(l){var
m=l.toJSON(),n=sessionStorage.setItem(l.id,JSON.stringify(m));return(n===null)?(n):(m)},_read:function(l){return
JSON.parse(sessionStorage.getItem(l.id))},_update:function(l){return
l._create(l)},_delete:function(l){return
sessionStorage.removeItem(l.id)},isNew:function(){return
!sessionStorage.hasOwnProperty(this.id)},_log:function(){return
JSON.stringify(this.toJSON(),null,"
")},toString:function(){return"SessionStorageModel("+this.id+")"}});(function(){a.prototype=_.omit(a.prototype,"url","urlRoot")}());var
g={searchAttributes:[],searchAliases:{},searchAttribute:function(n,l){var
m=this.get(n);if(!l||(m===undefined||m===null)){return false}if(_.isArray(m)){return
this._searchArrayAttribute(m,l)}return(m.toString().toLowerCase().indexOf(l.toLowerCase())!==-1)},_searchArrayAttribute:function(m,l){l=l.toLowerCase();return
_.any(m,function(n){return(n.toString().toLowerCase().indexOf(l.toLowerCase())!==-1)})},search:function(l){var
m=this;return _.filter(this.searchAttributes,function(n){return
m.searchAttribute(n,l)})},matches:function(m){var
o="=",l=m.split(o);if(l.length>=2){var
n=l[0];n=this.searchAliases[n]||n;return this.searchAttribute(n,l[1])}return
!!this.search(m).length},matchesAll:function(m){var
l=this;m=m.match(/(".*"|\w*=".*"|\S*)/g).filter(function(n){return
!!n});return _.all(m,function(n){n=n.replace(/"/g,"");return
l.matches(n)})}};var
c={hiddenUntilActivated:function(l,n){n=n||{};this.HUAVOptions={$elementShown:this.$el,showFn:jQuery.prototype.toggle,showSpeed:"fast"};_.extend(this.HUAVOptions,n||{});this.HUAVOptions.hasBeenShown=this.HUAVOptions.$elementShown.is(":visible");this.hidden=this.isHidden();if(l){var
m=this;l.on("click",function(o){m.toggle(m.HUAVOptions.showSpeed)})}},isHidden:function(){return(this.HUAVOptions.$elementShown.is(":hidden"))},toggle:function(){if(this.hidden){if(!this.HUAVOptions.hasBeenShown){if(_.isFunction(this.HUAVOptions.onshowFirstTime)){this.HUAVOptions.hasBeenShown=true;this.HUAVOptions.onshowFirstTime.call(this)}}if(_.isFunction(this.HUAVOptions.onshow)){this.HUAVOptions.onshow.call(this);this.trigger("hiddenUntilActivated:shown",this)}this.hidden=false}else{if(_.isFunction(this.HUAVOptions.onhide)){this.HUAVOptions.onhide.call(this);this.trigger("hiddenUntilActivated:hidden",this)}this.hidden=true}return
this.HUAVOptions.showFn.apply(this.HUAVOptions.$elementShown,arguments)}};function
k(o,n){var l=Array.prototype.slice.call(arguments,0),m=l.pop();l.unshift(m);return
_.defaults.apply(_,l)}function e(m,l){l=l||"model";var
n=_.template(m.join(""));return function(p,o){var
q={view:o||{},_l:_l};q[l]=p||{};return n(q)}}var
b=Backbone.View.extend(j).extend({initialize:function(l){this.expanded=l.expanded||false},fxSpeed:"fast",render:function(m){var
l=this._buildNewRender();this._setUpBehaviors(l);this._queueNewRender(l,m);return
this},_buildNewRender:function(){var
l=$(this.templates.el(this.model.toJSON(),this));if(this.expanded){this.$details(l).replaceWith(this._renderDetails().show())}return
l},_queueNewRender:function(m,n){n=(n===undefined)?(this.fxSpeed):(n);var
l=this;$(l).queue("fx",[function(o){this.$el.fadeOut(n,o)},function(o){l._swapNewRender(m);o()},function(o){this.$el.fadeIn(n,o)},function(o){this.trigger("rendered",l);o()}])},_swapNewRender:function(l){return
this.$el.empty().attr("class",this.className).append(l.children())},_setUpBehaviors:function(l){l=l||this.$el;make_popup_menus(l);l.find("[title]").tooltip({placement:"bottom"})},$details:function(l){l=l||this.$el;return
l.find(".details")},_renderDetails:function(){var
l=$(this.templates.details(this.model.toJSON(),this));this._setUpBehaviors(l);return
l},toggleExpanded:function(l){l=(l===undefined)?(!this.expanded):(l);if(l){this.expand()}else{this.collapse()}return
this},expand:function(){var l=this;return l._fetchModelDetails().always(function(){var
m=l._renderDetails();l.$details().replaceWith(m);l.expanded=true;m.slideDown(l.fxSpeed,function(){l.trigger("expanded",l)})})},_fetchModelDetails:function(){if(!this.model.hasDetails()){return
this.model.fetch()}return jQuery.when()},collapse:function(){var
l=this;l.expanded=false;this.$details().slideUp(l.fxSpeed,function(){l.trigger("collapsed",l)})}});var
f={initialize:function(l){this.draggable=l.draggable||false},$dragHandle:function(){return
this.$(".title-bar")},toggleDraggable:function(){if(this.draggable){this.draggableOff()}else{this.draggableOn()}},draggableOn:function(){this.draggable=true;this.dragStartHandler=_.bind(this._dragStartHandler,this);this.dragEndHandler=_.bind(this._dragEndHandler,this);var
l=this.$dragHandle().attr("draggable",true).get(0);l.addEventListener("dragstart",this.dragStartHandler,false);l.addEventListener("dragend",this.dragEndHandler,false)},draggableOff:function(){this.draggable=false;var
l=this.$dragHandle().attr("draggable",false).get(0);l.removeEventListener("dragstart",this.dragStartHandler,false);l.removeEventListener("dragend",this.dragEndHandler,false)},_dragStartHandler:function(l){this.trigger("dragstart",this);l.dataTransfer.effectAllowed="move";l.dataTransfer.setData("text",JSON.stringify(this.model.toJSON()));return
false},_dragEndHandler:function(l){this.trigger("dragend",this);return
false}};var
d={initialize:function(l){this.selectable=l.selectable||false;this.selected=l.selected||false},$selector:function(){return
this.$(".selector")},_renderSelected:function(){this.$selector().find("span").toggleClass("fa-check-square-o",this.selected).toggleClass("fa-square-o",!this.selected)},toggleSelector:function(){if(!this.$selector().is(":visible")){this.showSelector()}else{this.hideSelector()}},showSelector:function(l){l=l!==undefined?l:this.fxSpeed;this.selectable=true;this.trigger("selectable",true,this);this._renderSelected();this.$selector().show(l)},hideSelector:function(l){l=l!==undefined?l:this.fxSpeed;this.selectable=false;this.trigger("selectable",false,this);this.$selector().hide(l)},toggleSelect:function(l){if(this.selected){this.deselect(l)}else{this.select(l)}},select:function(l){if(!this.selected){this.trigger("selected",this,l);this.selected=true;this._renderSelected()}return
false},deselect:function(l){if(this.selected){this.trigger("de-selected",this,l);this.selected=false;this._renderSelected()}return
false}};var
h=b.extend(k(d,f,{tagName:"div",className:"list-item",initialize:function(l){b.prototype.initialize.call(this,l);d.initialize.call(this,l);f.initialize.call(this,l)},_buildNewRender:function(){var
l=b.prototype._buildNewRender.call(this);l.find(".warnings").replaceWith(this._renderWarnings());l.find(".title-bar").replaceWith(this._renderTitleBar());l.find(".primary-actions").append(this._renderPrimaryActions());l.find(".subtitle").replaceWith(this._renderSubtitle());return
l},_swapNewRender:function(l){b.prototype._swapNewRender.call(this,l);if(this.selectable){this.showSelector(0)}if(this.draggable){this.draggableOn()}return
this.$el},_renderWarnings:function(){var l=this,n=$('<div
class="warnings"></div>'),m=l.model.toJSON();_.each(l.templates.warnings,function(o){n.append($(o(m,l)))});return
n},_renderTitleBar:function(){return
$(this.templates.titleBar(this.model.toJSON(),this))},_renderPrimaryActions:function(){return[]},_renderSubtitle:function(){return
$(this.templates.subtitle(this.model.toJSON(),this))},events:{"click
.title-bar":"_clickTitleBar","keydown
.title-bar":"_keyDownTitleBar","click
.selector":"toggleSelect"},_clickTitleBar:function(l){l.stopPropagation();this.toggleExpanded()},_keyDownTitleBar:function(n){var
l=32,m=13;if(n&&(n.type==="keydown")&&(n.keyCode===l||n.keyCode===m)){this.toggleExpanded();n.stopPropagation();return
false}return true},toString:function(){var
l=(this.model)?(this.model+""):("(no
model)");return"ListItemView("+l+")"}}));h.prototype.templates=(function(){var
n=e(['<div class="list-element">','<div
class="warnings"></div>','<div
class="selector">','<span class="fa fa-2x
fa-square-o"></span>',"</div>",'<div
class="primary-actions"></div>','<div
class="title-bar"></div>','<div
class="details"></div>',"</div>"]);var l={};var
o=e(['<div class="title-bar clear"
tabindex="0">','<span
class="state-icon"></span>','<div
class="title">','<span class="name"><%-
element.name %></span>',"</div>",'<div
class="subtitle"></div>',"</div>"],"element");var
p=e(['<div class="subtitle"></div>']);var m=e(['<div
class="details"></div>']);return{el:n,warnings:l,titleBar:o,subtitle:p,details:m}}());return{LoggableMixin:j,SessionStorageModel:a,SearchableModelMixin:g,HiddenUntilActivatedViewMixin:c,mixin:k,wrapTemplate:e,ExpandableView:b,DraggableViewMixin:f,SelectableViewMixin:d,ListItemView:h}});
\ No newline at end of file
+define(["utils/add-logging","utils/localization"],function(j,b){var
k={logger:null,_logNamespace:"?",log:function(){if(this.logger){var
m=this.logger.log;if(typeof
this.logger.log==="object"){m=Function.prototype.bind.call(this.logger.log,this.logger)}return
m.apply(this.logger,arguments)}return undefined}};j(k);var
a=Backbone.Model.extend({initialize:function(n){this._checkEnabledSessionStorage();if(!n.id){throw
new Error("SessionStorageModel requires an id in the initial
attributes")}this.id=n.id;var
m=(!this.isNew())?(this._read(this)):({});this.clear({silent:true});this.save(_.extend({},this.defaults,m,n),{silent:true});this.on("change",function(){this.save()})},_checkEnabledSessionStorage:function(){try{return
sessionStorage.length}catch(m){alert("Please enable cookies in your browser for this
Galaxy site");return
false}},sync:function(p,n,m){if(!m.silent){n.trigger("request",n,{},m)}var
o;switch(p){case"create":o=this._create(n);break;case"read":o=this._read(n);break;case"update":o=this._update(n);break;case"delete":o=this._delete(n);break}if(o!==undefined||o!==null){if(m.success){m.success()}}else{if(m.error){m.error()}}return
o},_create:function(m){var
n=m.toJSON(),o=sessionStorage.setItem(m.id,JSON.stringify(n));return(o===null)?(o):(n)},_read:function(m){return
JSON.parse(sessionStorage.getItem(m.id))},_update:function(m){return
m._create(m)},_delete:function(m){return
sessionStorage.removeItem(m.id)},isNew:function(){return
!sessionStorage.hasOwnProperty(this.id)},_log:function(){return
JSON.stringify(this.toJSON(),null,"
")},toString:function(){return"SessionStorageModel("+this.id+")"}});(function(){a.prototype=_.omit(a.prototype,"url","urlRoot")}());var
h={searchAttributes:[],searchAliases:{},searchAttribute:function(o,m){var
n=this.get(o);if(!m||(n===undefined||n===null)){return false}if(_.isArray(n)){return
this._searchArrayAttribute(n,m)}return(n.toString().toLowerCase().indexOf(m.toLowerCase())!==-1)},_searchArrayAttribute:function(n,m){m=m.toLowerCase();return
_.any(n,function(o){return(o.toString().toLowerCase().indexOf(m.toLowerCase())!==-1)})},search:function(m){var
n=this;return _.filter(this.searchAttributes,function(o){return
n.searchAttribute(o,m)})},matches:function(n){var
p="=",m=n.split(p);if(m.length>=2){var
o=m[0];o=this.searchAliases[o]||o;return this.searchAttribute(o,m[1])}return
!!this.search(n).length},matchesAll:function(n){var
m=this;n=n.match(/(".*"|\w*=".*"|\S*)/g).filter(function(o){return
!!o});return _.all(n,function(o){o=o.replace(/"/g,"");return
m.matches(o)})}};var
d={hiddenUntilActivated:function(m,o){o=o||{};this.HUAVOptions={$elementShown:this.$el,showFn:jQuery.prototype.toggle,showSpeed:"fast"};_.extend(this.HUAVOptions,o||{});this.HUAVOptions.hasBeenShown=this.HUAVOptions.$elementShown.is(":visible");this.hidden=this.isHidden();if(m){var
n=this;m.on("click",function(p){n.toggle(n.HUAVOptions.showSpeed)})}},isHidden:function(){return(this.HUAVOptions.$elementShown.is(":hidden"))},toggle:function(){if(this.hidden){if(!this.HUAVOptions.hasBeenShown){if(_.isFunction(this.HUAVOptions.onshowFirstTime)){this.HUAVOptions.hasBeenShown=true;this.HUAVOptions.onshowFirstTime.call(this)}}if(_.isFunction(this.HUAVOptions.onshow)){this.HUAVOptions.onshow.call(this);this.trigger("hiddenUntilActivated:shown",this)}this.hidden=false}else{if(_.isFunction(this.HUAVOptions.onhide)){this.HUAVOptions.onhide.call(this);this.trigger("hiddenUntilActivated:hidden",this)}this.hidden=true}return
this.HUAVOptions.showFn.apply(this.HUAVOptions.$elementShown,arguments)}};function
l(p,o){var m=Array.prototype.slice.call(arguments,0),n=m.pop();m.unshift(n);return
_.defaults.apply(_,m)}function f(n,m){m=m||"model";var
o=_.template(n.join(""));return function(q,p){var
r={view:p||{},_l:b};r[m]=q||{};return o(r)}}var
c=Backbone.View.extend(k).extend({initialize:function(m){this.expanded=m.expanded||false;this.fxSpeed=m.fxSpeed||this.fxSpeed},fxSpeed:"fast",render:function(n){var
m=this._buildNewRender();this._setUpBehaviors(m);this._queueNewRender(m,n);return
this},_buildNewRender:function(){var
m=$(this.templates.el(this.model.toJSON(),this));if(this.expanded){this.$details(m).replaceWith(this._renderDetails().show())}return
m},_queueNewRender:function(n,o){o=(o===undefined)?(this.fxSpeed):(o);var
m=this;$(m).queue("fx",[function(p){this.$el.fadeOut(o,p)},function(p){m._swapNewRender(n);p()},function(p){this.$el.fadeIn(o,p)},function(p){this.trigger("rendered",m);p()}])},_swapNewRender:function(m){return
this.$el.empty().attr("class",this.className).append(m.children())},_setUpBehaviors:function(m){m=m||this.$el;m.find("[title]").tooltip({placement:"bottom"})},$details:function(m){m=m||this.$el;return
m.find(".details")},_renderDetails:function(){var
m=$(this.templates.details(this.model.toJSON(),this));this._setUpBehaviors(m);return
m},toggleExpanded:function(m){m=(m===undefined)?(!this.expanded):(m);if(m){this.expand()}else{this.collapse()}return
this},expand:function(){var m=this;return m._fetchModelDetails().always(function(){var
n=m._renderDetails();m.$details().replaceWith(n);m.expanded=true;n.slideDown(m.fxSpeed,function(){m.trigger("expanded",m)})})},_fetchModelDetails:function(){if(!this.model.hasDetails()){return
this.model.fetch()}return jQuery.when()},collapse:function(){var
m=this;m.expanded=false;this.$details().slideUp(m.fxSpeed,function(){m.trigger("collapsed",m)})}});var
g={initialize:function(m){this.draggable=m.draggable||false},$dragHandle:function(){return
this.$(".title-bar")},toggleDraggable:function(){if(this.draggable){this.draggableOff()}else{this.draggableOn()}},draggableOn:function(){this.draggable=true;this.dragStartHandler=_.bind(this._dragStartHandler,this);this.dragEndHandler=_.bind(this._dragEndHandler,this);var
m=this.$dragHandle().attr("draggable",true).get(0);m.addEventListener("dragstart",this.dragStartHandler,false);m.addEventListener("dragend",this.dragEndHandler,false)},draggableOff:function(){this.draggable=false;var
m=this.$dragHandle().attr("draggable",false).get(0);m.removeEventListener("dragstart",this.dragStartHandler,false);m.removeEventListener("dragend",this.dragEndHandler,false)},_dragStartHandler:function(m){this.trigger("dragstart",this);m.dataTransfer.effectAllowed="move";m.dataTransfer.setData("text",JSON.stringify(this.model.toJSON()));return
false},_dragEndHandler:function(m){this.trigger("dragend",this);return
false}};var
e={initialize:function(m){this.selectable=m.selectable||false;this.selected=m.selected||false},$selector:function(){return
this.$(".selector")},_renderSelected:function(){this.$selector().find("span").toggleClass("fa-check-square-o",this.selected).toggleClass("fa-square-o",!this.selected)},toggleSelector:function(){if(!this.$selector().is(":visible")){this.showSelector()}else{this.hideSelector()}},showSelector:function(m){m=m!==undefined?m:this.fxSpeed;this.selectable=true;this.trigger("selectable",true,this);this._renderSelected();this.$selector().show(m)},hideSelector:function(m){m=m!==undefined?m:this.fxSpeed;this.selectable=false;this.trigger("selectable",false,this);this.$selector().hide(m)},toggleSelect:function(m){if(this.selected){this.deselect(m)}else{this.select(m)}},select:function(m){if(!this.selected){this.trigger("selected",this,m);this.selected=true;this._renderSelected()}return
false},deselect:function(m){if(this.selected){this.trigger("de-selected",this,m);this.selected=false;this._renderSelected()}return
false}};var
i=c.extend(l(e,g,{tagName:"div",className:"list-item",initialize:function(m){c.prototype.initialize.call(this,m);e.initialize.call(this,m);g.initialize.call(this,m)},_buildNewRender:function(){var
m=c.prototype._buildNewRender.call(this);m.find(".warnings").replaceWith(this._renderWarnings());m.find(".title-bar").replaceWith(this._renderTitleBar());m.find(".primary-actions").append(this._renderPrimaryActions());m.find(".subtitle").replaceWith(this._renderSubtitle());return
m},_swapNewRender:function(m){c.prototype._swapNewRender.call(this,m);if(this.selectable){this.showSelector(0)}if(this.draggable){this.draggableOn()}return
this.$el},_renderWarnings:function(){var m=this,o=$('<div
class="warnings"></div>'),n=m.model.toJSON();_.each(m.templates.warnings,function(p){o.append($(p(n,m)))});return
o},_renderTitleBar:function(){return
$(this.templates.titleBar(this.model.toJSON(),this))},_renderPrimaryActions:function(){return[]},_renderSubtitle:function(){return
$(this.templates.subtitle(this.model.toJSON(),this))},events:{"click
.title-bar":"_clickTitleBar","keydown
.title-bar":"_keyDownTitleBar","click
.selector":"toggleSelect"},_clickTitleBar:function(m){m.stopPropagation();this.toggleExpanded()},_keyDownTitleBar:function(o){var
m=32,n=13;if(o&&(o.type==="keydown")&&(o.keyCode===m||o.keyCode===n)){this.toggleExpanded();o.stopPropagation();return
false}return true},toString:function(){var
m=(this.model)?(this.model+""):("(no
model)");return"ListItemView("+m+")"}}));i.prototype.templates=(function(){var
o=f(['<div class="list-element">','<div
class="warnings"></div>','<div
class="selector">','<span class="fa fa-2x
fa-square-o"></span>',"</div>",'<div
class="primary-actions"></div>','<div
class="title-bar"></div>','<div
class="details"></div>',"</div>"]);var m={};var
p=f(['<div class="title-bar clear"
tabindex="0">','<span
class="state-icon"></span>','<div
class="title">','<span class="name"><%-
element.name %></span>',"</div>",'<div
class="subtitle"></div>',"</div>"],"element");var
q=f(['<div class="subtitle"></div>']);var n=f(['<div
class="details"></div>']);return{el:o,warnings:m,titleBar:p,subtitle:q,details:n}}());return{LoggableMixin:k,SessionStorageModel:a,SearchableModelMixin:h,HiddenUntilActivatedViewMixin:d,mixin:l,wrapTemplate:f,ExpandableView:c,DraggableViewMixin:g,SelectableViewMixin:e,ListItemView:i}});
\ No newline at end of file
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/packed/mvc/dataset/dataset-li.js
--- a/static/scripts/packed/mvc/dataset/dataset-li.js
+++ b/static/scripts/packed/mvc/dataset/dataset-li.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/states","mvc/base-mvc","utils/localization"],function(a,b,c){var
e=b.ListItemView;var d=e.extend({className:e.prototype.className+"
dataset",id:function(){return["dataset",this.model.get("id")].join("-")},initialize:function(f){if(f.logger){this.logger=this.model.logger=f.logger}this.log(this+".initialize:",f);e.prototype.initialize.call(this,f);this.linkTarget=f.linkTarget||"_blank";this._setUpListeners()},_setUpListeners:function(){this.on("selectable",function(f){if(f){this.$(".primary-actions").hide()}else{this.$(".primary-actions").show()}});this.model.on("change",function(g,f){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this);this.on("all",function(f){this.log(f)},this)},_fetchModelDetails:function(){var
f=this;if(f.model.inReadyState()&&!f.model.hasDetails()){return
f.model.fetch({silent:true})}return jQuery.when()},remove:function(g,h){var
f=this;g=g||this.fxSpeed;this.$el.fadeOut(g,function(){Backbone.View.prototype.remove.call(f);if(h){h.call(f)}})},render:function(f){return
e.prototype.render.call(this,f)},_swapNewRender:function(f){e.prototype._swapNewRender.call(this,f);if(this.model.has("state")){this.$el.addClass("state-"+this.model.get("state"))}return
this.$el},_renderPrimaryActions:function(){return[this._renderDisplayButton()]},_renderDisplayButton:function(){var
h=this.model.get("state");if((h===a.NOT_VIEWABLE)||(h===a.DISCARDED)||(!this.model.get("accessible"))){return
null}var
g={target:this.linkTarget,classes:"display-btn"};if(this.model.get("purged")){g.disabled=true;g.title=c("Cannot
display datasets removed from
disk")}else{if(h===a.UPLOAD){g.disabled=true;g.title=c("This dataset must finish
uploading before it can be
viewed")}else{if(h===a.NEW){g.disabled=true;g.title=c("This dataset is not yet
viewable")}else{g.title=c("View data");g.href=this.model.urls.display;var
f=this;g.onclick=function(i){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Data
Viewer:
"+f.model.get("name"),type:"other",content:function(j){require(["mvc/data"],function(k){var
l=new
k.TabularDataset({id:f.model.get("id")});$.when(l.fetch()).then(function(){k.createTabularDatasetChunkedView({model:l,parent_elt:j,embedded:true,height:"100%"})})})}});i.preventDefault()}}}}}g.faIcon="fa-eye";return
faIconButton(g)},_renderDetails:function(){if(this.model.get("state")===a.NOT_VIEWABLE){return
$(this.templates.noAccess(this.model.toJSON(),this))}var
f=e.prototype._renderDetails.call(this);f.find(".actions
.left").empty().append(this._renderSecondaryActions());f.find(".summary").html(this._renderSummary()).prepend(this._renderDetailMessages());f.find(".display-applications").html(this._renderDisplayApplications());this._setUpBehaviors(f);return
f},_renderSummary:function(){var
f=this.model.toJSON(),g=this.templates.summaries[f.state];g=g||this.templates.summaries.unknown;return
g(f,this)},_renderDetailMessages:function(){var f=this,h=$('<div
class="detail-messages"></div>'),g=f.model.toJSON();_.each(f.templates.detailMessages,function(i){h.append($(i(g,f)))});return
h},_renderDisplayApplications:function(){if(this.model.isDeletedOrPurged()){return""}return[this.templates.displayApplications(this.model.get("display_apps"),this),this.templates.displayApplications(this.model.get("display_types"),this)].join("")},_renderSecondaryActions:function(){this.debug("_renderSecondaryActions");switch(this.model.get("state")){case
a.NOT_VIEWABLE:return[];case a.OK:case a.FAILED_METADATA:case
a.ERROR:return[this._renderDownloadButton(),this._renderShowParamsButton()]}return[this._renderShowParamsButton()]},_renderShowParamsButton:function(){return
faIconButton({title:c("View
details"),classes:"params-btn",href:this.model.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_renderDownloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return
null}if(!_.isEmpty(this.model.get("meta_files"))){return
this._renderMetaFileDownloadButton()}return $(['<a class="download-btn
icon-btn" href="',this.model.urls.download,'"
title="'+c("Download")+'">','<span
class="fa
fa-floppy-o"></span>',"</a>"].join(""))},_renderMetaFileDownloadButton:function(){var
f=this.model.urls;return $(['<div class="metafile-dropdown
dropdown">','<a class="download-btn icon-btn"
href="javascript:void(0)" data-toggle="dropdown"','
title="'+c("Download")+'">','<span
class="fa fa-floppy-o"></span>',"</a>",'<ul
class="dropdown-menu" role="menu"
aria-labelledby="dLabel">','<li><a
href="'+f.download+'">',c("Download
dataset"),"</a></li>",_.map(this.model.get("meta_files"),function(g){return['<li><a
href="',f.meta_download+g.file_type,'">',c("Download"),"
",g.file_type,"</a></li>"].join("")}).join("\n"),"</ul>","</div>"].join("\n"))},toString:function(){var
f=(this.model)?(this.model+""):("(no
model)");return"DatasetListItemView("+f+")"}});d.prototype.templates=(function(){var
h=_.extend({},e.prototype.templates.warnings,{failed_metadata:b.wrapTemplate(['<%
if( model.state === "failed_metadata" ){ %>','<div
class="warningmessagesmall">',c("An error occurred setting the
metadata for this dataset"),"</div>","<% }
%>"]),error:b.wrapTemplate(["<% if( model.error ){
%>",'<div class="errormessagesmall">',c("There was an
error getting the data for this dataset"),": <%- model.error
%>","</div>","<% }
%>"]),purged:b.wrapTemplate(["<% if( model.purged ){
%>",'<div class="purged-msg
warningmessagesmall">',c("This dataset has been deleted and removed from
disk"),"</div>","<% }
%>"]),deleted:b.wrapTemplate(["<% if( model.deleted &&
!model.purged ){ %>",'<div class="deleted-msg
warningmessagesmall">',c("This dataset has been
deleted"),"</div>","<% } %>"])});var
i=b.wrapTemplate(['<div class="details">','<div
class="summary"></div>','<div class="actions
clear">','<div class="left"></div>','<div
class="right"></div>',"</div>","<% if(
!dataset.deleted && !dataset.purged ){ %>",'<div
class="tags-display"></div>','<div
class="annotation-display"></div>','<div
class="display-applications"></div>',"<% if( dataset.peek
){ %>",'<pre class="dataset-peek"><%= dataset.peek
%></pre>',"<% } %>","<% }
%>","</div>"],"dataset");var
g=b.wrapTemplate(['<div class="details">','<div
class="summary">',c("You do not have permission to view this
dataset"),"</div>","</div>"],"dataset");var
j={};j[a.OK]=j[a.FAILED_METADATA]=b.wrapTemplate(["<% if( dataset.misc_blurb ){
%>",'<div class="blurb">','<span
class="value"><%- dataset.misc_blurb
%></span>',"</div>","<% } %>","<% if(
dataset.data_type ){ %>",'<div
class="datatype">','<label
class="prompt">',c("format"),"</label>",'<span
class="value"><%- dataset.data_type
%></span>',"</div>","<% } %>","<% if(
dataset.metadata_dbkey ){ %>",'<div
class="dbkey">','<label
class="prompt">',c("database"),"</label>",'<span
class="value">',"<%- dataset.metadata_dbkey
%>","</span>","</div>","<% }
%>","<% if( dataset.misc_info ){ %>",'<div
class="info">','<span class="value"><%-
dataset.misc_info %></span>',"</div>","<% }
%>"],"dataset");j[a.NEW]=b.wrapTemplate(["<div>",c("This
is a new dataset and not all of its data are available
yet"),"</div>"],"dataset");j[a.NOT_VIEWABLE]=b.wrapTemplate(["<div>",c("You
do not have permission to view this
dataset"),"</div>"],"dataset");j[a.DISCARDED]=b.wrapTemplate(["<div>",c("The
job creating this dataset was cancelled before
completion"),"</div>"],"dataset");j[a.QUEUED]=b.wrapTemplate(["<div>",c("This
job is waiting to
run"),"</div>"],"dataset");j[a.RUNNING]=b.wrapTemplate(["<div>",c("This
job is currently
running"),"</div>"],"dataset");j[a.UPLOAD]=b.wrapTemplate(["<div>",c("This
dataset is currently
uploading"),"</div>"],"dataset");j[a.SETTING_METADATA]=b.wrapTemplate(["<div>",c("Metadata
is being
auto-detected"),"</div>"],"dataset");j[a.PAUSED]=b.wrapTemplate(["<div>",c('This
job is paused. Use the "Resume Paused Jobs" in the history menu to
resume'),"</div>"],"dataset");j[a.ERROR]=b.wrapTemplate(["<%
if( !dataset.purged ){ %>","<div><%- dataset.misc_blurb
%></div>","<% } %>",'<span
class="help-text">',c("An error occurred with this
dataset"),":</span>",'<div
class="job-error-text"><%- dataset.misc_info
%></div>'],"dataset");j[a.EMPTY]=b.wrapTemplate(["<div>",c("No
data"),": <i><%- dataset.misc_blurb
%></i></div>"],"dataset");j.unknown=b.wrapTemplate(['<div>Error:
unknown dataset state: "<%- dataset.state
%>"</div>'],"dataset");var
k={resubmitted:b.wrapTemplate(["<% if( model.resubmitted ){
%>",'<div class="resubmitted-msg
infomessagesmall">',c("The job creating this dataset has been
resubmitted"),"</div>","<% } %>"])};var
f=b.wrapTemplate(["<% _.each( apps, function( app ){ %>",'<div
class="display-application">','<span
class="display-application-location"><%- app.label %></span>
','<span class="display-application-links">',"<%
_.each( app.links, function( link ){ %>",'<a target="<%=
link.target %>" href="<%= link.href %>">',"<%
print( _l( link.text ) ); %>","</a> ","<% });
%>","</span>","</div>","<% });
%>"],"apps");return
_.extend({},e.prototype.templates,{warnings:h,details:i,noAccess:g,summaries:j,detailMessages:k,displayApplications:f})}());return{DatasetListItemView:d}});
\ No newline at end of file
+define(["mvc/dataset/states","mvc/base-mvc","utils/localization"],function(a,b,c){var
e=b.ListItemView;var d=e.extend({className:e.prototype.className+"
dataset",id:function(){return["dataset",this.model.get("id")].join("-")},initialize:function(f){if(f.logger){this.logger=this.model.logger=f.logger}this.log(this+".initialize:",f);e.prototype.initialize.call(this,f);this.linkTarget=f.linkTarget||"_blank";this._setUpListeners()},_setUpListeners:function(){this.on("selectable",function(f){if(f){this.$(".primary-actions").hide()}else{this.$(".primary-actions").show()}},this);this.model.on("change",function(g,f){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this);this.on("all",function(f){this.log(f)},this)},_fetchModelDetails:function(){var
f=this;if(f.model.inReadyState()&&!f.model.hasDetails()){return
f.model.fetch({silent:true})}return jQuery.when()},remove:function(g,h){var
f=this;g=g||this.fxSpeed;this.$el.fadeOut(g,function(){Backbone.View.prototype.remove.call(f);if(h){h.call(f)}})},render:function(f){return
e.prototype.render.call(this,f)},_swapNewRender:function(f){e.prototype._swapNewRender.call(this,f);if(this.model.has("state")){this.$el.addClass("state-"+this.model.get("state"))}return
this.$el},_renderPrimaryActions:function(){return[this._renderDisplayButton()]},_renderDisplayButton:function(){var
h=this.model.get("state");if((h===a.NOT_VIEWABLE)||(h===a.DISCARDED)||(!this.model.get("accessible"))){return
null}var
g={target:this.linkTarget,classes:"display-btn"};if(this.model.get("purged")){g.disabled=true;g.title=c("Cannot
display datasets removed from
disk")}else{if(h===a.UPLOAD){g.disabled=true;g.title=c("This dataset must finish
uploading before it can be
viewed")}else{if(h===a.NEW){g.disabled=true;g.title=c("This dataset is not yet
viewable")}else{g.title=c("View data");g.href=this.model.urls.display;var
f=this;g.onclick=function(i){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Data
Viewer:
"+f.model.get("name"),type:"other",content:function(j){require(["mvc/data"],function(k){var
l=new
k.TabularDataset({id:f.model.get("id")});$.when(l.fetch()).then(function(){k.createTabularDatasetChunkedView({model:l,parent_elt:j,embedded:true,height:"100%"})})})}});i.preventDefault()}}}}}g.faIcon="fa-eye";return
faIconButton(g)},_renderDetails:function(){if(this.model.get("state")===a.NOT_VIEWABLE){return
$(this.templates.noAccess(this.model.toJSON(),this))}var
f=e.prototype._renderDetails.call(this);f.find(".actions
.left").empty().append(this._renderSecondaryActions());f.find(".summary").html(this._renderSummary()).prepend(this._renderDetailMessages());f.find(".display-applications").html(this._renderDisplayApplications());this._setUpBehaviors(f);return
f},_renderSummary:function(){var
f=this.model.toJSON(),g=this.templates.summaries[f.state];g=g||this.templates.summaries.unknown;return
g(f,this)},_renderDetailMessages:function(){var f=this,h=$('<div
class="detail-messages"></div>'),g=f.model.toJSON();_.each(f.templates.detailMessages,function(i){h.append($(i(g,f)))});return
h},_renderDisplayApplications:function(){if(this.model.isDeletedOrPurged()){return""}return[this.templates.displayApplications(this.model.get("display_apps"),this),this.templates.displayApplications(this.model.get("display_types"),this)].join("")},_renderSecondaryActions:function(){this.debug("_renderSecondaryActions");switch(this.model.get("state")){case
a.NOT_VIEWABLE:return[];case a.OK:case a.FAILED_METADATA:case
a.ERROR:return[this._renderDownloadButton(),this._renderShowParamsButton()]}return[this._renderShowParamsButton()]},_renderShowParamsButton:function(){return
faIconButton({title:c("View
details"),classes:"params-btn",href:this.model.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_renderDownloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return
null}if(!_.isEmpty(this.model.get("meta_files"))){return
this._renderMetaFileDownloadButton()}return $(['<a class="download-btn
icon-btn" href="',this.model.urls.download,'"
title="'+c("Download")+'">','<span
class="fa
fa-floppy-o"></span>',"</a>"].join(""))},_renderMetaFileDownloadButton:function(){var
f=this.model.urls;return $(['<div class="metafile-dropdown
dropdown">','<a class="download-btn icon-btn"
href="javascript:void(0)" data-toggle="dropdown"','
title="'+c("Download")+'">','<span
class="fa fa-floppy-o"></span>',"</a>",'<ul
class="dropdown-menu" role="menu"
aria-labelledby="dLabel">','<li><a
href="'+f.download+'">',c("Download
dataset"),"</a></li>",_.map(this.model.get("meta_files"),function(g){return['<li><a
href="',f.meta_download+g.file_type,'">',c("Download"),"
",g.file_type,"</a></li>"].join("")}).join("\n"),"</ul>","</div>"].join("\n"))},toString:function(){var
f=(this.model)?(this.model+""):("(no
model)");return"DatasetListItemView("+f+")"}});d.prototype.templates=(function(){var
h=_.extend({},e.prototype.templates.warnings,{failed_metadata:b.wrapTemplate(['<%
if( model.state === "failed_metadata" ){ %>','<div
class="warningmessagesmall">',c("An error occurred setting the
metadata for this dataset"),"</div>","<% }
%>"]),error:b.wrapTemplate(["<% if( model.error ){
%>",'<div class="errormessagesmall">',c("There was an
error getting the data for this dataset"),": <%- model.error
%>","</div>","<% }
%>"]),purged:b.wrapTemplate(["<% if( model.purged ){
%>",'<div class="purged-msg
warningmessagesmall">',c("This dataset has been deleted and removed from
disk"),"</div>","<% }
%>"]),deleted:b.wrapTemplate(["<% if( model.deleted &&
!model.purged ){ %>",'<div class="deleted-msg
warningmessagesmall">',c("This dataset has been
deleted"),"</div>","<% } %>"])});var
i=b.wrapTemplate(['<div class="details">','<div
class="summary"></div>','<div class="actions
clear">','<div class="left"></div>','<div
class="right"></div>',"</div>","<% if(
!dataset.deleted && !dataset.purged ){ %>",'<div
class="tags-display"></div>','<div
class="annotation-display"></div>','<div
class="display-applications"></div>',"<% if( dataset.peek
){ %>",'<pre class="dataset-peek"><%= dataset.peek
%></pre>',"<% } %>","<% }
%>","</div>"],"dataset");var
g=b.wrapTemplate(['<div class="details">','<div
class="summary">',c("You do not have permission to view this
dataset"),"</div>","</div>"],"dataset");var
j={};j[a.OK]=j[a.FAILED_METADATA]=b.wrapTemplate(["<% if( dataset.misc_blurb ){
%>",'<div class="blurb">','<span
class="value"><%- dataset.misc_blurb
%></span>',"</div>","<% } %>","<% if(
dataset.data_type ){ %>",'<div
class="datatype">','<label
class="prompt">',c("format"),"</label>",'<span
class="value"><%- dataset.data_type
%></span>',"</div>","<% } %>","<% if(
dataset.metadata_dbkey ){ %>",'<div
class="dbkey">','<label
class="prompt">',c("database"),"</label>",'<span
class="value">',"<%- dataset.metadata_dbkey
%>","</span>","</div>","<% }
%>","<% if( dataset.misc_info ){ %>",'<div
class="info">','<span class="value"><%-
dataset.misc_info %></span>',"</div>","<% }
%>"],"dataset");j[a.NEW]=b.wrapTemplate(["<div>",c("This
is a new dataset and not all of its data are available
yet"),"</div>"],"dataset");j[a.NOT_VIEWABLE]=b.wrapTemplate(["<div>",c("You
do not have permission to view this
dataset"),"</div>"],"dataset");j[a.DISCARDED]=b.wrapTemplate(["<div>",c("The
job creating this dataset was cancelled before
completion"),"</div>"],"dataset");j[a.QUEUED]=b.wrapTemplate(["<div>",c("This
job is waiting to
run"),"</div>"],"dataset");j[a.RUNNING]=b.wrapTemplate(["<div>",c("This
job is currently
running"),"</div>"],"dataset");j[a.UPLOAD]=b.wrapTemplate(["<div>",c("This
dataset is currently
uploading"),"</div>"],"dataset");j[a.SETTING_METADATA]=b.wrapTemplate(["<div>",c("Metadata
is being
auto-detected"),"</div>"],"dataset");j[a.PAUSED]=b.wrapTemplate(["<div>",c('This
job is paused. Use the "Resume Paused Jobs" in the history menu to
resume'),"</div>"],"dataset");j[a.ERROR]=b.wrapTemplate(["<%
if( !dataset.purged ){ %>","<div><%- dataset.misc_blurb
%></div>","<% } %>",'<span
class="help-text">',c("An error occurred with this
dataset"),":</span>",'<div
class="job-error-text"><%- dataset.misc_info
%></div>'],"dataset");j[a.EMPTY]=b.wrapTemplate(["<div>",c("No
data"),": <i><%- dataset.misc_blurb
%></i></div>"],"dataset");j.unknown=b.wrapTemplate(['<div>Error:
unknown dataset state: "<%- dataset.state
%>"</div>'],"dataset");var
k={resubmitted:b.wrapTemplate(["<% if( model.resubmitted ){
%>",'<div class="resubmitted-msg
infomessagesmall">',c("The job creating this dataset has been
resubmitted"),"</div>","<% } %>"])};var
f=b.wrapTemplate(["<% _.each( apps, function( app ){ %>",'<div
class="display-application">','<span
class="display-application-location"><%- app.label %></span>
','<span class="display-application-links">',"<%
_.each( app.links, function( link ){ %>",'<a target="<%=
link.target %>" href="<%= link.href %>">',"<%
print( _l( link.text ) ); %>","</a> ","<% });
%>","</span>","</div>","<% });
%>"],"apps");return
_.extend({},e.prototype.templates,{warnings:h,details:i,noAccess:g,summaries:j,detailMessages:k,displayApplications:f})}());return{DatasetListItemView:d}});
\ No newline at end of file
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641
static/scripts/packed/mvc/dataset/dataset-model.js
--- a/static/scripts/packed/mvc/dataset/dataset-model.js
+++ b/static/scripts/packed/mvc/dataset/dataset-model.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/states","mvc/base-mvc","utils/localization"],function(a,b,c){var
f=b.SearchableModelMixin;var
e=Backbone.Model.extend(b.LoggableMixin).extend(b.mixin(f,{defaults:{state:a.NEW,deleted:false,purged:false,name:"(unnamed
dataset)",accessible:true,data_type:"",file_ext:"",file_size:0,meta_files:[],misc_blurb:"",misc_info:"",tags:[]},initialize:function(g,h){this.debug(this+"(Dataset).initialize",g,h);if(!this.get("accessible")){this.set("state",a.NOT_VIEWABLE)}this.urls=this._generateUrls();this._setUpListeners()},_generateUrls:function(){var
i=this.get("id");if(!i){return{}}var
h={purge:"datasets/"+i+"/purge_async",display:"datasets/"+i+"/display/?preview=True",edit:"datasets/"+i+"/edit",download:"datasets/"+i+"/display?to_ext="+this.get("file_ext"),report_error:"dataset/errors?id="+i,rerun:"tool_runner/rerun?id="+i,show_params:"datasets/"+i+"/show_params",visualization:"visualization",meta_download:"dataset/get_metadata_file?hda_id="+i+"&metadata_name="};var
g=(galaxy_config&&galaxy_config.root)?(galaxy_config.root):("/");_.each(h,function(k,j){h[j]=g+k});this.urls=h;return
h},_setUpListeners:function(){this.on("change:state",function(h,g){this.log(this+"
has changed
state:",h,g);if(this.inReadyState()){this.trigger("state:ready",h,g,this.previous("state"))}});this.on("change:id
change:file_ext",function(g){this._generateUrls()})},toJSON:function(){var
g=Backbone.Model.prototype.toJSON.call(this);return
_.extend(g,{urls:this.urls})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},inReadyState:function(){var
g=_.contains(a.READY_STATES,this.get("state"));return(this.isDeletedOrPurged()||g)},hasDetails:function(){return
_.has(this.attributes,"genome_build")},hasData:function(){return(this.get("file_size")>0)},"delete":function(g){if(this.get("deleted")){return
jQuery.when()}return
this.save({deleted:true},g)},undelete:function(g){if(!this.get("deleted")||this.get("purged")){return
jQuery.when()}return this.save({deleted:false},g)},purge:function
d(g){if(this.get("purged")){return
jQuery.when()}g=g||{};g.url=this.urls.purge;var
h=this,i=jQuery.ajax(g);i.done(function(l,j,k){h.set({deleted:true,purged:true})});i.fail(function(n,j,m){var
k=c("Unable to purge dataset");var l=("Removal of datasets by users is not
allowed in this Galaxy
instance");if(n.responseJSON&&n.responseJSON.error){k=n.responseJSON.error}else{if(n.responseText.indexOf(l)!==-1){k=l}}n.responseText=k;h.trigger("error",h,n,g,c(k),{error:k})});return
i},searchAttributes:["name","file_ext","genome_build","misc_blurb","misc_info","annotation","tags"],searchAliases:{title:"name",format:"file_ext",database:"genome_build",blurb:"misc_blurb",description:"misc_blurb",info:"misc_info",tag:"tags"},toString:function(){var
g=this.get("id")||"";if(this.get("name")){g='"'+this.get("name")+'",'+g}return"Dataset("+g+")"}}));return{DatasetAssociation:e}});
\ No newline at end of file
+define(["mvc/dataset/states","mvc/base-mvc","utils/localization"],function(a,b,d){var
g=b.SearchableModelMixin;var
f=Backbone.Model.extend(b.LoggableMixin).extend(b.mixin(g,{defaults:{state:a.NEW,deleted:false,purged:false,name:"(unnamed
dataset)",accessible:true,data_type:"",file_ext:"",file_size:0,meta_files:[],misc_blurb:"",misc_info:"",tags:[]},initialize:function(h,i){this.debug(this+"(Dataset).initialize",h,i);if(!this.get("accessible")){this.set("state",a.NOT_VIEWABLE)}this.urls=this._generateUrls();this._setUpListeners()},_generateUrls:function(){var
j=this.get("id");if(!j){return{}}var
i={purge:"datasets/"+j+"/purge_async",display:"datasets/"+j+"/display/?preview=True",edit:"datasets/"+j+"/edit",download:"datasets/"+j+"/display?to_ext="+this.get("file_ext"),report_error:"dataset/errors?id="+j,rerun:"tool_runner/rerun?id="+j,show_params:"datasets/"+j+"/show_params",visualization:"visualization",meta_download:"dataset/get_metadata_file?hda_id="+j+"&metadata_name="};var
h=(window.galaxy_config&&galaxy_config.root)?(galaxy_config.root):("/");_.each(i,function(l,k){i[k]=h+l});this.urls=i;return
i},_setUpListeners:function(){this.on("change:state",function(i,h){this.log(this+"
has changed
state:",i,h);if(this.inReadyState()){this.trigger("state:ready",i,h,this.previous("state"))}});this.on("change:id
change:file_ext",function(h){this._generateUrls()})},toJSON:function(){var
h=Backbone.Model.prototype.toJSON.call(this);return
_.extend(h,{urls:this.urls})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},inReadyState:function(){var
h=_.contains(a.READY_STATES,this.get("state"));return(this.isDeletedOrPurged()||h)},hasDetails:function(){return
_.has(this.attributes,"genome_build")},hasData:function(){return(this.get("file_size")>0)},"delete":function(h){if(this.get("deleted")){return
jQuery.when()}return
this.save({deleted:true},h)},undelete:function(h){if(!this.get("deleted")||this.get("purged")){return
jQuery.when()}return this.save({deleted:false},h)},purge:function
e(h){if(this.get("purged")){return
jQuery.when()}h=h||{};h.url=this.urls.purge;var
i=this,j=jQuery.ajax(h);j.done(function(m,k,l){i.set({deleted:true,purged:true})});j.fail(function(o,k,n){var
l=d("Unable to purge dataset");var m=("Removal of datasets by users is not
allowed in this Galaxy
instance");if(o.responseJSON&&o.responseJSON.error){l=o.responseJSON.error}else{if(o.responseText.indexOf(m)!==-1){l=m}}o.responseText=l;i.trigger("error",i,o,h,d(l),{error:l})});return
j},searchAttributes:["name","file_ext","genome_build","misc_blurb","misc_info","annotation","tags"],searchAliases:{title:"name",format:"file_ext",database:"genome_build",blurb:"misc_blurb",description:"misc_blurb",info:"misc_info",tag:"tags"},toString:function(){var
h=this.get("id")||"";if(this.get("name")){h='"'+this.get("name")+'",'+h}return"Dataset("+h+")"}}));var
c=Backbone.Collection.extend(b.LoggableMixin).extend({model:f,urlRoot:((window.galaxy_config&&galaxy_config.root)?(galaxy_config.root):("/"))+"api/datasets",ids:function(){return
this.map(function(h){return h.get("id")})},notReady:function(){return
this.filter(function(h){return !h.inReadyState()})},haveDetails:function(){return
this.all(function(h){return h.hasDetails()})},ajaxQueue:function(m,j){var
i=jQuery.Deferred(),h=this.length,l=[];if(!h){i.resolve([]);return i}var
k=this.chain().reverse().map(function(o,n){return function(){var
p=m.call(o,j);p.done(function(q){i.notify({curr:n,total:h,response:q,model:o})});p.always(function(q){l.push(q);if(k.length){k.shift()()}else{i.resolve(l)}})}}).value();k.shift()();return
i},matches:function(h){return this.filter(function(i){return
i.matches(h)})},set:function(j,h){var i=this;j=_.map(j,function(l){if(!i.get(l.id)){return
l}var k=existing.toJSON();_.extend(k,l);return
k});Backbone.Collection.prototype.set.call(this,j,h)},toString:function(){return(["DatasetAssociationCollection(",this.length,")"].join(""))}});return{DatasetAssociation:f,DatasetAssociationCollection:c}});
\ No newline at end of file
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/scripts/packed/mvc/ui.js
--- a/static/scripts/packed/mvc/ui.js
+++ b/static/scripts/packed/mvc/ui.js
@@ -1,1 +1,1 @@
-var
IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var
IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var
a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return
this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return
false}return true},template:function(b){var a='title="'+b.title+'"
class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+="
"+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+='
id="'+b.id+'"'}a+='
href="'+b.href+'"';if(b.target){a+='
target="'+b.target+'"'}if(!b.visible){a+=' style="display:
none;"'}if(b.enabled){a="<a
"+a+"/>"}else{a="<span "+a+"/>"}return
$(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var
IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var
a=this;this.collection.each(function(d){var
b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button
menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var
c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var
create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new
IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return
new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var
GridView=Backbone.View.extend({});var
PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var
c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return
false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var
a=this;this.$el.find("li").each(function(c,b){var
d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return
this},template:function(b,a){return['<ul id="',b,'-menu"
class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no
options)</li>"}return _.map(a,function(d){if(d.divider){return'<li
class="divider"></li>'}else{if(d.header){return['<li
class="head"><a
href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var
c=d.href||"javascript:void(0);",e=(d.target)?('
target="'+d.target+'"'):(""),b=(d.checked)?('<span
class="fa
fa-check"></span>'):("");return['<li><a
class="popupmenu-option"
href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var
c=this.$el.width();var
a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var
c=this;function
a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return
this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return
this},findIndexByHtml:function(b){for(var
a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return
a}}return null},findItemByHtml:function(a){return
this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function
_create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var
a=[];_.each(c,function(f,d){var
e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return
new
PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var
b=[];c.find(a).each(function(g,e){var
f={},d=$(g);f.html=d.text();if(d.attr("href")){var
j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return
b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var
b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new
PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var
a=[];$(c).find(b).each(function(){var
e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return
a};var
faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var
b=['<a class="',a.classes.join("
"),'"',((a.title)?('
title="'+a.title+'"'):("")),((!a.disabled&&a.target)?('
target="'+a.target+'"'):("")),'
href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span
class="fa
',a.faIcon,'"></span>',"</a>"].join("");var
c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return
c};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function
d(){var e=['<div class="loading-indicator">','<div
class="loading-indicator-text">','<span class="fa fa-spinner
fa-spin fa-lg"></span>','<span
class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var
g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px
0px 0px
10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px
8px 0px 0px","font-style":"italic"})}return
g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return
b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return
b};return b}(function(){function a(j,p){var
d=27,m=13,c=$(j),e=true,g={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(q){},minSearchLen:0,escWillClear:true,oninit:function(){}};function
i(q){var
r=$(this).parent().children("input");r.val("");r.trigger("clear:searchInput");p.onclear()}function
o(r,q){$(this).trigger("search:searchInput",q);if(typeof
p.onfirstsearch==="function"&&e){e=false;p.onfirstsearch(q)}else{p.onsearch(q)}}function
f(){return['<input type="text" name="',p.name,'"
placeholder="',p.placeholder,'" ','class="search-query
',p.classes,'" ',"/>"].join("")}function
l(){return
$(f()).focus(function(q){$(this).select()}).keyup(function(r){if(r.which===d&&p.escWillClear){i.call(this,r)}else{var
q=$(this).val();if((r.which===m)||(p.minSearchLen&&q.length>=p.minSearchLen)){o.call(this,r,q)}else{if(!q.length){i.call(this,r)}}}}).val(p.initialVal)}function
k(){return $(['<span class="search-clear fa fa-times-circle"
','title="',_l("clear search
(esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(q){i.call(this,q)})}function
n(){return $(['<span class="search-loading fa fa-spinner fa-spin"
','title="',_l("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function
h(){c.find(".search-loading").toggle();c.find(".search-clear").toggle()}if(jQuery.type(p)==="string"){if(p==="toggle-loading"){h()}return
c}if(jQuery.type(p)==="object"){p=jQuery.extend(true,{},g,p)}return
c.addClass("search-input").prepend([l(),k(),n()])}jQuery.fn.extend({searchInput:function
b(c){return this.each(function(){return a(this,c)})}})}());(function(){function
c(o,n){this.currModeIndex=0;return
this._init(o,n)}c.prototype.DATA_KEY="mode-button";c.prototype.defaults={switchModesOnClick:true};c.prototype._init=function
j(o,n){n=n||{};this.$element=$(o);this.options=jQuery.extend(true,{},this.defaults,n);if(!n.modes){throw
new Error('ModeButton requires a "modes" array')}var
q=this;this.$element.click(function
p(r){q.callModeFn();if(q.options.switchModesOnClick){q._incModeIndex()}$(this).html(q.options.modes[q.currModeIndex].html)});return
this.reset()};c.prototype._incModeIndex=function
l(){this.currModeIndex+=1;if(this.currModeIndex>=this.options.modes.length){this.currModeIndex=0}return
this};c.prototype._getModeIndex=function f(n){for(var
o=0;o<this.options.modes.length;o+=1){if(this.options.modes[o].mode===n){return
o}}throw new Error("mode not found: "+n)};c.prototype._setModeByIndex=function
m(n){var o=this.options.modes[n];if(!o){throw new Error("mode index not found:
"+n)}this.currModeIndex=n;if(o.html){this.$element.html(o.html)}return
this};c.prototype.currentMode=function d(){return
this.options.modes[this.currModeIndex]};c.prototype.current=function i(){return
this.currentMode().mode};c.prototype.getMode=function g(n){if(!n){return
this.currentMode()}return
this.options.modes[(this._getModeIndex(n))]};c.prototype.hasMode=function b(n){try{return
!!this.getMode(n)}catch(o){}return false};c.prototype.setMode=function a(n){return
this._setModeByIndex(this._getModeIndex(n))};c.prototype.reset=function
h(){this.currModeIndex=0;if(this.options.initialMode){this.currModeIndex=this._getModeIndex(this.options.initialMode)}return
this._setModeByIndex(this.currModeIndex)};c.prototype.callModeFn=function e(n){var
o=this.getMode(n).onclick;if(o&&jQuery.type(o==="function")){return
o.call(this.$element.get(0))}return undefined};jQuery.fn.extend({modeButton:function
k(n){if(!this.size()){return this}if(jQuery.type(n)==="object"){return
this.map(function(){var r=$(this);r.data("mode-button",new c(r,n));return
this})}var p=$(this[0]),o=p.data("mode-button");if(!o){throw new
Error("modeButton needs an options object or string name of a
function")}if(o&&jQuery.type(n)==="string"){var
q=n;if(o&&jQuery.type(o[q])==="function"){return
o[q].apply(o,jQuery.makeArray(arguments).slice(1))}}return o}})}());function
dropDownSelect(b,c){c=c||((!_.isEmpty(b))?(b[0]):(""));var a=$(['<div
class="dropdown-select btn-group">','<button
type="button" class="btn btn-default">','<span
class="dropdown-select-selected">'+c+"</span>","</button>","</div>"].join("\n"));if(b&&b.length>1){a.find("button").addClass("dropdown-toggle").attr("data-toggle","dropdown").append('
<span class="caret"></span>');a.append(['<ul
class="dropdown-menu"
role="menu">',_.map(b,function(e){return['<li><a
href="javascript:void(0)">',e,"</a></li>"].join("")}).join("\n"),"</ul>"].join("\n"))}function
d(g){var
h=$(this),f=h.parents(".dropdown-select"),e=h.text();f.find(".dropdown-select-selected").text(e);f.trigger("change.dropdown-select",e)}a.find("a").click(d);return
a}(function(){function e(k,j){return
this.init(k,j)}e.prototype.DATA_KEY="filter-control";e.prototype.init=function
g(k,j){j=j||{filters:[]};this.$element=$(k).addClass("filter-control
btn-group");this.options=jQuery.extend(true,{},this.defaults,j);this.currFilter=this.options.filters[0];return
this.render()};e.prototype.render=function
d(){this.$element.empty().append([this._renderKeySelect(),this._renderOpSelect(),this._renderValueInput()]);return
this};e.prototype._renderKeySelect=function a(){var j=this;var
k=this.options.filters.map(function(l){return
l.key});this.$keySelect=dropDownSelect(k,this.currFilter.key).addClass("filter-control-key").on("change.dropdown-select",function(m,l){j.currFilter=_.findWhere(j.options.filters,{key:l});j.render()._triggerChange()});return
this.$keySelect};e.prototype._renderOpSelect=function i(){var
j=this,k=this.currFilter.ops;this.$opSelect=dropDownSelect(k,k[0]).addClass("filter-control-op").on("change.dropdown-select",function(m,l){j._triggerChange()});return
this.$opSelect};e.prototype._renderValueInput=function c(){var
j=this;if(this.currFilter.values){this.$valueSelect=dropDownSelect(this.currFilter.values,this.currFilter.values[0]).on("change.dropdown-select",function(l,k){j._triggerChange()})}else{this.$valueSelect=$("<input/>").addClass("form-control").on("change",function(k,l){j._triggerChange()})}this.$valueSelect.addClass("filter-control-value");return
this.$valueSelect};e.prototype.val=function b(){var
k=this.$element.find(".filter-control-key
.dropdown-select-selected").text(),m=this.$element.find(".filter-control-op
.dropdown-select-selected").text(),j=this.$element.find(".filter-control-value"),l=(j.hasClass("dropdown-select"))?(j.find(".dropdown-select-selected").text()):(j.val());return{key:k,op:m,value:l}};e.prototype._triggerChange=function
h(){this.$element.trigger("change.filter-control",this.val())};jQuery.fn.extend({filterControl:function
f(k){var j=jQuery.makeArray(arguments).slice(1);return this.map(function(){var
n=$(this),m=n.data(e.prototype.DATA_KEY);if(jQuery.type(k)==="object"){m=new
e(n,k);n.data(e.prototype.DATA_KEY,m)}if(m&&jQuery.type(k)==="string"){var
l=m[k];if(jQuery.type(l)==="function"){return l.apply(m,j)}}return
this})}})}());(function(){function i(o,n){this.numPages=null;this.currPage=0;return
this.init(o,n)}i.prototype.DATA_KEY="pagination";i.prototype.defaults={startingPage:0,perPage:20,totalDataSize:null,currDataSize:null};i.prototype.init=function
g(n,o){o=o||{};this.$element=n;this.options=jQuery.extend(true,{},this.defaults,o);this.currPage=this.options.startingPage;if(this.options.totalDataSize!==null){this.numPages=Math.ceil(this.options.totalDataSize/this.options.perPage);if(this.currPage>=this.numPages){this.currPage=this.numPages-1}}this.$element.data(i.prototype.DATA_KEY,this);this._render();return
this};function m(n){return $(['<li><a
href="javascript:void(0);">',n,"</a></li>"].join(""))}i.prototype._render=function
e(){if(this.options.totalDataSize===0){return this}if(this.numPages===1){return
this}if(this.numPages>0){this._renderPages();this._scrollToActivePage()}else{this._renderPrevNext()}return
this};i.prototype._renderPrevNext=function b(){var
o=this,p=m("Prev"),n=m("Next"),q=$("<ul/>").addClass("pagination
pagination-prev-next");if(this.currPage===0){p.addClass("disabled")}else{p.click(function(){o.prevPage()})}if((this.numPages&&this.currPage===(this.numPages-1))||(this.options.currDataSize&&this.options.currDataSize<this.options.perPage)){n.addClass("disabled")}else{n.click(function(){o.nextPage()})}this.$element.html(q.append([p,n]));return
this.$element};i.prototype._renderPages=function a(){var
n=this,q=$("<div>").addClass("pagination-scroll-container"),s=$("<ul/>").addClass("pagination
pagination-page-list"),r=function(t){n.goToPage($(this).data("page"))};for(var
o=0;o<this.numPages;o+=1){var
p=m(o+1).attr("data-page",o).click(r);if(o===this.currPage){p.addClass("active")}s.append(p)}return
this.$element.html(q.html(s))};i.prototype._scrollToActivePage=function l(){var
p=this.$element.find(".pagination-scroll-container");if(!p.size()){return
this}var
o=this.$element.find("li.active"),n=p.width()/2;p.scrollLeft(p.scrollLeft()+o.position().left-n);return
this};i.prototype.goToPage=function
j(n){if(n<=0){n=0}if(this.numPages&&n>=this.numPages){n=this.numPages-1}if(n===this.currPage){return
this}this.currPage=n;this.$element.trigger("pagination.page-change",this.currPage);this._render();return
this};i.prototype.prevPage=function c(){return
this.goToPage(this.currPage-1)};i.prototype.nextPage=function h(){return
this.goToPage(this.currPage+1)};i.prototype.page=function f(){return
this.currPage};i.create=function k(n,o){return new
i(n,o)};jQuery.fn.extend({pagination:function d(o){var
n=jQuery.makeArray(arguments).slice(1);if(jQuery.type(o)==="object"){return
this.map(function(){i.create($(this),o);return this})}var
q=$(this[0]),r=q.data(i.prototype.DATA_KEY);if(r){if(jQuery.type(o)==="string"){var
p=r[o];if(jQuery.type(p)==="function"){return p.apply(r,n)}}else{return
r}}return undefined}})}());(function(){var
g={renameColumns:false,columnNames:[],commentChar:"#",hideCommentRows:false,includePrompts:true,topLeftContent:"Columns:"},s="peek-control.change",t="peek-control.rename",l="peek-control",v="control",f="control-prompt",c="selected",n="disabled",u="button",q="renamable-header",p="column-index",a="column-name";function
i(w){if(w.disabled&&jQuery.type(w.disabled)!=="array"){throw new
Error('"disabled" must be defined as an array of indeces:
'+JSON.stringify(w))}if(w.multiselect&&w.selected&&jQuery.type(w.selected)!=="array"){throw
new Error('Mulitselect rows need an array for "selected":
'+JSON.stringify(w))}if(!w.label||!w.id){throw new Error("Peek controls need a
label and id for each control row:
"+JSON.stringify(w))}if(w.disabled&&w.disabled.indexOf(w.selected)!==-1){throw
new Error("Selected column is in the list of disabled columns:
"+JSON.stringify(w))}return w}function o(x,w){return
$("<div/>").addClass(u).text(x.label)}function k(x,w){var
y=$("<td/>").html(o(x,w)).attr("data-"+p,w);if(x.disabled&&x.disabled.indexOf(w)!==-1){y.addClass(n)}return
y}function e(y,z,w){var
x=y.children("."+u);if(y.hasClass(c)){x.html((z.selectedText!==undefined)?(z.selectedText):(z.label))}else{x.html((z.unselectedText!==undefined)?(z.unselectedText):(z.label))}}function
h(z,x){var
y=k(z,x);if(z.selected===x){y.addClass(c)}e(y,z,x);if(!y.hasClass(n)){y.click(function
w(D){var E=$(this);if(!E.hasClass(c)){var
A=E.parent().children("."+c).removeClass(c);A.each(function(){e($(this),z,x)});E.addClass(c);e(E,z,x);var
C={},B=E.parent().attr("id"),F=E.data(p);C[B]=F;E.parents(".peek").trigger(s,C)}})}return
y}function m(z,x){var
y=k(z,x);if(z.selected&&z.selected.indexOf(x)!==-1){y.addClass(c)}e(y,z,x);if(!y.hasClass(n)){y.click(function
w(D){var E=$(this);E.toggleClass(c);e(E,z,x);var
C=E.parent().find("."+c).map(function(G,H){return $(H).data(p)});var
B={},A=E.parent().attr("id"),F=jQuery.makeArray(C);B[A]=F;E.parents(".peek").trigger(s,B)})}return
y}function j(y,z){var w=[];for(var
x=0;x<y;x+=1){w.push(z.multiselect?m(z,x):h(z,x))}return w}function r(y,z,x){var
A=$("<tr/>").attr("id",z.id).addClass(v);if(x){var
w=$("<td/>").addClass(f).text(z.label+":");A.append(w)}A.append(j(y,z));return
A}function b(E){E=jQuery.extend(true,{},g,E);var
D=$(this).addClass(l),A=D.find("table"),z=A.find("th").size(),C=A.find("tr").size(),w=A.find("td[colspan]").map(function(H,F){var
G=$(this);if(G.text()&&G.text().match(new
RegExp("^"+E.commentChar))){return
$(this).css("color","grey").parent().get(0)}return
null});if(E.hideCommentRows){w.hide();C-=w.size()}if(E.includePrompts){var
y=$("<th/>").addClass("top-left").text(E.topLeftContent).attr("rowspan",C);A.find("tr").first().prepend(y)}var
B=A.find("th:not(.top-left)").each(function(G,I){var
H=$(this),J=H.text().replace(/^\d+\.*/,""),F=E.columnNames[G]||J;H.attr("data-"+a,F).text((G+1)+((F)?("."+F):("")))});if(E.renameColumns){B.addClass(q).click(function
x(){var G=$(this),F=G.index()+(E.includePrompts?0:1),I=G.data(a),H=prompt("New column
name:",I);if(H!==null&&H!==I){G.text(F+(H?("."+H):"")).data(a,H).attr("data-",a,H);var
J=jQuery.makeArray(G.parent().children("th:not(.top-left)").map(function(){return
$(this).data(a)}));G.parents(".peek").trigger(t,J)}})}E.controls.forEach(function(G,F){i(G);var
H=r(z,G,E.includePrompts);A.find("tbody").append(H)});return
this}jQuery.fn.extend({peekControl:function d(w){return this.map(function(){return
b.call(this,w)})}})}());
\ No newline at end of file
+var
IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var
IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var
a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return
this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return
false}return true},template:function(b){var a='title="'+b.title+'"
class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+="
"+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+='
id="'+b.id+'"'}a+='
href="'+b.href+'"';if(b.target){a+='
target="'+b.target+'"'}if(!b.visible){a+=' style="display:
none;"'}if(b.enabled){a="<a
"+a+"/>"}else{a="<span "+a+"/>"}return
$(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var
IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var
a=this;this.collection.each(function(d){var
b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button
menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var
c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var
create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new
IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return
new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var
GridView=Backbone.View.extend({});var
PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var
c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return
false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var
a=this;this.$el.find("li").each(function(c,b){var
d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return
this},template:function(b,a){return['<ul id="',b,'-menu"
class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no
options)</li>"}return _.map(a,function(d){if(d.divider){return'<li
class="divider"></li>'}else{if(d.header){return['<li
class="head"><a
href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var
c=d.href||"javascript:void(0);",e=(d.target)?('
target="'+d.target+'"'):(""),b=(d.checked)?('<span
class="fa
fa-check"></span>'):("");return['<li><a
class="popupmenu-option"
href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var
c=this.$el.width();var
a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var
c=this;function
a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return
this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return
this},findIndexByHtml:function(b){for(var
a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return
a}}return null},findItemByHtml:function(a){return
this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function
_create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var
a=[];_.each(c,function(f,d){var
e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return
new
PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var
b=[];c.find(a).each(function(g,e){var
f={},d=$(g);f.html=d.text();if(d.attr("href")){var
j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return
b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var
b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new
PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var
a=[];$(c).find(b).each(function(){var
e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return
a};var
faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var
b=['<a class="',a.classes.join("
"),'"',((a.title)?('
title="'+a.title+'"'):("")),((!a.disabled&&a.target)?('
target="'+a.target+'"'):("")),'
href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span
class="fa
',a.faIcon,'"></span>',"</a>"].join("");var
c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return
c};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function
d(){var e=['<div class="loading-indicator">','<div
class="loading-indicator-text">','<span class="fa fa-spinner
fa-spin fa-lg"></span>','<span
class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var
g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px
0px 0px
10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px
8px 0px 0px","font-style":"italic"})}return
g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return
b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return
b};return b}(function(){var b=window._l||function(d){return d};function a(k,q){var
e=27,n=13,d=$(k),f=true,h={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(r){},minSearchLen:0,escWillClear:true,oninit:function(){}};function
j(r){var
s=$(this).parent().children("input");s.val("");s.trigger("clear:searchInput");q.onclear()}function
p(s,r){$(this).trigger("search:searchInput",r);if(typeof
q.onfirstsearch==="function"&&f){f=false;q.onfirstsearch(r)}else{q.onsearch(r)}}function
g(){return['<input type="text" name="',q.name,'"
placeholder="',q.placeholder,'" ','class="search-query
',q.classes,'" ',"/>"].join("")}function
m(){return
$(g()).focus(function(r){$(this).select()}).keyup(function(s){s.preventDefault();s.stopPropagation();if(!$(this).val()){$(this).blur()}if(s.which===e&&q.escWillClear){j.call(this,s)}else{var
r=$(this).val();if((s.which===n)||(q.minSearchLen&&r.length>=q.minSearchLen)){p.call(this,s,r)}else{if(!r.length){j.call(this,s)}}}}).val(q.initialVal)}function
l(){return $(['<span class="search-clear fa fa-times-circle"
','title="',b("clear search
(esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(r){j.call(this,r)})}function
o(){return $(['<span class="search-loading fa fa-spinner fa-spin"
','title="',b("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function
i(){d.find(".search-loading").toggle();d.find(".search-clear").toggle()}if(jQuery.type(q)==="string"){if(q==="toggle-loading"){i()}return
d}if(jQuery.type(q)==="object"){q=jQuery.extend(true,{},h,q)}return
d.addClass("search-input").prepend([m(),l(),o()])}jQuery.fn.extend({searchInput:function
c(d){return this.each(function(){return a(this,d)})}})}());(function(){function
c(o,n){this.currModeIndex=0;return
this._init(o,n)}c.prototype.DATA_KEY="mode-button";c.prototype.defaults={switchModesOnClick:true};c.prototype._init=function
j(o,n){n=n||{};this.$element=$(o);this.options=jQuery.extend(true,{},this.defaults,n);if(!n.modes){throw
new Error('ModeButton requires a "modes" array')}var
q=this;this.$element.click(function
p(r){q.callModeFn();if(q.options.switchModesOnClick){q._incModeIndex()}$(this).html(q.options.modes[q.currModeIndex].html)});return
this.reset()};c.prototype._incModeIndex=function
l(){this.currModeIndex+=1;if(this.currModeIndex>=this.options.modes.length){this.currModeIndex=0}return
this};c.prototype._getModeIndex=function f(n){for(var
o=0;o<this.options.modes.length;o+=1){if(this.options.modes[o].mode===n){return
o}}throw new Error("mode not found: "+n)};c.prototype._setModeByIndex=function
m(n){var o=this.options.modes[n];if(!o){throw new Error("mode index not found:
"+n)}this.currModeIndex=n;if(o.html){this.$element.html(o.html)}return
this};c.prototype.currentMode=function d(){return
this.options.modes[this.currModeIndex]};c.prototype.current=function i(){return
this.currentMode().mode};c.prototype.getMode=function g(n){if(!n){return
this.currentMode()}return
this.options.modes[(this._getModeIndex(n))]};c.prototype.hasMode=function b(n){try{return
!!this.getMode(n)}catch(o){}return false};c.prototype.setMode=function a(n){return
this._setModeByIndex(this._getModeIndex(n))};c.prototype.reset=function
h(){this.currModeIndex=0;if(this.options.initialMode){this.currModeIndex=this._getModeIndex(this.options.initialMode)}return
this._setModeByIndex(this.currModeIndex)};c.prototype.callModeFn=function e(n){var
o=this.getMode(n).onclick;if(o&&jQuery.type(o==="function")){return
o.call(this.$element.get(0))}return undefined};jQuery.fn.extend({modeButton:function
k(n){if(!this.size()){return this}if(jQuery.type(n)==="object"){return
this.map(function(){var r=$(this);r.data("mode-button",new c(r,n));return
this})}var p=$(this[0]),o=p.data("mode-button");if(!o){throw new
Error("modeButton needs an options object or string name of a
function")}if(o&&jQuery.type(n)==="string"){var
q=n;if(o&&jQuery.type(o[q])==="function"){return
o[q].apply(o,jQuery.makeArray(arguments).slice(1))}}return o}})}());function
dropDownSelect(b,c){c=c||((!_.isEmpty(b))?(b[0]):(""));var a=$(['<div
class="dropdown-select btn-group">','<button
type="button" class="btn btn-default">','<span
class="dropdown-select-selected">'+c+"</span>","</button>","</div>"].join("\n"));if(b&&b.length>1){a.find("button").addClass("dropdown-toggle").attr("data-toggle","dropdown").append('
<span class="caret"></span>');a.append(['<ul
class="dropdown-menu"
role="menu">',_.map(b,function(e){return['<li><a
href="javascript:void(0)">',e,"</a></li>"].join("")}).join("\n"),"</ul>"].join("\n"))}function
d(g){var
h=$(this),f=h.parents(".dropdown-select"),e=h.text();f.find(".dropdown-select-selected").text(e);f.trigger("change.dropdown-select",e)}a.find("a").click(d);return
a}(function(){function e(k,j){return
this.init(k,j)}e.prototype.DATA_KEY="filter-control";e.prototype.init=function
g(k,j){j=j||{filters:[]};this.$element=$(k).addClass("filter-control
btn-group");this.options=jQuery.extend(true,{},this.defaults,j);this.currFilter=this.options.filters[0];return
this.render()};e.prototype.render=function
d(){this.$element.empty().append([this._renderKeySelect(),this._renderOpSelect(),this._renderValueInput()]);return
this};e.prototype._renderKeySelect=function a(){var j=this;var
k=this.options.filters.map(function(l){return
l.key});this.$keySelect=dropDownSelect(k,this.currFilter.key).addClass("filter-control-key").on("change.dropdown-select",function(m,l){j.currFilter=_.findWhere(j.options.filters,{key:l});j.render()._triggerChange()});return
this.$keySelect};e.prototype._renderOpSelect=function i(){var
j=this,k=this.currFilter.ops;this.$opSelect=dropDownSelect(k,k[0]).addClass("filter-control-op").on("change.dropdown-select",function(m,l){j._triggerChange()});return
this.$opSelect};e.prototype._renderValueInput=function c(){var
j=this;if(this.currFilter.values){this.$valueSelect=dropDownSelect(this.currFilter.values,this.currFilter.values[0]).on("change.dropdown-select",function(l,k){j._triggerChange()})}else{this.$valueSelect=$("<input/>").addClass("form-control").on("change",function(k,l){j._triggerChange()})}this.$valueSelect.addClass("filter-control-value");return
this.$valueSelect};e.prototype.val=function b(){var
k=this.$element.find(".filter-control-key
.dropdown-select-selected").text(),m=this.$element.find(".filter-control-op
.dropdown-select-selected").text(),j=this.$element.find(".filter-control-value"),l=(j.hasClass("dropdown-select"))?(j.find(".dropdown-select-selected").text()):(j.val());return{key:k,op:m,value:l}};e.prototype._triggerChange=function
h(){this.$element.trigger("change.filter-control",this.val())};jQuery.fn.extend({filterControl:function
f(k){var j=jQuery.makeArray(arguments).slice(1);return this.map(function(){var
n=$(this),m=n.data(e.prototype.DATA_KEY);if(jQuery.type(k)==="object"){m=new
e(n,k);n.data(e.prototype.DATA_KEY,m)}if(m&&jQuery.type(k)==="string"){var
l=m[k];if(jQuery.type(l)==="function"){return l.apply(m,j)}}return
this})}})}());(function(){function i(o,n){this.numPages=null;this.currPage=0;return
this.init(o,n)}i.prototype.DATA_KEY="pagination";i.prototype.defaults={startingPage:0,perPage:20,totalDataSize:null,currDataSize:null};i.prototype.init=function
g(n,o){o=o||{};this.$element=n;this.options=jQuery.extend(true,{},this.defaults,o);this.currPage=this.options.startingPage;if(this.options.totalDataSize!==null){this.numPages=Math.ceil(this.options.totalDataSize/this.options.perPage);if(this.currPage>=this.numPages){this.currPage=this.numPages-1}}this.$element.data(i.prototype.DATA_KEY,this);this._render();return
this};function m(n){return $(['<li><a
href="javascript:void(0);">',n,"</a></li>"].join(""))}i.prototype._render=function
e(){if(this.options.totalDataSize===0){return this}if(this.numPages===1){return
this}if(this.numPages>0){this._renderPages();this._scrollToActivePage()}else{this._renderPrevNext()}return
this};i.prototype._renderPrevNext=function b(){var
o=this,p=m("Prev"),n=m("Next"),q=$("<ul/>").addClass("pagination
pagination-prev-next");if(this.currPage===0){p.addClass("disabled")}else{p.click(function(){o.prevPage()})}if((this.numPages&&this.currPage===(this.numPages-1))||(this.options.currDataSize&&this.options.currDataSize<this.options.perPage)){n.addClass("disabled")}else{n.click(function(){o.nextPage()})}this.$element.html(q.append([p,n]));return
this.$element};i.prototype._renderPages=function a(){var
n=this,q=$("<div>").addClass("pagination-scroll-container"),s=$("<ul/>").addClass("pagination
pagination-page-list"),r=function(t){n.goToPage($(this).data("page"))};for(var
o=0;o<this.numPages;o+=1){var
p=m(o+1).attr("data-page",o).click(r);if(o===this.currPage){p.addClass("active")}s.append(p)}return
this.$element.html(q.html(s))};i.prototype._scrollToActivePage=function l(){var
p=this.$element.find(".pagination-scroll-container");if(!p.size()){return
this}var
o=this.$element.find("li.active"),n=p.width()/2;p.scrollLeft(p.scrollLeft()+o.position().left-n);return
this};i.prototype.goToPage=function
j(n){if(n<=0){n=0}if(this.numPages&&n>=this.numPages){n=this.numPages-1}if(n===this.currPage){return
this}this.currPage=n;this.$element.trigger("pagination.page-change",this.currPage);this._render();return
this};i.prototype.prevPage=function c(){return
this.goToPage(this.currPage-1)};i.prototype.nextPage=function h(){return
this.goToPage(this.currPage+1)};i.prototype.page=function f(){return
this.currPage};i.create=function k(n,o){return new
i(n,o)};jQuery.fn.extend({pagination:function d(o){var
n=jQuery.makeArray(arguments).slice(1);if(jQuery.type(o)==="object"){return
this.map(function(){i.create($(this),o);return this})}var
q=$(this[0]),r=q.data(i.prototype.DATA_KEY);if(r){if(jQuery.type(o)==="string"){var
p=r[o];if(jQuery.type(p)==="function"){return p.apply(r,n)}}else{return
r}}return undefined}})}());(function(){var
g={renameColumns:false,columnNames:[],commentChar:"#",hideCommentRows:false,includePrompts:true,topLeftContent:"Columns:"},s="peek-control.change",t="peek-control.rename",l="peek-control",v="control",f="control-prompt",c="selected",n="disabled",u="button",q="renamable-header",p="column-index",a="column-name";function
i(w){if(w.disabled&&jQuery.type(w.disabled)!=="array"){throw new
Error('"disabled" must be defined as an array of indeces:
'+JSON.stringify(w))}if(w.multiselect&&w.selected&&jQuery.type(w.selected)!=="array"){throw
new Error('Mulitselect rows need an array for "selected":
'+JSON.stringify(w))}if(!w.label||!w.id){throw new Error("Peek controls need a
label and id for each control row:
"+JSON.stringify(w))}if(w.disabled&&w.disabled.indexOf(w.selected)!==-1){throw
new Error("Selected column is in the list of disabled columns:
"+JSON.stringify(w))}return w}function o(x,w){return
$("<div/>").addClass(u).text(x.label)}function k(x,w){var
y=$("<td/>").html(o(x,w)).attr("data-"+p,w);if(x.disabled&&x.disabled.indexOf(w)!==-1){y.addClass(n)}return
y}function e(y,z,w){var
x=y.children("."+u);if(y.hasClass(c)){x.html((z.selectedText!==undefined)?(z.selectedText):(z.label))}else{x.html((z.unselectedText!==undefined)?(z.unselectedText):(z.label))}}function
h(z,x){var
y=k(z,x);if(z.selected===x){y.addClass(c)}e(y,z,x);if(!y.hasClass(n)){y.click(function
w(D){var E=$(this);if(!E.hasClass(c)){var
A=E.parent().children("."+c).removeClass(c);A.each(function(){e($(this),z,x)});E.addClass(c);e(E,z,x);var
C={},B=E.parent().attr("id"),F=E.data(p);C[B]=F;E.parents(".peek").trigger(s,C)}})}return
y}function m(z,x){var
y=k(z,x);if(z.selected&&z.selected.indexOf(x)!==-1){y.addClass(c)}e(y,z,x);if(!y.hasClass(n)){y.click(function
w(D){var E=$(this);E.toggleClass(c);e(E,z,x);var
C=E.parent().find("."+c).map(function(G,H){return $(H).data(p)});var
B={},A=E.parent().attr("id"),F=jQuery.makeArray(C);B[A]=F;E.parents(".peek").trigger(s,B)})}return
y}function j(y,z){var w=[];for(var
x=0;x<y;x+=1){w.push(z.multiselect?m(z,x):h(z,x))}return w}function r(y,z,x){var
A=$("<tr/>").attr("id",z.id).addClass(v);if(x){var
w=$("<td/>").addClass(f).text(z.label+":");A.append(w)}A.append(j(y,z));return
A}function b(E){E=jQuery.extend(true,{},g,E);var
D=$(this).addClass(l),A=D.find("table"),z=A.find("th").size(),C=A.find("tr").size(),w=A.find("td[colspan]").map(function(H,F){var
G=$(this);if(G.text()&&G.text().match(new
RegExp("^"+E.commentChar))){return
$(this).css("color","grey").parent().get(0)}return
null});if(E.hideCommentRows){w.hide();C-=w.size()}if(E.includePrompts){var
y=$("<th/>").addClass("top-left").text(E.topLeftContent).attr("rowspan",C);A.find("tr").first().prepend(y)}var
B=A.find("th:not(.top-left)").each(function(G,I){var
H=$(this),J=H.text().replace(/^\d+\.*/,""),F=E.columnNames[G]||J;H.attr("data-"+a,F).text((G+1)+((F)?("."+F):("")))});if(E.renameColumns){B.addClass(q).click(function
x(){var G=$(this),F=G.index()+(E.includePrompts?0:1),I=G.data(a),H=prompt("New column
name:",I);if(H!==null&&H!==I){G.text(F+(H?("."+H):"")).data(a,H).attr("data-",a,H);var
J=jQuery.makeArray(G.parent().children("th:not(.top-left)").map(function(){return
$(this).data(a)}));G.parents(".peek").trigger(t,J)}})}E.controls.forEach(function(G,F){i(G);var
H=r(z,G,E.includePrompts);A.find("tbody").append(H)});return
this}jQuery.fn.extend({peekControl:function d(w){return this.map(function(){return
b.call(this,w)})}})}());
\ No newline at end of file
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1428,7 +1428,7 @@
.pagination-scroll-container
.pagination-page-list>li:last-child>a,.pagination-scroll-container
.pagination-page-list>li:last-child>span{border-radius:0px}
.pagination-scroll-container
.pagination-page-list>li>a{float:none;position:static;border:1px solid
#BFBFBF;border-width:0px 0px 0px 1px}
.peek-control{border-radius:3px;border:1px solid #5f6990}
-.peek-control td,th{padding:4px 10px 4px 4px}
+.peek-control td,.peek-control th{padding:4px 10px 4px 4px}
.peek-control th:last-child{width:100%}
.peek-control
.top-left{width:10%;white-space:normal;vertical-align:top;text-align:right;font-family:"Lucida
Grande",verdana,arial,helvetica,sans-serif;font-weight:normal}
.peek-control .renamable-header:hover{background-color:black}
@@ -1625,6 +1625,13 @@
.icon-button.link{background:url(../images/silk/link.png)
no-repeat;cursor:pointer;float:none;display:inline-block;margin-left:10px}
.icon-button.link-broken{background:url(../images/silk/link_break.png)
no-repeat;cursor:pointer;float:none;display:inline-block;margin-left:10px}
.workflow-invocation-complete{border:solid 1px #6A6;border-left-width:5px;margin:10px
0;padding-left:5px}
+.icon-btn{display:inline-block;height:22px;width:22px;text-align:center;line-height:19px;font-size:1.2em;border-radius:3px;border:1px
solid #bfbfbf;background-color:#f2f2f2;color:#333;cursor:pointer}
+.icon-btn:hover{background-color:white;color:maroon}
+.icon-btn.disabled{background-color:transparent;color:#BBB;border-color:#BBB}
+.icon-btn-group{display:inline-block}.icon-btn-group
.icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
+.icon-btn-group
.icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
+.icon-btn-group .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px}
+.icon-btn-group .icon-btn:only-child{margin:0px;border-radius:3px}
.list-item{border:1px solid #bfbfbf}.list-item .vertical-spacing{margin-bottom:8px}
.list-item .info-section{border-radius:3px;border:1px solid
rgba(153,153,153,0.30000000000000004);padding:4px}
.list-item .padded{padding:6px 10px 6px 8px}
@@ -1642,13 +1649,22 @@
.list-item .details label{margin:0px;padding:0px;font-weight:normal}
.list-item .details .prompt{font-weight:normal;color:#555}
.list-item .details .prompt:after{content:':';margin-right:4px}
-.icon-btn{display:inline-block;height:22px;width:22px;text-align:center;line-height:19px;font-size:1.2em;border-radius:3px;border:1px
solid #bfbfbf;background-color:#f2f2f2;color:#333;cursor:pointer}
-.icon-btn:hover{background-color:white;color:maroon}
-.icon-btn.disabled{background-color:transparent;color:#BBB;border-color:#BBB}
-.icon-btn-group{display:inline-block}.icon-btn-group
.icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
-.icon-btn-group
.icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
-.icon-btn-group .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px}
-.icon-btn-group .icon-btn:only-child{margin:0px;border-radius:3px}
+.list-panel .controls>*:not(:empty){margin-bottom:8px}
+.list-panel .controls .name{word-wrap:break-word;font-weight:bold}
+.list-panel .controls .subtitle{color:grey}.list-panel .controls
.subtitle:not(:empty){margin-top:-8px}
+.list-panel .controls .actions{display:inline-block;float:right}.list-panel .controls
.actions .icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
+.list-panel .controls .actions
.icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
+.list-panel .controls .actions .icon-btn:last-child{margin-left:0px;border-radius:0px 3px
3px 0px}
+.list-panel .controls .actions .icon-btn:only-child{margin:0px;border-radius:3px}
+.list-panel .controls .actions .icon-btn{margin-left:2px}
+.list-panel .controls .messages [class$=message]{margin:0px}.list-panel .controls
.messages [class$=message]:not(:last-child){margin-bottom:8px}
+.list-panel .controls .list-actions{display:none}.list-panel .controls
.list-actions:before,.list-panel .controls .list-actions:after{content:"
";display:table;}
+.list-panel .controls .list-actions:after{clear:both}
+.list-panel .controls .list-actions:before,.list-panel .controls
.list-actions:after{content:" ";display:table;}
+.list-panel .controls .list-actions:after{clear:both}
+.list-panel .controls .list-actions
.btn{padding-top:2px;padding-bottom:2px;font-size:90%}
+.list-panel .list-items .list-item:not(:last-child){border-bottom-width:0px}
+.list-panel .empty-message{display:none;margin:0px}
.search-input .search-query{width:100%;padding-right:24px}
.search-input .search-clear,.search-input
.search-loading{position:relative;display:inline-block;float:right;margin-top:-24px;margin-right:4px;font-size:1.4em;line-height:23px;color:grey}
.search-input .search-clear:hover{color:#303030}
@@ -1857,6 +1873,20 @@
.collection-creator .footer .attributes
.collection-name-prompt.validation-warning:before{content:'(required)';margin-right:4px;color:red}
.collection-creator .footer .attributes .collection-name{width:50%}.collection-creator
.footer .attributes .collection-name.validation-warning{border-color:red}
.collection-creator .footer .actions .other-options>*{display:none;margin-left:4px}
+.dataset-choice{border:1px solid lightgrey;border-radius:3px;overflow:hidden;padding:10px
8px 8px
8px}.dataset-choice:hover{border-color:black;cursor:pointer}.dataset-choice:hover>*{cursor:pointer}
+.dataset-choice .prompt{margin-right:8px}.dataset-choice
.prompt:after{content:':'}
+.dataset-choice .prompt:empty{display:none}
+.dataset-choice .none-selected-msg{color:grey}
+.dataset-choice .selected{display:inline-block}.dataset-choice .selected
.title{font-weight:bold}
+.dataset-choice .selected .subtitle{color:grey}.dataset-choice .selected
.subtitle:before{content:'-';margin:0px 4px 0px 4px}
+.dataset-choice .selected .subtitle i{font-style:normal}.dataset-choice .selected
.subtitle i:not(:last-child):after{content:', '}
+.dataset-choice.multi .selected{display:block;font-weight:normal}
+.dataset-choice.multi
table{width:100%;margin-top:8px;cursor:pointer}.dataset-choice.multi
table:hover{border-color:black}
+.dataset-choice.multi table tr:nth-child(even){background-color:aliceblue}
+.dataset-choice.multi table th{padding:0px;font-weight:normal;font-size:80%;color:grey}
+.dataset-choice.multi table th:not(:last-child),.dataset-choice.multi table
td:not(:last-child){padding-right:8px}
+.dataset-choice.multi table td.cell-name{font-weight:bold}
+.dataset-choice-modal .list-panel .controls .title .name{font-size:120%}
.toolMenuContainer{color:#000;background:#dfe5f9;min-height:100%;padding:5px 10px}
div.toolSectionPad{margin:0;padding:0;height:5px;font-size:0px}
div.toolSectionWrapper{margin-bottom:5px}
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/style/src/less/base.less
--- a/static/style/src/less/base.less
+++ b/static/style/src/less/base.less
@@ -551,7 +551,8 @@
border: 1px solid rgb(95, 105, 144);
}
-.peek-control td, th {
+.peek-control td,
+.peek-control th {
padding: 4px 10px 4px 4px;
}
@@ -1551,16 +1552,18 @@
padding-left:5px;
}
-// ==== History styles ====
+// ============================================================================ History
@import "sprite-history-states.less";
@import "sprite-history-buttons.less";
+@import "ui/icon-btn.less";
@import "list-item.less";
@import "history.less";
@import "collections.less";
@import "ui/paired-collection-creator.less";
+@import "ui/dataset-choice.less";
// ==== Tool menu styles
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/style/src/less/history.less
--- a/static/style/src/less/history.less
+++ b/static/style/src/less/history.less
@@ -1,89 +1,3 @@
-// trello-ish style
-//@icon-btn-size: 18px;
-//@icon-btn-margin: 2px;
-//@icon-btn-color: #AAA;
-//@icon-btn-bg: @btn-default-bg;
-//@icon-btn-border: lightgrey;
-
-// no bg
-//@icon-btn-size: 16px;
-//@icon-btn-margin: 0px;
-//@icon-btn-color: #444;
-//@icon-btn-bg: transparent;
-//@icon-btn-border: transparent;
-
-// dark bg
-//@icon-btn-size: 16px;
-//@icon-btn-margin: 1px;
-//@icon-btn-color: @link-color;
-//@icon-btn-bg: rgba( 0, 0, 0, 0.1 );
-//@icon-btn-border: transparent;
-
-// big & dark style
-@icon-btn-size: 22px;
-@icon-btn-margin: 2px;
-@icon-btn-color: @btn-default-color;
-//@icon-btn-bg: transparent;
-@icon-btn-bg: @btn-default-bg;
-@icon-btn-border: @btn-default-border;
-
-.icon-btn {
- display : inline-block;
- height : @icon-btn-size;
- width : @icon-btn-size;
- // center the icon
- text-align: center;
- line-height: @icon-btn-size - 3;
- font-size: 1.2em;
-
- // colors and borders
- border-radius: 3px;
- border: 1px solid @icon-btn-border;
- background-color: @icon-btn-bg;
- color : @icon-btn-color;
-
- cursor: pointer;
-
- // tweaks
- //TODO: not working - span
- //.fa-comment {
- // display: inline-block;
- // margin-bottom: 4px;
- //}
-}
-.icon-btn:hover {
- background-color: white;
- color: maroon;
-}
-.icon-btn.disabled {
- background-color: transparent;
- color: #BBB;
- border-color: #BBB;
- //color: @icon-btn-border;
-}
-.icon-btn-group {
- display: inline-block;
- .icon-btn:not(:last-child) {
- margin: 0px;
- border-radius: 0px;
- border-right: none;
- }
- .icon-btn:first-child {
- margin-right: 0px;
- border-top-left-radius: 3px;
- border-bottom-left-radius: 3px;
- }
- .icon-btn:last-child {
- margin-left: 0px;
- border-radius: 0px 3px 3px 0px;
- }
- .icon-btn:only-child {
- margin: 0px;
- border-radius: 3px;
- }
-}
-
-
// ---------------------------------------------------------------------------- search
bar
.search-input {
.search-query {
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/style/src/less/list-item.less
--- a/static/style/src/less/list-item.less
+++ b/static/style/src/less/list-item.less
@@ -98,3 +98,69 @@
}
}
+// ---------------------------------------------------------------------------- generic
panel list (of list-items)
+.list-panel {
+
+ .controls {
+ & > *:not(:empty) {
+ margin-bottom: 8px;
+ }
+ .title {
+ }
+ .name {
+ word-wrap: break-word;
+ font-weight: bold;
+ }
+
+ .subtitle {
+ color: grey;
+ &:not(:empty) {
+ margin-top: -8px;
+ }
+ }
+
+ .actions {
+ .icon-btn-group();
+ float: right;
+ .icon-btn {
+ margin-left: @icon-btn-margin;
+ }
+ }
+
+ .messages {
+ [class$=message] {
+ margin: 0px;
+ &:not(:last-child) {
+ margin-bottom: 8px;
+ }
+ }
+ }
+
+ .search {
+ }
+
+ .list-actions {
+ display: none;
+ .clear;
+ .btn {
+ padding-top: 2px;
+ padding-bottom: 2px;
+ font-size: 90%;
+ }
+ }
+ }
+
+ // display only a top border on all
+ .list-items {
+ .list-item {
+ &:not(:last-child) {
+ border-bottom-width: 0px;
+ }
+ }
+ }
+
+ .empty-message {
+ display: none;
+ margin: 0px;
+ }
+}
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/style/src/less/ui/dataset-choice.less
--- /dev/null
+++ b/static/style/src/less/ui/dataset-choice.less
@@ -0,0 +1,88 @@
+// component to display a dataset choice and activate a modal chooser (single *and*
multiple datasets)
+.dataset-choice {
+ border: 1px solid lightgrey;
+ border-radius: 3px;
+ overflow: hidden;
+ padding: 10px 8px 8px 8px;
+
+ &:hover {
+ border-color: black;
+ cursor: pointer;
+ & > * {
+ cursor: pointer;
+ }
+ }
+ .prompt {
+ margin-right: 8px;
+ &:after {
+ content: ':';
+ }
+ &:empty {
+ display: none;
+ }
+ }
+ .none-selected-msg {
+ color: grey;
+ }
+
+ .selected {
+ display: inline-block;
+
+ .title {
+ font-weight: bold;
+ }
+ .subtitle {
+ color: grey;
+ &:before {
+ content: '-';
+ margin: 0px 4px 0px 4px;
+ }
+ i {
+ font-style: normal;
+ &:not(:last-child):after {
+ content: ', ';
+ }
+ }
+ }
+ }
+}
+
+// component to display a dataset choice and activate a modal chooser (multiple
datasets)
+.dataset-choice.multi {
+ .selected {
+ display: block;
+ font-weight: normal;
+ }
+
+ table {
+ width: 100%;
+ margin-top: 8px;
+ cursor: pointer;
+
+ &:hover {
+ border-color: black;
+ }
+ tr:nth-child(even) {
+ background-color: aliceblue;
+ }
+ th {
+ padding: 0px;
+ font-weight: normal;
+ font-size: 80%;
+ color: grey;
+ }
+ th:not(:last-child),
+ td:not(:last-child) {
+ padding-right: 8px;
+ }
+ td.cell-name {
+ font-weight: bold;
+ }
+ }
+}
+
+// modal allowing single or multiple dataset selection - often activated by
.dataset-choice above
+.dataset-choice-modal .list-panel .controls .title .name {
+ font-size: 120%;
+}
+
diff -r b7fb63b197362424b39c2cc73d1589a0e383443e -r
737f78bb4a4581630734a693d6675daaae35b641 static/style/src/less/ui/icon-btn.less
--- /dev/null
+++ b/static/style/src/less/ui/icon-btn.less
@@ -0,0 +1,84 @@
+// trello-ish style
+//@icon-btn-size: 18px;
+//@icon-btn-margin: 2px;
+//@icon-btn-color: #AAA;
+//@icon-btn-bg: @btn-default-bg;
+//@icon-btn-border: lightgrey;
+
+// no bg
+//@icon-btn-size: 16px;
+//@icon-btn-margin: 0px;
+//@icon-btn-color: #444;
+//@icon-btn-bg: transparent;
+//@icon-btn-border: transparent;
+
+// dark bg
+//@icon-btn-size: 16px;
+//@icon-btn-margin: 1px;
+//@icon-btn-color: @link-color;
+//@icon-btn-bg: rgba( 0, 0, 0, 0.1 );
+//@icon-btn-border: transparent;
+
+// big & dark style
+@icon-btn-size: 22px;
+@icon-btn-margin: 2px;
+@icon-btn-color: @btn-default-color;
+//@icon-btn-bg: transparent;
+@icon-btn-bg: @btn-default-bg;
+@icon-btn-border: @btn-default-border;
+
+.icon-btn {
+ display : inline-block;
+ height : @icon-btn-size;
+ width : @icon-btn-size;
+ // center the icon
+ text-align: center;
+ line-height: @icon-btn-size - 3;
+ font-size: 1.2em;
+
+ // colors and borders
+ border-radius: 3px;
+ border: 1px solid @icon-btn-border;
+ background-color: @icon-btn-bg;
+ color : @icon-btn-color;
+
+ cursor: pointer;
+
+ // tweaks
+ //TODO: not working - span
+ //.fa-comment {
+ // display: inline-block;
+ // margin-bottom: 4px;
+ //}
+}
+.icon-btn:hover {
+ background-color: white;
+ color: maroon;
+}
+.icon-btn.disabled {
+ background-color: transparent;
+ color: #BBB;
+ border-color: #BBB;
+ //color: @icon-btn-border;
+}
+.icon-btn-group {
+ display: inline-block;
+ .icon-btn:not(:last-child) {
+ margin: 0px;
+ border-radius: 0px;
+ border-right: none;
+ }
+ .icon-btn:first-child {
+ margin-right: 0px;
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ }
+ .icon-btn:last-child {
+ margin-left: 0px;
+ border-radius: 0px 3px 3px 0px;
+ }
+ .icon-btn:only-child {
+ margin: 0px;
+ border-radius: 3px;
+ }
+}
https://bitbucket.org/galaxy/galaxy-central/commits/ece8ef90a828/
Changeset: ece8ef90a828
User: carlfeberhard
Date: 2014-08-26 18:59:59
Summary: (add packed scripts)
Affected #: 3 files
diff -r 737f78bb4a4581630734a693d6675daaae35b641 -r
ece8ef90a8289399bf9faca6a3265696da7e0beb
static/scripts/packed/mvc/dataset/dataset-choice.js
--- /dev/null
+++ b/static/scripts/packed/mvc/dataset/dataset-choice.js
@@ -0,0 +1,1 @@
+define(["mvc/dataset/dataset-model","mvc/dataset/dataset-list","mvc/ui/ui-modal","mvc/base-mvc","utils/localization"],function(a,d,f,i,c){function
g(k,j,m){function l(p,o){for(var n in o){if(o.hasOwnProperty(n)){if(p[n]!==o[n]){return
false}}}return true}return
k.filter(function(n){return(!n.deleted&&n.visible)&&(!m||n.collection_type===undefined)&&(l(n,j))})}var
b=function(n,j){j=_.defaults(j||{},{datasetsOnly:true,where:{state:"ok"},multiselect:false,selected:[]});j.title=j.title||(j.multiselect?c("Choose
datasets:"):c("Choose a dataset:"));var
m,o,l,q=jQuery.Deferred(),p=j.filter||g;n=p(n,j.where,j.datasetsOnly);if(!n.length){return
q.reject("No matches found")}function
k(){q.resolve(o.getSelectedModels().map(function(r){return
r.toJSON()}))}if(j.multiselect){l={};l[c("Ok")]=k}m=new
f.View({height:"auto",buttons:l,closing_events:true,closing_callback:function(){q.resolve(null)},body:['<div
class="list-panel"></div>'].join("")});m.$(".modal-header").remove();m.$(".modal-footer").css("margin-top","0px");o=new
d.DatasetList({title:j.title,subtitle:j.subtitle||c(["Click the checkboxes on the
right to select datasets. ","Click the datasets names to see their details.
"].join("")),el:m.$body.find(".list-panel"),selecting:true,selected:j.selected,collection:new
a.DatasetAssociationCollection(n)});o.once("rendered:initial",function(){m.show();m.$el.addClass("dataset-choice-modal")});if(!j.multiselect){o.on("rendered",function(){o.$(".list-actions").hide()});o.on("view:selected",function(r){q.resolve([r.model.toJSON()])})}o.render(0);return
q.always(function(){m.hide()})};var
e=Backbone.View.extend(i.LoggableMixin).extend({className:"dataset-choice",initialize:function(j){this.debug(this+"(DatasetChoice).initialize:",j);this.label=j.label!==undefined?c(j.label):"";this.where=j.where;this.datasetsOnly=j.datasetsOnly!==undefined?j.datasetsOnly:true;this.datasetJSON=j.datasetJSON||[];this.selected=j.selected||[];this._setUpListeners()},_setUpListeners:function(){},render:function(){var
j=this.toJSON();this.$el.html(this._template(j));this.$(".selected").replaceWith(this._renderSelected(j));return
this},_template:function(j){return _.template(["<label>",'<span
class="prompt"><%= json.label %></span>','<div
class="selected"></div>',"</label>"].join(""),{json:j})},_renderSelected:function(j){if(j.selected.length){return
$(_.template(['<div class="selected">','<span
class="title"><%= selected.hid %>: <%= selected.name
%></span>','<span
class="subtitle">',"<i><%= selected.misc_blurb
%></i>","<i>",c("format")+":
","<%= selected.data_type %></i>","<i><%=
selected.misc_info
%></i>","</span>","</div>"].join(""),{selected:j.selected[0]}))}return
$(['<span class="none-selected-msg">(',c("click to select a
dataset"),")</span>"].join(""))},toJSON:function(){var
j=this;return{label:j.label,datasets:j.datasetJSON,selected:_.compact(_.map(j.selected,function(k){return
_.findWhere(j.datasetJSON,{id:k})}))}},events:{click:"chooseWithModal"},chooseWithModal:function(){var
j=this;return
this._createModal().done(function(k){if(k){j.selected=_.pluck(k,"id");j.trigger("selected",j,k);j.render()}else{j.trigger("cancelled",j)}}).fail(function(){j.trigger("error",j,arguments)})},_createModal:function(){return
new
b(this.datasetJSON,this._getModalOptions())},_getModalOptions:function(){return{title:this.label,multiselect:false,selected:this.selected,where:this.where,datasetsOnly:this.datasetsOnly}},toString:function(){return"DatasetChoice("+this.selected+")"}});var
h=e.extend({className:e.prototype.className+" multi",cells:{hid:c("History
#"),name:c("Name"),misc_blurb:c("Summary"),data_type:c("Format"),genome_build:c("Genome"),tags:c("Tags"),annotation:c("Annotation")},initialize:function(j){this.showHeaders=j.showHeaders!==undefined?j.showHeaders:true;this.cells=j.cells||this.cells;e.prototype.initialize.call(this,j)},_renderSelected:function(j){if(j.selected.length){return
$(_.template(['<table class="selected">',"<% if(
json.showHeaders ){ %>","<thead><tr>","<% _.map(
json.cells, function( val, key ){ %>","<th><%= val
%></th>","<% });
%>","</tr></thead>","<% }
%>","<tbody>","<% _.map( json.selected, function( selected
){ %>","<tr>","<% _.map( json.cells, function( val, key ){
%>",'<td class="cell-<%= key %>"><%= selected[ key ]
%></td>',"<% }) %>","</tr>","<% });
%>","</tbody>","</table>"].join(""),{json:j}))}return
$(['<span class="none-selected-msg">(',c("click to select a
dataset"),")</span>"].join(""))},toJSON:function(){return
_.extend(e.prototype.toJSON.call(this),{showHeaders:this.showHeaders,cells:this.cells})},_getModalOptions:function(){return
_.extend(e.prototype._getModalOptions.call(this),{multiselect:true})},toString:function(){return"DatasetChoice("+this.selected+")"}});return{DatasetChoiceModal:b,DatasetChoice:e,MultiDatasetChoice:h}});
\ No newline at end of file
diff -r 737f78bb4a4581630734a693d6675daaae35b641 -r
ece8ef90a8289399bf9faca6a3265696da7e0beb
static/scripts/packed/mvc/dataset/dataset-list.js
--- /dev/null
+++ b/static/scripts/packed/mvc/dataset/dataset-list.js
@@ -0,0 +1,1 @@
+define(["mvc/dataset/list-panel","mvc/dataset/dataset-li","mvc/base-mvc","utils/localization"],function(c,f,a,b){var
e=c.ListPanel;var
d=e.extend({viewClass:f.DatasetListItemView,className:e.prototype.className+"
dataset-list",noneFoundMsg:b("No matching datasets
found"),initialize:function(g){e.prototype.initialize.call(this,g)},toString:function(){return"DatasetList("+this.collection+")"}});return{DatasetList:d}});
\ No newline at end of file
diff -r 737f78bb4a4581630734a693d6675daaae35b641 -r
ece8ef90a8289399bf9faca6a3265696da7e0beb static/scripts/packed/mvc/dataset/list-panel.js
--- /dev/null
+++ b/static/scripts/packed/mvc/dataset/list-panel.js
@@ -0,0 +1,1 @@
+define(["mvc/base-mvc","utils/localization"],function(a,b){var
c=Backbone.View.extend(a.LoggableMixin).extend({viewClass:a.ListItemView,tagName:"div",className:"list-panel",fxSpeed:"fast",emptyMsg:b("This
list is empty"),noneFoundMsg:b("No matching items
found"),initialize:function(d,e){d=d||{};if(d.logger){this.logger=d.logger}this.log(this+".initialize:",d);this.fxSpeed=_.has(d,"fxSpeed")?(d.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor=d.searchFor||"";this.indicator=new
LoadingIndicator(this.$el);this.selecting=(d.selecting!==undefined)?d.selecting:true;this.selected=d.selected||[];this.lastSelected=null;this.viewClass=d.viewClass||this.viewClass;this.views=[];this.collection=d.collection||(new
Backbone.Collection([]));this.filters=d.filters||[];this.title=d.title||"";this.subtitle=d.subtitle||"";this._setUpListeners()},_setUpListeners:function(){this.on("error",function(e,h,d,g,f){console.error(e,h,d,g,f)},this);this.on("loading",function(){this._showLoadingIndicator("loading...",40)},this);this.on("loading-done",function(){this._hideLoadingIndicator(40)},this);this.once("rendered",function(){this.trigger("rendered:initial",this)},this);if(this.logger){this.on("all",function(d){this.log(this+"",arguments)},this)}this._setUpCollectionListeners();this._setUpViewListeners();return
this},freeViews:function(){this.views=[];return
this},_setUpCollectionListeners:function(){this.collection.on("reset",function(){this.renderItems()},this);this.collection.on("add",this.addItemView,this);this.collection.on("remove",this.removeItemView,this);if(this.logger){this.collection.on("all",function(d){this.info(this+"(collection)",arguments)},this)}return
this},_setUpViewListeners:function(){this.on("view:selected",function(d,e){if(e&&e.shiftKey&&this.lastSelected){var
f=_.find(this.views,function(g){return
g.model.id===this.lastSelected});if(f){this.selectRange(d,f)}}this.selected.push(d.model.id);this.lastSelected=d.model.id},this)},render:function(e){var
d=this._buildNewRender();this._setUpBehaviors(d);this._queueNewRender(d,e);return
this},_buildNewRender:function(){var
e=this.model?this.model.toJSON():{},d=$(this.templates.el(e,this));this._renderTitle(d);this._renderSubtitle(d);this._renderSearch(d);this.renderItems(d);return
d},_renderTitle:function(d){},_renderSubtitle:function(d){},_queueNewRender:function(e,f){f=(f===undefined)?(this.fxSpeed):(f);var
d=this;$(d).queue("fx",[function(g){this.$el.fadeOut(f,g)},function(g){d._swapNewRender(e);g()},function(g){this.$el.fadeIn(f,g)},function(g){d.trigger("rendered",d);g()}])},_swapNewRender:function(d){this.$el.empty().attr("class",this.className).append(d.children());if(this.selecting){this.showSelectors(0)}return
this},_setUpBehaviors:function(d){d=d||this.$el;d.find(".controls
[title]").tooltip({placement:"bottom"});return
this},$scrollContainer:function(){return
this.$el.parent().parent()},$list:function(d){return(d||this.$el).find(".list-items")},$messages:function(d){return(d||this.$el).find(".message-container")},$emptyMessage:function(d){return(d||this.$el).find(".empty-message")},renderItems:function(g){g=g||this.$el;var
h=this,e=[];var f=this.$list(g),d=this._filterCollection().map(function(j){var
i=h._createItemView(j);e.push(i);return
i.render(0).$el});this.debug(d);this.debug(e);f.empty();if(d.length){f.append(d);this.$emptyMessage(g).hide()}else{this._renderEmptyMessage(g).show()}this.views=e;return
e},_filterCollection:function(){var d=this;return
d.collection.filter(_.bind(d._filterItem,d))},_filterItem:function(d){var
e=this;return(_.every(e.filters.map(function(f){return
f.call(d)})))&&(!e.searchFor||d.matchesAll(e.searchFor))},_createItemView:function(f){var
g=this._getItemViewClass(f),e=_.extend(this._getItemViewOptions(f),{model:f}),d=new
g(e);this._setUpItemViewListeners(d);return d},_getItemViewClass:function(d){return
this.viewClass},_getItemViewOptions:function(d){return{fxSpeed:this.fxSpeed,expanded:false,selectable:this.selecting,selected:_.contains(this.selected,d.id),draggable:this.dragging}},_setUpItemViewListeners:function(d){var
e=this;d.on("all",function(){var
f=Array.prototype.slice.call(arguments,0);f[0]="view:"+f[0];e.trigger.apply(e,f)});return
this},_renderEmptyMessage:function(d){var
e=this.searchFor?this.noneFoundMsg:this.emptyMsg;return
this.$emptyMessage(d).text(e)},expandAll:function(){_.each(this.views,function(d){d.expand()})},collapseAll:function(){_.each(this.views,function(d){d.collapse()})},addItemView:function(f,h,e){this.log(this+".addItemView:",f);var
g=this;if(!this._filterItem(f)){return undefined}var
d=g._createItemView(f);this.views.push(d);$(d).queue("fx",[function(i){g.$emptyMessage().fadeOut(g.fxSpeed,i)},function(i){g.$list().append(d.render().$el);i()}]);return
d},removeItemView:function(f,h,e){this.log(this+".removeItemView:",f);var
g=this,d=g.viewFromModel(f);if(!d){return
undefined}this.views=_.without(this.views,d);d.remove();if(!this.views.length){g._renderEmptyMessage().fadeIn(g.fxSpeed)}return
d},viewFromModel:function(e){for(var f=0;f<this.views.length;f++){var
d=this.views[f];if(d.model===e){return d}}return
undefined},viewsWhereModel:function(d){return this.views.filter(function(e){var
g=e.model.toJSON();for(var f in
d){if(d.hasOwnPropery(f)){if(g[f]!==e.model.properties[f]){return false}}}return
true})},viewRange:function(g,f){if(g===f){return(g)?([g]):([])}var
e=this.views.indexOf(g),d=this.views.indexOf(f);if(e===-1||d===-1){if(e===d){return[]}return(e===-1)?([f]):([g])}return(e<d)?this.views.slice(e,d+1):this.views.slice(d,e+1)},_renderSearch:function(d){d.find(".controls
.search-input").searchInput({placeholder:"search",initialVal:this.searchFor,onfirstsearch:_.bind(this._firstSearch,this),onsearch:_.bind(this.searchItems,this),onclear:_.bind(this.clearSearch,this)});return
d},_firstSearch:function(d){this.log("onFirstSearch",d);return
this.searchItems(d)},searchItems:function(d){this.searchFor=d;this.trigger("search:searching",d,this);this.renderItems();return
this},clearSearch:function(d){this.searchFor="";this.trigger("search:clear",this);this.renderItems();return
this},showSelectors:function(d){d=(d!==undefined)?(d):(this.fxSpeed);this.selecting=true;this.$(".list-actions").slideDown(d);_.each(this.views,function(e){e.showSelector(d)});this.selected=[];this.lastSelected=null},hideSelectors:function(d){d=(d!==undefined)?(d):(this.fxSpeed);this.selecting=false;this.$(".list-actions").slideUp(d);_.each(this.views,function(e){e.hideSelector(d)});this.selected=[];this.lastSelected=null},toggleSelectors:function(){if(!this.selecting){this.showSelectors()}else{this.hideSelectors()}},selectAll:function(d){_.each(this.views,function(e){e.select(d)})},deselectAll:function(d){this.lastSelected=null;_.each(this.views,function(e){e.deselect(d)})},selectRange:function(f,e){var
d=this.viewRange(f,e);_.each(d,function(g){g.select()});return
d},getSelectedViews:function(){return _.filter(this.views,function(d){return
d.selected})},getSelectedModels:function(){return new
this.collection.constructor(_.map(this.getSelectedViews(),function(d){return
d.model}))},_showLoadingIndicator:function(e,d,f){d=(d!==undefined)?(d):(this.fxSpeed);if(!this.indicator){this.indicator=new
LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,f)}else{this.$el.fadeOut(d);this.indicator.show(e,d,f)}},_hideLoadingIndicator:function(d,e){d=(d!==undefined)?(d):(this.fxSpeed);if(this.indicator){this.indicator.hide(d,e)}},scrollPosition:function(){return
this.$scrollContainer().scrollTop()},scrollTo:function(d){this.$scrollContainer().scrollTop(d);return
this},scrollToTop:function(){this.$scrollContainer().scrollTop(0);return
this},scrollToItem:function(d){if(!d){return}var
e=d.$el.offset().top;this.$scrollContainer().scrollTop(e)},events:{"click
.select-all":"selectAll","click
.deselect-all":"deselectAll"},toString:function(){return"ListPanel("+this.collection+")"}});c.prototype.templates=(function(){var
d=a.wrapTemplate(["<div>",'<div
class="controls">','<div
class="title">','<div class="name"><%= model.name
|| view.title %></div>',"</div>",'<div
class="subtitle"><%= view.subtitle %></div>','<div
class="actions"></div>','<div
class="messages"></div>','<div
class="search">','<div
class="search-input"></div>',"</div>",'<div
class="list-actions">','<div
class="btn-group">','<button class="select-all btn
btn-default"','data-mode="select">',b("All"),"</button>",'<button
class="deselect-all btn
btn-default"','data-mode="select">',b("None"),"</button>","</div>","</div>","</div>",'<div
class="list-items"></div>','<div class="empty-message
infomessagesmall"></div>',"</div>"]);return{el:d}}());return{ListPanel:c}});
\ No newline at end of file
Repository URL:
https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from
bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.