1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e66076ed4678/
Changeset: e66076ed4678
User: carlfeberhard
Date: 2013-10-23 19:03:59
Summary: History panel: cleanup, todo list, docs; pack scripts
Affected #: 10 files
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/mvc/dataset/hda-base.js
--- a/static/scripts/mvc/dataset/hda-base.js
+++ b/static/scripts/mvc/dataset/hda-base.js
@@ -5,7 +5,7 @@
//==============================================================================
/** @class Read only view for HistoryDatasetAssociation.
* @name HDABaseView
- *
+ *
* @augments Backbone.View
* @borrows LoggableMixin#logger as #logger
* @borrows LoggableMixin#log as #log
@@ -23,7 +23,7 @@
fxSpeed : 'fast',
- // ......................................................................... SET UP
+ // ......................................................................... set up
/** Set up the view, cache url templates, bind listeners
* @param {Object} attributes
* @config {Object} urlTemplates nested object containing url templates for this view
@@ -44,13 +44,17 @@
this._setUpListeners();
},
+ /** event listeners */
_setUpListeners : function(){
+
// re-rendering on any model changes
this.model.on( 'change', function( model, options ){
- // if the model moved into the ready state and is expanded without details, fetch those details
+
+ // if the model moved into the ready state and is expanded without details, fetch those details now
if( this.model.changedAttributes().state && this.model.inReadyState()
&& this.expanded && !this.model.hasDetails() ){
this.model.fetch(); // will render automatically (due to lines below)
+
} else {
this.render();
}
@@ -61,7 +65,7 @@
//}, this );
},
- // ......................................................................... RENDER MAIN
+ // ......................................................................... render main
/** Render this HDA, set up ui.
* @fires rendered:ready when rendered and NO running HDAs
* @fires rendered when rendered and running HDAs
@@ -122,7 +126,6 @@
_setUpBehaviors : function( $container ){
$container = $container || this.$el;
// set up canned behavior on children (bootstrap, popupmenus, editable_text, etc.)
- //TODO: we can potentially skip this step and call popupmenu directly on the download button
make_popup_menus( $container );
$container.find( '[title]' ).tooltip({ placement : 'bottom' });
},
@@ -213,13 +216,10 @@
* @returns {jQuery} rendered DOM
*/
_render_titleLink : function(){
- return $( jQuery.trim( HDABaseView.templates.titleLink(
- //TODO?? does this need urls?
- _.extend( this.model.toJSON(), { urls: this.urls } )
- )));
+ return $( jQuery.trim( HDABaseView.templates.titleLink( this.model.toJSON() )));
},
- // ......................................................................... RENDER BODY
+ // ......................................................................... body
/** Render the data/metadata summary (format, size, misc info, etc.).
* @returns {jQuery} rendered DOM
*/
@@ -283,7 +283,7 @@
/** Render links to external genome display applications (igb, gbrowse, etc.).
* @param {jQuery} $parent the jq node to search for .display-apps and render into to (defaults to this.$el)
*/
- //TODO: not a fan of the style on these
+//TODO: move into visualization button
_render_displayApps : function( $parent ){
$parent = $parent || this.$el;
var $displayAppsDiv = $parent.find( 'div.display-apps' ),
@@ -310,7 +310,6 @@
/** Render the data peek.
* @returns {jQuery} rendered DOM
*/
- //TODO: curr. pre-formatted into table on the server side - may not be ideal/flexible
_render_peek : function(){
var peek = this.model.get( 'peek' );
if( !peek ){ return null; }
@@ -326,74 +325,38 @@
/** Render the enclosing div of the hda body and, if expanded, the html in the body
* @returns {jQuery} rendered DOM
*/
- //TODO: only render these on expansion (or already expanded)
_render_body : function(){
- var body = $( '<div/>' )
+ var $body = $( '<div/>' )
.attr( 'id', 'info-' + this.model.get( 'id' ) )
.addClass( 'historyItemBody' )
.attr( 'style', 'display: none' );
if( this.expanded ){
// only render the body html if it's being shown
- this._render_body_html( body );
- //TODO: switch back when jq -> 1.9
- //body.show();
- body.css( 'display', 'block' );
+ this._render_body_html( $body );
+ $body.show();
}
- return body;
+ return $body;
},
/** Render the (expanded) body of an HDA, dispatching to other functions based on the HDA state
* @param {jQuery} body the body element to append the html to
*/
- //TODO: only render these on expansion (or already expanded)
- _render_body_html : function( body ){
+ _render_body_html : function( $body ){
//this.log( this + '_render_body' );
- body.html( '' );
- //TODO: not a fan of this dispatch
- switch( this.model.get( 'state' ) ){
- case hdaModel.HistoryDatasetAssociation.STATES.NEW :
- this._render_body_new( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.NOT_VIEWABLE :
- this._render_body_not_viewable( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.UPLOAD :
- this._render_body_uploading( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.PAUSED:
- this._render_body_paused( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.QUEUED :
- this._render_body_queued( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.RUNNING :
- this._render_body_running( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.ERROR :
- this._render_body_error( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.DISCARDED :
- this._render_body_discarded( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.SETTING_METADATA :
- this._render_body_setting_metadata( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.EMPTY :
- this._render_body_empty( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.FAILED_METADATA :
- this._render_body_failed_metadata( body );
- break;
- case hdaModel.HistoryDatasetAssociation.STATES.OK :
- this._render_body_ok( body );
- break;
- default:
- //??: no body?
- body.append( $( '<div>Error: unknown dataset state "' + this.model.get( 'state' ) + '".</div>' ) );
+ $body.empty();
+
+ var modelState = this.model.get( 'state' );
+ // cheesy get function by assumed matching name
+ var renderFnName = '_render_body_' + modelState,
+ renderFn = this[ renderFnName ];
+ if( _.isFunction( renderFn ) ){
+ this[ renderFnName ]( $body );
+ } else {
+ $body.append( $( '<div>Error: unknown dataset state "' + this.model.get( 'state' ) + '".</div>' ) );
}
- body.append( '<div style="clear: both"></div>' );
- this._setUpBehaviors( body );
+ $body.append( '<div style="clear: both"></div>' );
+ this._setUpBehaviors( $body );
},
/** Render a new dataset - this should be a transient state that's never shown
@@ -408,15 +371,14 @@
/** Render inaccessible, not-owned by curr user.
* @param {jQuery} parent DOM to which to append this body
*/
- _render_body_not_viewable : function( parent ){
- //TODO: revisit - still showing display, edit, delete (as common) - that CAN'T be right
- parent.append( $( '<div>' + _l( 'You do not have permission to view dataset' ) + '</div>' ) );
+ _render_body_noPermission : function( parent ){
+ parent.append( $( '<div>' + _l( 'You do not have permission to view this dataset' ) + '</div>' ) );
},
/** Render an HDA still being uploaded.
* @param {jQuery} parent DOM to which to append this body
*/
- _render_body_uploading : function( parent ){
+ _render_body_upload : function( parent ){
parent.append( $( '<div>' + _l( 'Dataset is uploading' ) + '</div>' ) );
},
@@ -432,7 +394,8 @@
* @param {jQuery} parent DOM to which to append this body
*/
_render_body_paused: function( parent ){
- parent.append( $( '<div>' + _l( 'Job is paused. Use the history menu to resume' ) + '</div>' ) );
+ parent.append( $( '<div>' + _l( 'Job is paused. '
+ + 'Use the "Resume Paused Jobs" in the history menu to resume' ) + '</div>' ) );
parent.append( this._render_primaryActionButtons( this.defaultPrimaryActionButtonRenderers ));
},
@@ -477,8 +440,6 @@
* @param {jQuery} parent DOM to which to append this body
*/
_render_body_empty : function( parent ){
- //TODO: replace i with dataset-misc-info class
- //?? why are we showing the file size when we know it's zero??
parent.append( $( '<div>' + _l( 'No data' ) + ': <i>' + this.model.get( 'misc_blurb' ) + '</i></div>' ) );
parent.append( this._render_primaryActionButtons( this.defaultPrimaryActionButtonRenderers ));
},
@@ -487,7 +448,6 @@
* @param {jQuery} parent DOM to which to append this body
*/
_render_body_failed_metadata : function( parent ){
- //TODO: the css for this box is broken (unlike the others)
// add a message box about the failure at the top of the body...
parent.append( $( HDABaseView.templates.failedMetadata(
_.extend( this.model.toJSON(), { urls: this.urls } )
@@ -504,7 +464,6 @@
parent.append( this._render_hdaSummary() );
// return shortened form if del'd
- //TODO: is this correct? maybe only on purged
if( this.model.isDeletedOrPurged() ){
parent.append( this._render_primaryActionButtons([
this._render_downloadButton,
@@ -525,44 +484,55 @@
parent.append( this._render_peek() );
},
- // ......................................................................... EVENTS
+ // ......................................................................... events
/** event map */
events : {
+ // expand the body when the title is clicked
'click .historyItemTitle' : 'toggleBodyVisibility'
},
- /** Render an HDA that's done running and where everything worked.
+ /** Show or hide the body/details of an HDA.
+ * note: if the model does not have detailed data, fetch that data before showing the body
* @param {Event} event the event that triggered this (@link HDABaseView#events)
* @param {Boolean} expanded if true, expand; if false, collapse
* @fires body-expanded when a body has been expanded
* @fires body-collapsed when a body has been collapsed
*/
toggleBodyVisibility : function( event, expand ){
- var hdaView = this;
expand = ( expand === undefined )?( !this.body.is( ':visible' ) ):( expand );
if( expand ){
- if( this.model.inReadyState() && !this.model.hasDetails() ){
- var xhr = this.model.fetch();
- xhr.done( function( model ){
- hdaView.expandBody();
- });
- } else {
- this.expandBody();
- }
+ this.expandBody();
} else {
this.collapseBody();
}
},
+ /** Render and show the full, detailed body of this view including extra data and controls.
+ * @fires body-expanded when a body has been expanded
+ */
expandBody : function(){
var hdaView = this;
- hdaView._render_body_html( hdaView.body );
- this.body.slideDown( hdaView.fxSpeed, function(){
- hdaView.expanded = true;
- hdaView.trigger( 'body-expanded', hdaView.model.get( 'id' ) );
- });
+
+ function _renderBodyAndExpand(){
+ hdaView._render_body_html( hdaView.body );
+ hdaView.body.slideDown( hdaView.fxSpeed, function(){
+ hdaView.expanded = true;
+ hdaView.trigger( 'body-expanded', hdaView.model.get( 'id' ) );
+ });
+ }
+ // fetch first if no details in the model
+ if( this.model.inReadyState() && !this.model.hasDetails() ){
+ this.model.fetch().done( function( model ){
+ _renderBodyAndExpand();
+ });
+ } else {
+ _renderBodyAndExpand();
+ }
},
+ /** Hide the body/details of an HDA.
+ * @fires body-collapsed when a body has been collapsed
+ */
collapseBody : function(){
var hdaView = this;
this.body.slideUp( hdaView.fxSpeed, function(){
@@ -571,7 +541,10 @@
});
},
- // ......................................................................... DELETION
+ // ......................................................................... removal
+ /** Remove this view's html from the DOM and remove all event listeners.
+ * @param {Function} callback an optional function called when removal is done
+ */
remove : function( callback ){
var hdaView = this;
this.$el.fadeOut( hdaView.fxSpeed, function(){
@@ -581,7 +554,8 @@
});
},
- // ......................................................................... MISC
+ // ......................................................................... misc
+ /** String representation */
toString : function(){
var modelString = ( this.model )?( this.model + '' ):( '(no model)' );
return 'HDABaseView(' + modelString + ')';
@@ -602,5 +576,5 @@
//==============================================================================
return {
- HDABaseView : HDABaseView,
+ HDABaseView : HDABaseView
};});
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/mvc/dataset/hda-edit.js
--- a/static/scripts/mvc/dataset/hda-edit.js
+++ b/static/scripts/mvc/dataset/hda-edit.js
@@ -14,7 +14,7 @@
var HDAEditView = hdaBase.HDABaseView.extend( LoggableMixin ).extend(
/** @lends HDAEditView.prototype */{
- // ......................................................................... SET UP
+ // ......................................................................... set up
/** Set up the view, cache url templates, bind listeners.
* Overrides HDABaseView.initialize to change default actions (adding re-run).
* @param {Object} attributes
@@ -43,7 +43,7 @@
//var hdaView = this;
},
- // ......................................................................... RENDER WARNINGS
+ // ......................................................................... render warnings
/** Render any hda warnings including: is deleted, is purged, is hidden.
* Overrides _render_warnings to include links to further actions (undelete, etc.)).
* @returns {Object} the templated urls
@@ -71,13 +71,14 @@
return buttonDiv;
},
+//TODO: move titleButtons into state renderers, remove state checks in the buttons
+
/** Render icon-button to edit the attributes (format, permissions, etc.) this hda.
* @returns {jQuery} rendered DOM
*/
_render_editButton : function(){
// don't show edit while uploading, in-accessible
// DO show if in error (ala previous history panel)
- //TODO??: not viewable/accessible are essentially the same (not viewable set from accessible)
if( ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NEW )
|| ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.UPLOAD )
|| ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NOT_VIEWABLE )
@@ -114,7 +115,6 @@
*/
_render_deleteButton : function(){
// don't show delete if...
- //TODO??: not viewable/accessible are essentially the same (not viewable set from accessible)
if( ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NEW )
|| ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NOT_VIEWABLE )
|| ( !this.model.get( 'accessible' ) ) ){
@@ -147,7 +147,7 @@
return this.deleteButton.render().$el;
},
- // ......................................................................... RENDER BODY
+ // ......................................................................... render body
/** Render the data/metadata summary (format, size, misc info, etc.).
* Overrides _render_hdaSummary to include edit link in dbkey.
* @see HDABaseView#_render_hdaSummary
@@ -158,7 +158,6 @@
// if there's no dbkey and it's editable : pass a flag to the template to render a link to editing in the '?'
if( this.model.get( 'metadata_dbkey' ) === '?'
&& !this.model.isDeletedOrPurged() ){
- //TODO: use HDABaseView and select/replace base on this switch
_.extend( modelData, { dbkey_unknown_and_editable : true });
}
return hdaBase.HDABaseView.templates.hdaSummary( modelData );
@@ -238,10 +237,8 @@
var $icon = this.visualizationsButton.render().$el;
$icon.addClass( 'visualize-icon' ); // needed?
- //TODO: make this more concise
// map a function to each visualization in the icon's attributes
// create a popupmenu from that map
-
/** @inner */
function create_viz_action( visualization ) {
switch( visualization ){
@@ -269,7 +266,6 @@
// >1: Populate menu dict with visualization fns, make the popupmenu
} else {
_.each( visualizations, function( visualization ) {
- //TODO: move to utils
var titleCaseVisualization = visualization.charAt( 0 ).toUpperCase() + visualization.slice( 1 );
popup_menu_dict[ _l( titleCaseVisualization ) ] = create_viz_action( visualization );
});
@@ -334,9 +330,7 @@
/** Render icon-button to load and display tagging html.
* @returns {jQuery} rendered DOM
*/
- //TODO: these should be a sub-MV
_render_tagButton : function(){
- //TODO: check for User
if( !this.hasUser || !this.urls.tags.get ){
this.tagButton = null;
return null;
@@ -354,9 +348,7 @@
/** Render icon-button to load and display annotation html.
* @returns {jQuery} rendered DOM
*/
- //TODO: these should be a sub-MV
_render_annotateButton : function(){
- //TODO: check for User
if( !this.hasUser || !this.urls.annotation.get ){
this.annotateButton = null;
return null;
@@ -370,33 +362,6 @@
return this.annotateButton.render().$el;
},
- // ......................................................................... other elements
- /** Render area to display tags.
- * @returns {jQuery} rendered DOM
- */
-//TODO: into sub-MV
-//TODO: check for User
- _render_tagArea : function(){
- if( !this.urls.tags.set ){ return null; }
- //TODO: move to mvc/tags.js
- return $( HDAEditView.templates.tagArea(
- _.extend( this.model.toJSON(), { urls: this.urls } )
- ).trim() );
- },
-
- /** Render area to display annotation.
- * @returns {jQuery} rendered DOM
- */
-//TODO: into sub-MV
-//TODO: check for User
- _render_annotationArea : function(){
- if( !this.urls.annotation.get ){ return null; }
- //TODO: move to mvc/annotations.js
- return $( HDAEditView.templates.annotationArea(
- _.extend( this.model.toJSON(), { urls: this.urls } )
- ).trim() );
- },
-
// ......................................................................... state body renderers
/** Render an HDA whose job has failed.
* Overrides _render_body_error to prepend error report button to primary actions strip.
@@ -415,7 +380,6 @@
* @see HDABaseView#_render_body_ok
*/
_render_body_ok : function( parent ){
- //TODO: should call super somehow and insert the needed...
// most common state renderer and the most complicated
parent.append( this._render_hdaSummary() );
@@ -451,7 +415,7 @@
parent.append( this._render_peek() );
},
- // ......................................................................... EVENTS
+ // ......................................................................... events
/** event map */
events : {
'click .historyItemTitle' : 'toggleBodyVisibility',
@@ -463,16 +427,28 @@
'click a.icon-button.annotate' : 'loadAndDisplayAnnotation'
},
- // ......................................................................... STATE CHANGES / MANIPULATION
+ /** listener for item purge */
confirmPurge : function _confirmPurge( ev ){
- //TODO: confirm dialog
+//TODO: confirm dialog
this.model.purge({ url: this.urls.purge });
return false;
},
+ // ......................................................................... tags
+ /** Render area to display tags.
+ * @returns {jQuery} rendered DOM
+ */
+//TODO: into sub-MV
+ _render_tagArea : function(){
+ if( !this.hasUser || !this.urls.tags.set ){ return null; }
+ return $( HDAEditView.templates.tagArea(
+ _.extend( this.model.toJSON(), { urls: this.urls } )
+ ).trim() );
+ },
+
/** Find the tag area and, if initial: load the html (via ajax) for displaying them; otherwise, unhide/hide
*/
- //TODO: into sub-MV
+//TODO: into sub-MV
loadAndDisplayTags : function( event ){
//BUG: broken with latest
//TODO: this is a drop in from history.mako - should use MV as well
@@ -508,6 +484,18 @@
}
return false;
},
+
+ // ......................................................................... annotations
+ /** Render area to display annotation.
+ * @returns {jQuery} rendered DOM
+ */
+//TODO: into sub-MV
+ _render_annotationArea : function(){
+ if( !this.hasUser || !this.urls.annotation.get ){ return null; }
+ return $( HDAEditView.templates.annotationArea(
+ _.extend( this.model.toJSON(), { urls: this.urls } )
+ ).trim() );
+ },
/** Find the annotation area and, if initial: load the html (via ajax) for displaying them; otherwise, unhide/hide
*/
@@ -555,7 +543,7 @@
return false;
},
- // ......................................................................... UTILTIY
+ // ......................................................................... misc
/** string rep */
toString : function(){
var modelString = ( this.model )?( this.model + '' ):( '(no model)' );
@@ -678,5 +666,5 @@
//==============================================================================
return {
- HDAEditView : HDAEditView,
+ HDAEditView : HDAEditView
};});
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/mvc/dataset/hda-model.js
--- a/static/scripts/mvc/dataset/hda-model.js
+++ b/static/scripts/mvc/dataset/hda-model.js
@@ -53,41 +53,42 @@
misc_info : ''
},
- /** fetch location of this history in the api */
+ /** fetch location of this HDA's history in the api */
urlRoot: 'api/histories/',
+ /** full url spec. for this HDA */
url : function(){
return this.urlRoot + this.get( 'history_id' ) + '/contents/' + this.get( 'id' );
},
+ /** controller urls assoc. with this HDA */
urls : function(){
var id = this.get( 'id' );
if( !id ){ return {}; }
var urls = {
- 'delete' : galaxy_config.root + 'datasets/' + id + '/delete_async',
- 'purge' : galaxy_config.root + 'datasets/' + id + '/purge_async',
- 'unhide' : galaxy_config.root + 'datasets/' + id + '/unhide',
- 'undelete' : galaxy_config.root + 'datasets/' + id + '/undelete',
+ 'purge' : galaxy_config.root + 'datasets/' + id + '/purge_async',
- 'display' : galaxy_config.root + 'datasets/' + id + '/display/?preview=True',
- 'download' : galaxy_config.root + 'datasets/' + id + '/display?to_ext=' + this.get( 'file_ext' ),
- 'edit' : galaxy_config.root + 'datasets/' + id + '/edit',
- 'report_error': galaxy_config.root + 'dataset/errors?id=' + id,
- 'rerun' : galaxy_config.root + 'tool_runner/rerun?id=' + id,
- 'show_params': galaxy_config.root + 'datasets/' + id + '/show_params',
- 'visualization': galaxy_config.root + 'visualization',
+ 'display' : galaxy_config.root + 'datasets/' + id + '/display/?preview=True',
+ 'download' : galaxy_config.root + 'datasets/' + id + '/display?to_ext=' + this.get( 'file_ext' ),
+ 'edit' : galaxy_config.root + 'datasets/' + id + '/edit',
+ 'report_error' : galaxy_config.root + 'dataset/errors?id=' + id,
+ 'rerun' : galaxy_config.root + 'tool_runner/rerun?id=' + id,
+ 'show_params' : galaxy_config.root + 'datasets/' + id + '/show_params',
+ 'visualization' : galaxy_config.root + 'visualization',
'annotation': { 'get': galaxy_config.root + 'dataset/get_annotation_async?id=' + id,
'set': galaxy_config.root + 'dataset/annotate_async?id=' + id },
- 'tags' : { 'get': galaxy_config.root + 'tag/get_tagging_elt_async?item_id=' + id + '&item_class=HistoryDatasetAssociation',
- 'set': galaxy_config.root + 'tag/retag?item_id=' + id + '&item_class=HistoryDatasetAssociation' }
+ 'tags' : { 'get': galaxy_config.root + 'tag/get_tagging_elt_async?item_id='
+ + id + '&item_class=HistoryDatasetAssociation',
+ 'set': galaxy_config.root + 'tag/retag?item_id='
+ + id + '&item_class=HistoryDatasetAssociation' }
};
- //'meta_download': '/dataset/get_metadata_file?hda_id=%3C%25%3D+id+%25%3E&metadata_name=%3C%25%3D+file_type+%25%3E',
+ // download links to assoc. metadata files (bam indeces, etc.)
var meta_files = this.get( 'meta_files' );
if( meta_files ){
urls.meta_download = _.map( meta_files, function( meta_file ){
return {
- //url : _.template( urlTemplate, { id: modelJson.id, file_type: meta_file.file_type }),
- url : galaxy_config.root + 'dataset/get_metadata_file?hda_id=' + id + '&metadata_name=' + meta_file.file_type,
+ url : galaxy_config.root + 'dataset/get_metadata_file?hda_id='
+ + id + '&metadata_name=' + meta_file.file_type,
file_type : meta_file.file_type
};
});
@@ -110,6 +111,9 @@
this._setUpListeners();
},
+ /** set up any event listeners
+ * event: state:ready fired when this HDA moves into a ready state
+ */
_setUpListeners : function(){
// if the state has changed and the new state is a ready state, fire an event
this.on( 'change:state', function( currModel, newState ){
@@ -121,8 +125,7 @@
},
// ........................................................................ common queries
- /** Is this hda deleted or purged?
- */
+ /** Is this hda deleted or purged? */
isDeletedOrPurged : function(){
return ( this.get( 'deleted' ) || this.get( 'purged' ) );
},
@@ -132,7 +135,6 @@
* @param {Boolean} show_deleted are we showing deleted hdas?
* @param {Boolean} show_hidden are we showing hidden hdas?
*/
- //TODO: too many 'visible's
isVisible : function( show_deleted, show_hidden ){
var isVisible = true;
if( ( !show_deleted )
@@ -146,6 +148,7 @@
return isVisible;
},
+ /** the more common alias of visible */
hidden : function(){
return !this.get( 'visible' );
},
@@ -158,33 +161,37 @@
return ( this.isDeletedOrPurged() || ready );
},
+ /** Does this model already contain detailed data (as opposed to just summary level data)? */
hasDetails : function(){
//?? this may not be reliable
return _.has( this.attributes, 'genome_build' );
},
- /** Convenience function to match hda.has_data.
- */
+ /** Convenience function to match hda.has_data. */
hasData : function(){
- //TODO:?? is this equivalent to all possible hda.has_data calls?
return ( this.get( 'file_size' ) > 0 );
},
// ........................................................................ ajax
+ /** save this HDA, _Mark_ing it as deleted (just a flag) */
'delete' : function _delete( options ){
return this.save( { deleted: true }, options );
},
+ /** save this HDA, _Mark_ing it as undeleted */
undelete : function _undelete( options ){
return this.save( { deleted: false }, options );
},
+ /** save this HDA as not visible */
hide : function _hide( options ){
return this.save( { visible: false }, options );
},
+ /** save this HDA as visible */
unhide : function _uhide( options ){
return this.save( { visible: true }, options );
},
+ /** purge this HDA and remove the underlying dataset file from the server's fs */
purge : function _purge( options ){
//TODO: ideally this would be a DELETE call to the api
// using purge async for now
@@ -210,10 +217,15 @@
},
// ........................................................................ sorting/filtering
+ /** what attributes of an HDA will be used in a search */
searchKeys : [
'name', 'file_ext', 'genome_build', 'misc_blurb', 'misc_info', 'annotation', 'tags'
],
+ /** search this HDA for the string searchFor
+ * @param {String} searchFor look for this string in all attributes listed in searchKeys (above) using indexOf
+ * @returns {Array} an array of attribute keys where searchFor was found
+ */
search : function( searchFor ){
var model = this;
searchFor = searchFor.toLowerCase();
@@ -223,13 +235,16 @@
});
},
+ /** alias of search, but returns a boolean
+ * @param {String} matchesWhat look for this string in all attributes listed in searchKeys (above) using indexOf
+ * @returns {Boolean} was matchesWhat found in any attributes
+ */
matches : function( matchesWhat ){
return !!this.search( matchesWhat ).length;
},
// ........................................................................ misc
- /** String representation
- */
+ /** String representation */
toString : function(){
var nameAndId = this.get( 'id' ) || '';
if( this.get( 'name' ) ){
@@ -274,6 +289,7 @@
ERROR : 'error'
};
+/** states that are in a final state (the underlying job is complete) */
HistoryDatasetAssociation.READY_STATES = [
HistoryDatasetAssociation.STATES.NEW,
HistoryDatasetAssociation.STATES.OK,
@@ -285,6 +301,7 @@
HistoryDatasetAssociation.STATES.ERROR
];
+/** states that will change (the underlying job is not finished) */
HistoryDatasetAssociation.NOT_READY_STATES = [
HistoryDatasetAssociation.STATES.UPLOAD,
HistoryDatasetAssociation.STATES.QUEUED,
@@ -306,7 +323,10 @@
///** logger used to record this.log messages, commonly set to console */
//// comment this out to suppress log output
//logger : console,
+
+ /** root api url */
urlRoot : galaxy_config.root + 'api/histories',
+ /** complete api url */
url : function(){
return this.urlRoot + '/' + this.historyId + '/contents';
},
@@ -331,6 +351,9 @@
return this.map( function( hda ){ return hda.id; });
},
+ /** Get hdas that are not ready
+ * @returns array of HDAs
+ */
notReady : function(){
return this.filter( function( hda ){
return !hda.inReadyState();
@@ -370,11 +393,13 @@
},
// ........................................................................ ajax
+ /** fetch detailed model data for all HDAs in this collection */
fetchAllDetails : function(){
return this.fetch({ data : { details : 'all' } });
},
// ........................................................................ sorting/filtering
+ /** return a new collection of HDAs whose attributes contain the substring matchesWhat */
matches : function( matchesWhat ){
return this.filter( function( hda ){
return hda.matches( matchesWhat );
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/mvc/history/history-model.js
--- a/static/scripts/mvc/history/history-model.js
+++ b/static/scripts/mvc/history/history-model.js
@@ -13,7 +13,6 @@
*/
var History = Backbone.Model.extend( LoggableMixin ).extend(
/** @lends History.prototype */{
- //TODO: bind change events from items and collection to this (itemLengths, states)
///** logger used to record this.log messages, commonly set to console */
//// comment this out to suppress log output
@@ -33,17 +32,20 @@
// ........................................................................ urls
urlRoot: galaxy_config.root + 'api/histories',
+ /** url for changing the name of the history */
renameUrl : function(){
//TODO: just use this.save()
var id = this.get( 'id' );
if( !id ){ return undefined; }
return galaxy_config.root + 'history/rename_async?id=' + this.get( 'id' );
},
+ /** url for changing the annotation of the history */
annotateUrl : function(){
var id = this.get( 'id' );
if( !id ){ return undefined; }
return galaxy_config.root + 'history/annotate_async?id=' + this.get( 'id' );
},
+ /** url for changing the tags of the history */
tagUrl : function(){
var id = this.get( 'id' );
if( !id ){ return undefined; }
@@ -51,9 +53,10 @@
},
// ........................................................................ set up/tear down
- /** Set up the hdas collection
+ /** Set up the model
* @param {Object} historyJSON model data for this History
* @param {Object[]} hdaJSON array of model data for this History's HDAs
+ * @param {Object} options any extra settings including logger
* @see BaseModel#initialize
*/
initialize : function( historyJSON, hdaJSON, options ){
@@ -70,10 +73,15 @@
this._setUpListeners();
+ /** cached timeout id for the HDA updater */
+ this.updateTimeoutId = null;
// set up update timeout if needed
this.checkForUpdates();
},
+ /** set up any event listeners for this history including those to the contained HDAs
+ * events: error:hdas if an error occurred with the HDA collection
+ */
_setUpListeners : function(){
this.on( 'error', function( model, xhr, options, msg, details ){
this.errorHandler( model, xhr, options, msg, details );
@@ -107,25 +115,29 @@
// }
//},
+ /** event listener for errors. Generally errors are handled outside this model */
errorHandler : function( model, xhr, options, msg, details ){
// clear update timeout on model err
this.clearUpdateTimeout();
},
// ........................................................................ common queries
+ /** is this model already associated with a user? */
hasUser : function(){
var user = this.get( 'user' );
return !!( user && user.id );
},
// ........................................................................ ajax
- // get the history's state from it's cummulative ds states, delay + update if needed
- // events: ready
+ /** does the HDA collection indicate they're still running and need to be updated later? delay + update if needed
+ * @param {Function} onReadyCallback function to run when all HDAs are in the ready state
+ * events: ready
+ */
checkForUpdates : function( onReadyCallback ){
//console.info( 'checkForUpdates' )
// get overall History state from collection, run updater if History has running/queued hdas
- // boiling it down on the client to running/not
+ // boiling it down on the client to running/not
if( this.hdas.running().length ){
this.setUpdateTimeout();
@@ -138,8 +150,8 @@
return this;
},
+ /** create a timeout (after UPDATE_DELAY or delay ms) to refetch the HDA collection. Clear any prev. timeout */
setUpdateTimeout : function( delay ){
- //TODO: callbacks?
delay = delay || History.UPDATE_DELAY;
var history = this;
@@ -151,6 +163,7 @@
return this.updateTimeoutId;
},
+ /** clear the timeout and the cached timeout id */
clearUpdateTimeout : function(){
if( this.updateTimeoutId ){
clearTimeout( this.updateTimeoutId );
@@ -158,25 +171,26 @@
}
},
- // update this history, find any hda's running/queued, update ONLY those that have changed states,
- // set up to run this again in some interval of time
- // events: ready
+ /* update the HDA collection getting full detailed model data for any hda whose id is in detailIds
+ * set up to run this again in some interval of time
+ * @param {String[]} detailIds list of HDA ids to get detailed model data for
+ * @param {Object} options std. backbone fetch options map
+ */
refresh : function( detailIds, options ){
//console.info( 'refresh:', detailIds, this.hdas );
detailIds = detailIds || [];
options = options || {};
var history = this;
+ // add detailIds to options as CSV string
options.data = options.data || {};
if( detailIds.length ){
options.data.details = detailIds.join( ',' );
}
var xhr = this.hdas.fetch( options );
xhr.done( function( hdaModels ){
- //this.trigger( 'hdas-refreshed', this, hdaModels );
- history.checkForUpdates(function(){
- // fetch the history after an update in order to recalc history size
- //TODO: move to event?
+ history.checkForUpdates( function(){
+ // fetch the history inside onReadyCallback in order to recalc history size
this.fetch();
});
});
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/mvc/history/history-panel.js
--- a/static/scripts/mvc/history/history-panel.js
+++ b/static/scripts/mvc/history/history-panel.js
@@ -16,20 +16,14 @@
meta:
css/html class/id 'item' -> hda
add classes, ids on empty divs
- events (local/ui and otherwise)
- list in docs as well
- require.js
convert function comments to jsDoc style, complete comments
move inline styles into base.less
- watch the magic strings
- watch your globals
feature creep:
lineage
hide button
show permissions in info
show shared/sharing status on ds, history
- maintain scroll position on refresh (storage?)
selection, multi-select (and actions common to selected (ugh))
searching
sorting, re-shuffling
@@ -58,13 +52,14 @@
tagName : 'div',
className : 'history-panel',
- //fxSpeed : 'fast',
+ /** (in ms) that jquery effects will use */
fxSpeed : 300,
- /** event map
- */
+ /** event map */
events : {
'click #history-tag' : 'loadAndDisplayTags',
+ // allow (error) messages to be clicked away
+//TODO: switch to common close (X) idiom
'click #message-container' : 'clearMessages'
},
@@ -107,6 +102,10 @@
}
},
+ /** create any event listeners for the panel
+ * @fires: rendered:initial on the first render
+ * @fires: empty-history when switching to a history with no HDAs or creating a new history
+ */
_setUpListeners : function(){
// ---- event handlers for self
this.on( 'error', function( model, xhr, options, msg, details ){
@@ -154,13 +153,24 @@
//},
// ........................................................................ error handling
+ /** Event listener to handle errors (from the panel, the history, or the history's HDAs)
+ * @param {Model or View} model the (Backbone) source of the error
+ * @param {XMLHTTPRequest} xhr any ajax obj. assoc. with the error
+ * @param {Object} options the options map commonly used with bbone ajax
+ * @param {String} msg optional message passed to ease error location
+ * @param {Object} msg optional object containing error details
+ */
errorHandler : function( model, xhr, options, msg, details ){
var parsed = this._parseErrorMessage( model, xhr, options, msg, details );
+ // interrupted ajax
if( xhr && xhr.status === 0 && xhr.readyState === 0 ){
+ // bad gateway
} else if( xhr && xhr.status === 502 ){
+//TODO: gmail style 'reconnecting in Ns'
+ // otherwise, show an error message inside the panel
} else {
// it's possible to have a triggered error before the message container is rendered - wait for it to show
if( !this.$el.find( '#message-container' ).is( ':visible' ) ){
@@ -173,6 +183,9 @@
}
},
+ /** Parse an error event into an Object usable by displayMessage based on the parameters
+ * note: see errorHandler for more info on params
+ */
_parseErrorMessage : function( model, xhr, options, msg, details ){
var user = Galaxy.currUser,
// add the args (w/ some extra info) into an obj
@@ -199,12 +212,92 @@
return parsed;
},
+ /** Modify an error message to be fancy and wear a monocle. */
_bePolite : function( msg ){
msg = msg || _l( 'An error occurred while getting updates from the server' );
return msg + '. ' + _l( 'Please contact a Galaxy administrator if the problem persists.' );
},
// ------------------------------------------------------------------------ loading history/hda models
+
+ //NOTE: all the following fns replace the existing history model with a new model
+ // (in the following 'details' refers to the full set of hda api data (urls, display_apps, misc_info, etc.)
+ // - hdas w/o details will have summary data only (name, hid, deleted, visible, state, etc.))
+
+ /** (re-)loads the user's current history & hdas w/ details */
+ // implemented as a 'fresh start' or for when there is no model (intial panel render)
+ loadCurrentHistory : function( attributes ){
+ var panel = this;
+ return this.loadHistoryWithHDADetails( 'current', attributes )
+ .then(function( historyData, hdaData ){
+ panel.trigger( 'current-history', panel );
+ });
+ },
+
+ /** loads a history & hdas w/ details and makes them the current history */
+ switchToHistory : function( historyId, attributes ){
+ //console.info( 'switchToHistory:', historyId, attributes );
+ var panel = this,
+ historyFn = function(){
+ // make this current and get history data with one call
+ return jQuery.post( galaxy_config.root + 'api/histories/' + historyId + '/set_as_current' );
+ };
+ return this.loadHistoryWithHDADetails( historyId, attributes, historyFn )
+ .then(function( historyData, hdaData ){
+ panel.trigger( 'switched-history', panel );
+ });
+ },
+
+ /** creates a new history on the server and sets it as the user's current history */
+ createNewHistory : function( attributes ){
+ var panel = this,
+ historyFn = function(){
+ // get history data from posting a new history (and setting it to current)
+ return jQuery.post( galaxy_config.root + 'api/histories', { current: true });
+ };
+ // id undefined bc there is no historyId yet - the server will provide
+ // (no need for details - nothing expanded in new history)
+ return this.loadHistory( undefined, attributes, historyFn )
+ .then(function( historyData, hdaData ){
+ panel.trigger( 'new-history', panel );
+ });
+ },
+
+ /** loads a history & hdas w/ details (but does not make them the current history) */
+ loadHistoryWithHDADetails : function( historyId, attributes, historyFn, hdaFn ){
+ //console.info( 'loadHistoryWithHDADetails:', historyId, attributes, historyFn, hdaFn );
+ var panel = this,
+ // will be called to get hda ids that need details from the api
+ hdaDetailIds = function( historyData ){
+ return panel.getExpandedHdaIds( historyData.id );
+ };
+ return this.loadHistory( historyId, attributes, historyFn, hdaFn, hdaDetailIds );
+ },
+
+ /** loads a history & hdas w/ NO details (but does not make them the current history) */
+ loadHistory : function( historyId, attributes, historyFn, hdaFn, hdaDetailIds ){
+ this.trigger( 'loading-history', this );
+ attributes = attributes || {};
+ var panel = this;
+ //console.info( 'loadHistory:', historyId, attributes, historyFn, hdaFn, hdaDetailIds );
+ var xhr = historyModel.History.getHistoryData( historyId, {
+ historyFn : historyFn,
+ hdaFn : hdaFn,
+ hdaDetailIds : attributes.initiallyExpanded || hdaDetailIds
+ });
+ //console.debug( 'xhr:', xhr );
+ return this._loadHistoryFromXHR( xhr, attributes )
+ .fail( function( xhr, where, history ){
+ // throw an error up for the error handler
+ panel.trigger( 'error', panel, xhr, attributes, _l( 'An error was encountered while ' + where ),
+ { historyId: historyId, history: history || {} });
+ })
+ .always( function(){
+ // bc hideLoadingIndicator relies on this firing
+ panel.trigger( 'loading-done', panel );
+ });
+ },
+
/** given an xhr that will provide both history and hda data, pass data to set model or handle xhr errors */
_loadHistoryFromXHR : function( xhr, attributes ){
var panel = this;
@@ -246,84 +339,6 @@
return this;
},
- //NOTE: all the following fns replace the existing history model with a new model
- // (in the following 'details' refers to the full set of hda api data (urls, display_apps, misc_info, etc.)
- // - hdas w/o details will have summary data only (name, hid, deleted, visible, state, etc.))
-
- /** loads a history & hdas w/ NO details (but does not make them the current history) */
- loadHistory : function( historyId, attributes, historyFn, hdaFn, hdaDetailIds ){
- this.trigger( 'loading-history', this );
- attributes = attributes || {};
- var panel = this;
- //console.info( 'loadHistory:', historyId, attributes, historyFn, hdaFn, hdaDetailIds );
- var xhr = historyModel.History.getHistoryData( historyId, {
- historyFn : historyFn,
- hdaFn : hdaFn,
- hdaDetailIds : attributes.initiallyExpanded || hdaDetailIds
- });
- //console.debug( 'xhr:', xhr );
- return this._loadHistoryFromXHR( xhr, attributes )
- .fail( function( xhr, where, history ){
- // throw an error up for the error handler
- panel.trigger( 'error', panel, xhr, attributes, _l( 'An error was encountered while ' + where ),
- { historyId: historyId, history: history || {} });
- })
- .always( function(){
- // bc hideLoadingIndicator relies on this firing
- panel.trigger( 'loading-done', panel );
- });
- },
-
- /** loads a history & hdas w/ details (but does not make them the current history) */
- loadHistoryWithHDADetails : function( historyId, attributes, historyFn, hdaFn ){
- //console.info( 'loadHistoryWithHDADetails:', historyId, attributes, historyFn, hdaFn );
- var panel = this,
- // will be called to get hda ids that need details from the api
- hdaDetailIds = function( historyData ){
- return panel.getExpandedHdaIds( historyData.id );
- };
- return this.loadHistory( historyId, attributes, historyFn, hdaFn, hdaDetailIds );
- },
-
- /** loads a history & hdas w/ details and makes them the current history */
- switchToHistory : function( historyId, attributes ){
- //console.info( 'switchToHistory:', historyId, attributes );
- var panel = this,
- historyFn = function(){
- // make this current and get history data with one call
- return jQuery.post( galaxy_config.root + 'api/histories/' + historyId + '/set_as_current' );
- };
- return this.loadHistoryWithHDADetails( historyId, attributes, historyFn )
- .then(function( historyData, hdaData ){
- panel.trigger( 'switched-history', panel );
- });
- },
-
- /** (re-)loads the user's current history & hdas w/ details */
- // implemented as a 'fresh start' or for when there is no model (intial panel render)
- loadCurrentHistory : function( attributes ){
- var panel = this;
- return this.loadHistoryWithHDADetails( 'current', attributes )
- .then(function( historyData, hdaData ){
- panel.trigger( 'current-history', panel );
- });
- },
-
- /** creates a new history on the server and sets it as the user's current history */
- createNewHistory : function( attributes ){
- var panel = this,
- historyFn = function(){
- // get history data from posting a new history (and setting it to current)
- return jQuery.post( galaxy_config.root + 'api/histories', { current: true });
- };
- // id undefined bc there is no historyId yet - the server will provide
- // (no need for details - nothing expanded in new history)
- return this.loadHistory( undefined, attributes, historyFn )
- .then(function( historyData, hdaData ){
- panel.trigger( 'new-history', panel );
- });
- },
-
// alias to the model. Updates the hda list only (not the history)
refreshHdas : function( detailIds, options ){
if( this.model ){
@@ -334,15 +349,7 @@
},
// ------------------------------------------------------------------------ browser stored prefs
- //TODO: simplify
-
- /** key string to store each histories settings under */
- _getStorageKey : function( id ){
- if( !id ){
- throw new Error( '_getStorageKey needs valid id: ' + id );
- }
- return ( 'history:' + id );
- },
+//TODO: simplify
/** Set up client side storage. Currently PersistanStorage keyed under 'HistoryPanel.<id>'
* @param {Object} initiallyExpanded
@@ -359,7 +366,6 @@
// data that needs to be persistent over page refreshes
// (note the key function which uses the history id as well)
this.storage = new PersistentStorage( this._getStorageKey( this.model.get( 'id' ) ), {
- //TODO: initiallyExpanded only works on first load right now
expandedHdas : {},
show_deleted : false,
show_hidden : false
@@ -393,6 +399,15 @@
this.log( this + ' (init\'d) storage:', this.storage.get() );
},
+ /** key string to store each histories settings under */
+ _getStorageKey : function( id ){
+ if( !id ){
+ throw new Error( '_getStorageKey needs valid id: ' + id );
+ }
+ return ( 'history:' + id );
+ },
+
+ /** clear all stored history panel data */
clearWebStorage : function(){
for( var key in sessionStorage ){
if( key.indexOf( 'HistoryView.' ) === 0 ){
@@ -401,6 +416,7 @@
}
},
+ /** get all stored data as an Object for a history with the given id */
getStoredOptions : function( historyId ){
if( !historyId || historyId === 'current' ){
return ( this.storage )?( this.storage.get() ):( {} );
@@ -410,12 +426,14 @@
return ( item === null )?( {} ):( JSON.parse( item ) );
},
+ /** get all the map of expaneded hda ids for the given history id */
getExpandedHdaIds : function( historyId ){
var expandedHdas = this.getStoredOptions( historyId ).expandedHdas;
return (( _.isEmpty( expandedHdas ) )?( [] ):( _.keys( expandedHdas ) ));
},
// ------------------------------------------------------------------------ history/hda event listening
+ /** listening for history and HDA events */
_setUpModelEventHandlers : function(){
// ---- history
// on a model error - bounce it up to the panel and remove it from the model
@@ -454,7 +472,7 @@
this.model.hdas.on( 'state:ready', function( hda, newState, oldState ){
if( ( !hda.get( 'visible' ) )
&& ( !this.storage.get( 'show_hidden' ) ) ){
- this.removeHdaView( hda.get( 'id' ) );
+ this.removeHdaView( this.hdaViews[ hda.id ] );
}
}, this );
@@ -491,7 +509,9 @@
]);
},
-//TODO: use this below in renderItems
+ /** Create an HDA view for the given HDA (but leave attachment for addHdaView above)
+ * @param {HistoryDatasetAssociation} hda
+ */
createHdaView : function( hda ){
var hdaId = hda.get( 'id' ),
expanded = this.storage.get( 'expandedHdas' ).get( hdaId ),
@@ -506,12 +526,31 @@
return hdaView.render();
},
+ /** Set up HistoryPanel listeners for HDAView events. Currently binds:
+ * HDAView#body-visible, HDAView#body-hidden to store expanded states
+ * @param {HDAView} hdaView HDAView (base or edit) to listen to
+ */
+ _setUpHdaListeners : function( hdaView ){
+ var historyView = this;
+ // maintain a list of hdas whose bodies are expanded
+ hdaView.on( 'body-expanded', function( id ){
+ historyView.storage.get( 'expandedHdas' ).set( id, true );
+ });
+ hdaView.on( 'body-collapsed', function( id ){
+ historyView.storage.get( 'expandedHdas' ).deleteKey( id );
+ });
+//TODO: remove?
+ hdaView.on( 'error', function( model, xhr, options, msg ){
+ historyView.errorHandler( model, xhr, options, msg );
+ });
+ },
+
/** If this hda is deleted and we're not showing deleted hdas, remove the view
* @param {HistoryDataAssociation} the hda to check
*/
handleHdaDeletionChange : function( hda ){
if( hda.get( 'deleted' ) && !this.storage.get( 'show_deleted' ) ){
- this.removeHdaView( hda.get( 'id' ) );
+ this.removeHdaView( this.hdaViews[ hda.id ] );
} // otherwise, the hdaView rendering should handle it
},
@@ -520,22 +559,21 @@
*/
handleHdaVisibleChange : function( hda ){
if( hda.hidden() && !this.storage.get( 'show_hidden' ) ){
- this.removeHdaView( hda.get( 'id' ) );
+ this.removeHdaView( this.hdaViews[ hda.id ] );
} // otherwise, the hdaView rendering should handle it
},
/** Remove a view from the panel and if the panel is now empty, re-render
* @param {Int} the id of the hdaView to remove
*/
- removeHdaView : function( id ){
- //console.debug( 'removeHdaView' );
- var panel = this,
- hdaView = this.hdaViews[ id ];
+ removeHdaView : function( hdaView ){
if( !hdaView ){ return; }
+ var panel = this;
hdaView.$el.fadeOut( panel.fxSpeed, function(){
+ hdaView.off();
hdaView.remove();
- delete panel.hdaViews[ id ];
+ delete panel.hdaViews[ hdaView.model.id ];
if( _.isEmpty( panel.hdaViews ) ){
panel.$el.find( '#emptyHistoryMessage' ).fadeIn( panel.fxSpeed );
}
@@ -544,10 +582,9 @@
// ------------------------------------------------------------------------ panel rendering
/** Render urls, historyPanel body, and hdas (if any are shown)
+ * @fires: rendered when the panel is attached and fully visible
* @see Backbone.View#render
*/
- /** event rendered triggered when the panel rendering is complete */
- /** event rendered:initial triggered when the FIRST panel rendering is complete */
render : function( callback ){
var panel = this,
$newRender;
@@ -579,11 +616,13 @@
//TODO: ideally, these would be set up before the fade in (can't because of async save text)
panel._setUpBehaviours();
if( callback ){ callback.call( this ); }
+ panel.trigger( 'rendered', this );
}
]);
return this;
},
+ /** render with history data */
renderModel : function( ){
var $newRender = $( '<div/>' );
// render the main template, tooltips
@@ -601,7 +640,9 @@
return $newRender;
},
+ /** render with no history data */
renderWithoutModel : function( ){
+ // we'll always need the message container
var $newRender = $( '<div/>' ),
$msgContainer = $( '<div/>' ).attr( 'id', 'message-container' )
.css({ 'margin-left': '4px', 'margin-right': '4px' });
@@ -624,44 +665,12 @@
);
_.each( visibleHdas, function( hda ){
- var hdaId = hda.get( 'id' ),
- expanded = historyView.storage.get( 'expandedHdas' ).get( hdaId );
-
- historyView.hdaViews[ hdaId ] = new historyView.HDAView({
- model : hda,
- expanded : expanded,
- hasUser : historyView.model.hasUser(),
- logger : historyView.logger
- });
- historyView._setUpHdaListeners( historyView.hdaViews[ hdaId ] );
-
// render it (NOTE: reverse order, newest on top (prepend))
- //TODO: by default send a reverse order list (although this may be more efficient - it's more confusing)
- $whereTo.prepend( historyView.hdaViews[ hdaId ].render().$el );
+ $whereTo.prepend( historyView.createHdaView( hda ).$el );
});
return visibleHdas.length;
},
- /** Set up HistoryPanel listeners for HDAView events. Currently binds:
- * HDAView#body-visible, HDAView#body-hidden to store expanded states
- * @param {HDAView} hdaView HDAView (base or edit) to listen to
- */
- _setUpHdaListeners : function( hdaView ){
- var historyView = this;
- // maintain a list of hdas whose bodies are expanded
- hdaView.on( 'body-expanded', function( id ){
- historyView.storage.get( 'expandedHdas' ).set( id, true );
- });
- hdaView.on( 'body-collapsed', function( id ){
- historyView.storage.get( 'expandedHdas' ).deleteKey( id );
- });
-//TODO: remove?
- hdaView.on( 'error', function( model, xhr, options, msg ){
-//TODO: change to modal?
- historyView.errorHandler( model, xhr, options, msg );
- });
- },
-
/** Set up HistoryPanel js/widget behaviours
*/
//TODO: these should be either sub-MVs, or handled by events
@@ -770,6 +779,7 @@
},
// ........................................................................ loading indicator
+ /** hide the panel and display a loading indicator (in the panel's parent) when history model's are switched */
showLoadingIndicator : function( msg, speed, callback ){
speed = ( speed !== undefined )?( speed ):( this.fxSpeed );
if( !this.indicator ){
@@ -783,6 +793,7 @@
}
},
+ /** hide the loading indicator */
hideLoadingIndicator : function( speed, callback ){
speed = ( speed !== undefined )?( speed ):( this.fxSpeed );
if( this.indicator ){
@@ -816,6 +827,7 @@
return $msgContainer.html( $msg );
},
+ /** convert msg and details into modal options usable by Galaxy.modal */
messageToModalOptions : function( type, msg, details ){
// only error is fleshed out here
var panel = this,
@@ -860,10 +872,12 @@
},
// ........................................................................ scrolling
+ /** get the current scroll position of the panel in its parent */
scrollPosition : function(){
return this.$el.parent().scrollTop();
},
+ /** set the current scroll position of the panel in its parent */
scrollTo : function( pos ){
this.$el.parent().scrollTop( pos );
},
@@ -925,6 +939,7 @@
// ........................................................................ external objects/MVC
//TODO: remove quota meter from panel and remove this
+ /** add listeners to an external quota meter (mvc/user/user-quotameter.js) */
connectToQuotaMeter : function( quotaMeter ){
if( !quotaMeter ){
return this;
@@ -942,25 +957,26 @@
return this;
},
+//TODO: this seems more like a per user message than a history message; IOW, this doesn't belong here
/** Show the over quota message (which happens to be in the history panel).
*/
-//TODO: this seems more like a per user message than a history message; IOW, this doesn't belong here
showQuotaMessage : function(){
var msg = this.$el.find( '#quota-message-container' );
//this.log( this + ' showing quota message:', msg, userData );
if( msg.is( ':hidden' ) ){ msg.slideDown( this.fxSpeed ); }
},
+//TODO: this seems more like a per user message than a history message
/** Hide the over quota message (which happens to be in the history panel).
*/
-//TODO: this seems more like a per user message than a history message
hideQuotaMessage : function(){
var msg = this.$el.find( '#quota-message-container' );
//this.log( this + ' hiding quota message:', msg, userData );
if( !msg.is( ':hidden' ) ){ msg.slideUp( this.fxSpeed ); }
},
- //TODO: move show_deleted/hidden into panel from opt menu and remove this
+//TODO: move show_deleted/hidden into panel from opt menu and remove this
+ /** add listeners to an external options menu (templates/webapps/galaxy/root/index.mako) */
connectToOptionsMenu : function( optionsMenu ){
if( !optionsMenu ){
return this;
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/packed/mvc/dataset/hda-base.js
--- a/static/scripts/packed/mvc/dataset/hda-base.js
+++ b/static/scripts/packed/mvc/dataset/hda-base.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/hda-model"],function(b){var a=Backbone.View.extend(LoggableMixin).extend({tagName:"div",className:"historyItemContainer",fxSpeed:"fast",initialize:function(c){if(c.logger){this.logger=this.model.logger=c.logger}this.log(this+".initialize:",c);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.expanded=c.expanded||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(d,c){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(){var d=this,g=this.model.get("id"),e=this.model.get("state"),c=$("<div/>").attr("id","historyItem-"+g),f=(this.$el.children().size()===0);this.$el.attr("id","historyItemContainer-"+g);this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();c.addClass("historyItemWrapper").addClass("historyItem").addClass("historyItem-"+e);c.append(this._render_warnings());c.append(this._render_titleBar());this._setUpBehaviors(c);this.body=$(this._render_body());c.append(this.body);this.$el.fadeOut(this.fxSpeed,function(){d.$el.children().remove();d.$el.append(c).fadeIn(d.fxSpeed,function(){d.log(d+" rendered:",d.$el);var h="rendered";if(f){h+=":initial"}else{if(d.model.inReadyState()){h+=":ready"}}d.trigger(h)})});return this},_setUpBehaviors:function(c){c=c||this.$el;make_popup_menus(c);c.find("[title]").tooltip({placement:"bottom"})},_render_warnings:function(){return $(jQuery.trim(a.templates.messages(this.model.toJSON())))},_render_titleBar:function(){var c=$('<div class="historyItemTitleBar" style="overflow: hidden"></div>');c.append(this._render_titleButtons());c.append('<span class="state-icon"></span>');c.append(this._render_titleLink());return c},_render_titleButtons:function(){var c=$('<div class="historyItemButtons"></div>');c.append(this._render_displayButton());return c},_render_displayButton:function(){if((this.model.get("state")===b.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===b.HistoryDatasetAssociation.STATES.NEW)||(!this.model.get("accessible"))){this.displayButton=null;return null}var d={icon_class:"display",target:"galaxy_main"};if(this.model.get("purged")){d.enabled=false;d.title=_l("Cannot display datasets removed from disk")}else{if(this.model.get("state")===b.HistoryDatasetAssociation.STATES.UPLOAD){d.enabled=false;d.title=_l("This dataset must finish uploading before it can be viewed")}else{d.title=_l("View data");d.href=this.urls.display;var c=this;d.on_click=function(){Galaxy.frame_manager.frame_new({title:"Data Viewer: "+c.model.get("name"),type:"url",location:"center",content:c.urls.display})}}}this.displayButton=new IconButtonView({model:new IconButton(d)});return this.displayButton.render().$el},_render_titleLink:function(){return $(jQuery.trim(a.templates.titleLink(_.extend(this.model.toJSON(),{urls:this.urls}))))},_render_hdaSummary:function(){var c=_.extend(this.model.toJSON(),{urls:this.urls});return a.templates.hdaSummary(c)},_render_primaryActionButtons:function(e){var c=this,d=$("<div/>").attr("id","primary-actions-"+this.model.get("id"));_.each(e,function(f){d.append(f.call(c))});return d},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var c=a.templates.downloadLinks(_.extend(this.model.toJSON(),{urls:this.urls}));return $(c.trim())},_render_showParamsButton:function(){this.showParamsButton=new IconButtonView({model:new IconButton({title:_l("View details"),href:this.urls.show_params,target:"galaxy_main",icon_class:"information"})});return this.showParamsButton.render().$el},_render_displayAppArea:function(){return $("<div/>").addClass("display-apps")},_render_displayApps:function(e){e=e||this.$el;var f=e.find("div.display-apps"),c=this.model.get("display_types"),d=this.model.get("display_apps");if((!this.model.hasData())||(!e||!e.length)||(!f.length)){return}f.html(null);if(!_.isEmpty(c)){f.append(a.templates.displayApps({displayApps:c}))}if(!_.isEmpty(d)){f.append(a.templates.displayApps({displayApps:d}))}},_render_peek:function(){var c=this.model.get("peek");if(!c){return null}return $("<div/>").append($("<pre/>").attr("id","peek"+this.model.get("id")).addClass("peek").append(c))},_render_body:function(){var c=$("<div/>").attr("id","info-"+this.model.get("id")).addClass("historyItemBody").attr("style","display: none");if(this.expanded){this._render_body_html(c);c.css("display","block")}return c},_render_body_html:function(c){c.html("");switch(this.model.get("state")){case b.HistoryDatasetAssociation.STATES.NEW:this._render_body_new(c);break;case b.HistoryDatasetAssociation.STATES.NOT_VIEWABLE:this._render_body_not_viewable(c);break;case b.HistoryDatasetAssociation.STATES.UPLOAD:this._render_body_uploading(c);break;case b.HistoryDatasetAssociation.STATES.PAUSED:this._render_body_paused(c);break;case b.HistoryDatasetAssociation.STATES.QUEUED:this._render_body_queued(c);break;case b.HistoryDatasetAssociation.STATES.RUNNING:this._render_body_running(c);break;case b.HistoryDatasetAssociation.STATES.ERROR:this._render_body_error(c);break;case b.HistoryDatasetAssociation.STATES.DISCARDED:this._render_body_discarded(c);break;case b.HistoryDatasetAssociation.STATES.SETTING_METADATA:this._render_body_setting_metadata(c);break;case b.HistoryDatasetAssociation.STATES.EMPTY:this._render_body_empty(c);break;case b.HistoryDatasetAssociation.STATES.FAILED_METADATA:this._render_body_failed_metadata(c);break;case b.HistoryDatasetAssociation.STATES.OK:this._render_body_ok(c);break;default:c.append($('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'))}c.append('<div style="clear: both"></div>');this._setUpBehaviors(c)},_render_body_new:function(d){var c=_l("This is a new dataset and not all of its data are available yet");d.append($("<div>"+_l(c)+"</div>"))},_render_body_not_viewable:function(c){c.append($("<div>"+_l("You do not have permission to view dataset")+"</div>"))},_render_body_uploading:function(c){c.append($("<div>"+_l("Dataset is uploading")+"</div>"))},_render_body_queued:function(c){c.append($("<div>"+_l("Job is waiting to run")+"</div>"));c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_paused:function(c){c.append($("<div>"+_l("Job is paused. Use the history menu to resume")+"</div>"));c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_running:function(c){c.append("<div>"+_l("Job is currently running")+"</div>");c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_error:function(c){if(!this.model.get("purged")){c.append($("<div>"+this.model.get("misc_blurb")+"</div>"))}c.append((_l("An error occurred with this dataset")+": <i>"+$.trim(this.model.get("misc_info"))+"</i>"));c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers.concat([this._render_downloadButton])))},_render_body_discarded:function(c){c.append("<div>"+_l("The job creating this dataset was cancelled before completion")+".</div>");c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_setting_metadata:function(c){c.append($("<div>"+_l("Metadata is being auto-detected")+".</div>"))},_render_body_empty:function(c){c.append($("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>"));c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_failed_metadata:function(c){c.append($(a.templates.failedMetadata(_.extend(this.model.toJSON(),{urls:this.urls}))));this._render_body_ok(c)},_render_body_ok:function(c){c.append(this._render_hdaSummary());if(this.model.isDeletedOrPurged()){c.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton]));return}c.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton]));c.append('<div class="clear"/>');c.append(this._render_displayAppArea());this._render_displayApps(c);c.append(this._render_peek())},events:{"click .historyItemTitle":"toggleBodyVisibility"},toggleBodyVisibility:function(e,c){var d=this;c=(c===undefined)?(!this.body.is(":visible")):(c);if(c){if(this.model.inReadyState()&&!this.model.hasDetails()){var f=this.model.fetch();f.done(function(g){d.expandBody()})}else{this.expandBody()}}else{this.collapseBody()}},expandBody:function(){var c=this;c._render_body_html(c.body);this.body.slideDown(c.fxSpeed,function(){c.expanded=true;c.trigger("body-expanded",c.model.get("id"))})},collapseBody:function(){var c=this;this.body.slideUp(c.fxSpeed,function(){c.expanded=false;c.trigger("body-collapsed",c.model.get("id"))})},remove:function(d){var c=this;this.$el.fadeOut(c.fxSpeed,function(){c.$el.remove();c.off();if(d){d()}})},toString:function(){var c=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+c+")"}});a.templates={warningMsg:Handlebars.templates["template-warningmessagesmall"],messages:Handlebars.templates["template-hda-warning-messages"],titleLink:Handlebars.templates["template-hda-titleLink"],hdaSummary:Handlebars.templates["template-hda-hdaSummary"],downloadLinks:Handlebars.templates["template-hda-downloadLinks"],failedMetadata:Handlebars.templates["template-hda-failedMetadata"],displayApps:Handlebars.templates["template-hda-displayApps"]};return{HDABaseView:a,}});
\ No newline at end of file
+define(["mvc/dataset/hda-model"],function(b){var a=Backbone.View.extend(LoggableMixin).extend({tagName:"div",className:"historyItemContainer",fxSpeed:"fast",initialize:function(c){if(c.logger){this.logger=this.model.logger=c.logger}this.log(this+".initialize:",c);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.expanded=c.expanded||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(d,c){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(){var d=this,g=this.model.get("id"),e=this.model.get("state"),c=$("<div/>").attr("id","historyItem-"+g),f=(this.$el.children().size()===0);this.$el.attr("id","historyItemContainer-"+g);this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();c.addClass("historyItemWrapper").addClass("historyItem").addClass("historyItem-"+e);c.append(this._render_warnings());c.append(this._render_titleBar());this._setUpBehaviors(c);this.body=$(this._render_body());c.append(this.body);this.$el.fadeOut(this.fxSpeed,function(){d.$el.children().remove();d.$el.append(c).fadeIn(d.fxSpeed,function(){d.log(d+" rendered:",d.$el);var h="rendered";if(f){h+=":initial"}else{if(d.model.inReadyState()){h+=":ready"}}d.trigger(h)})});return this},_setUpBehaviors:function(c){c=c||this.$el;make_popup_menus(c);c.find("[title]").tooltip({placement:"bottom"})},_render_warnings:function(){return $(jQuery.trim(a.templates.messages(this.model.toJSON())))},_render_titleBar:function(){var c=$('<div class="historyItemTitleBar" style="overflow: hidden"></div>');c.append(this._render_titleButtons());c.append('<span class="state-icon"></span>');c.append(this._render_titleLink());return c},_render_titleButtons:function(){var c=$('<div class="historyItemButtons"></div>');c.append(this._render_displayButton());return c},_render_displayButton:function(){if((this.model.get("state")===b.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===b.HistoryDatasetAssociation.STATES.NEW)||(!this.model.get("accessible"))){this.displayButton=null;return null}var d={icon_class:"display",target:"galaxy_main"};if(this.model.get("purged")){d.enabled=false;d.title=_l("Cannot display datasets removed from disk")}else{if(this.model.get("state")===b.HistoryDatasetAssociation.STATES.UPLOAD){d.enabled=false;d.title=_l("This dataset must finish uploading before it can be viewed")}else{d.title=_l("View data");d.href=this.urls.display;var c=this;d.on_click=function(){Galaxy.frame_manager.frame_new({title:"Data Viewer: "+c.model.get("name"),type:"url",location:"center",content:c.urls.display})}}}this.displayButton=new IconButtonView({model:new IconButton(d)});return this.displayButton.render().$el},_render_titleLink:function(){return $(jQuery.trim(a.templates.titleLink(this.model.toJSON())))},_render_hdaSummary:function(){var c=_.extend(this.model.toJSON(),{urls:this.urls});return a.templates.hdaSummary(c)},_render_primaryActionButtons:function(e){var c=this,d=$("<div/>").attr("id","primary-actions-"+this.model.get("id"));_.each(e,function(f){d.append(f.call(c))});return d},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var c=a.templates.downloadLinks(_.extend(this.model.toJSON(),{urls:this.urls}));return $(c.trim())},_render_showParamsButton:function(){this.showParamsButton=new IconButtonView({model:new IconButton({title:_l("View details"),href:this.urls.show_params,target:"galaxy_main",icon_class:"information"})});return this.showParamsButton.render().$el},_render_displayAppArea:function(){return $("<div/>").addClass("display-apps")},_render_displayApps:function(e){e=e||this.$el;var f=e.find("div.display-apps"),c=this.model.get("display_types"),d=this.model.get("display_apps");if((!this.model.hasData())||(!e||!e.length)||(!f.length)){return}f.html(null);if(!_.isEmpty(c)){f.append(a.templates.displayApps({displayApps:c}))}if(!_.isEmpty(d)){f.append(a.templates.displayApps({displayApps:d}))}},_render_peek:function(){var c=this.model.get("peek");if(!c){return null}return $("<div/>").append($("<pre/>").attr("id","peek"+this.model.get("id")).addClass("peek").append(c))},_render_body:function(){var c=$("<div/>").attr("id","info-"+this.model.get("id")).addClass("historyItemBody").attr("style","display: none");if(this.expanded){this._render_body_html(c);c.show()}return c},_render_body_html:function(e){e.empty();var c=this.model.get("state");var f="_render_body_"+c,d=this[f];if(_.isFunction(d)){this[f](e)}else{e.append($('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'))}e.append('<div style="clear: both"></div>');this._setUpBehaviors(e)},_render_body_new:function(d){var c=_l("This is a new dataset and not all of its data are available yet");d.append($("<div>"+_l(c)+"</div>"))},_render_body_noPermission:function(c){c.append($("<div>"+_l("You do not have permission to view this dataset")+"</div>"))},_render_body_upload:function(c){c.append($("<div>"+_l("Dataset is uploading")+"</div>"))},_render_body_queued:function(c){c.append($("<div>"+_l("Job is waiting to run")+"</div>"));c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_paused:function(c){c.append($("<div>"+_l('Job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>"));c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_running:function(c){c.append("<div>"+_l("Job is currently running")+"</div>");c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_error:function(c){if(!this.model.get("purged")){c.append($("<div>"+this.model.get("misc_blurb")+"</div>"))}c.append((_l("An error occurred with this dataset")+": <i>"+$.trim(this.model.get("misc_info"))+"</i>"));c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers.concat([this._render_downloadButton])))},_render_body_discarded:function(c){c.append("<div>"+_l("The job creating this dataset was cancelled before completion")+".</div>");c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_setting_metadata:function(c){c.append($("<div>"+_l("Metadata is being auto-detected")+".</div>"))},_render_body_empty:function(c){c.append($("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>"));c.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_failed_metadata:function(c){c.append($(a.templates.failedMetadata(_.extend(this.model.toJSON(),{urls:this.urls}))));this._render_body_ok(c)},_render_body_ok:function(c){c.append(this._render_hdaSummary());if(this.model.isDeletedOrPurged()){c.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton]));return}c.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton]));c.append('<div class="clear"/>');c.append(this._render_displayAppArea());this._render_displayApps(c);c.append(this._render_peek())},events:{"click .historyItemTitle":"toggleBodyVisibility"},toggleBodyVisibility:function(d,c){c=(c===undefined)?(!this.body.is(":visible")):(c);if(c){this.expandBody()}else{this.collapseBody()}},expandBody:function(){var c=this;function d(){c._render_body_html(c.body);c.body.slideDown(c.fxSpeed,function(){c.expanded=true;c.trigger("body-expanded",c.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch().done(function(e){d()})}else{d()}},collapseBody:function(){var c=this;this.body.slideUp(c.fxSpeed,function(){c.expanded=false;c.trigger("body-collapsed",c.model.get("id"))})},remove:function(d){var c=this;this.$el.fadeOut(c.fxSpeed,function(){c.$el.remove();c.off();if(d){d()}})},toString:function(){var c=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+c+")"}});a.templates={warningMsg:Handlebars.templates["template-warningmessagesmall"],messages:Handlebars.templates["template-hda-warning-messages"],titleLink:Handlebars.templates["template-hda-titleLink"],hdaSummary:Handlebars.templates["template-hda-hdaSummary"],downloadLinks:Handlebars.templates["template-hda-downloadLinks"],failedMetadata:Handlebars.templates["template-hda-failedMetadata"],displayApps:Handlebars.templates["template-hda-displayApps"]};return{HDABaseView:a}});
\ No newline at end of file
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/packed/mvc/dataset/hda-edit.js
--- a/static/scripts/packed/mvc/dataset/hda-edit.js
+++ b/static/scripts/packed/mvc/dataset/hda-edit.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/hda-model","mvc/dataset/hda-base"],function(d,a){var f=a.HDABaseView.extend(LoggableMixin).extend({initialize:function(g){a.HDABaseView.prototype.initialize.call(this,g);this.hasUser=g.hasUser;this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton,this._render_rerunButton]},_setUpBehaviors:function(g){a.HDABaseView.prototype._setUpBehaviors.call(this,g)},_render_warnings:function(){return $(jQuery.trim(a.HDABaseView.templates.messages(_.extend(this.model.toJSON(),{urls:this.urls}))))},_render_titleButtons:function(){var g=$('<div class="historyItemButtons"></div>');g.append(this._render_displayButton());g.append(this._render_editButton());g.append(this._render_deleteButton());return g},_render_editButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.editButton=null;return null}var i=this.model.get("purged"),g=this.model.get("deleted"),h={title:_l("Edit Attributes"),href:this.urls.edit,target:"galaxy_main",icon_class:"edit"};if(g||i){h.enabled=false;if(i){h.title=_l("Cannot edit attributes of datasets removed from disk")}else{if(g){h.title=_l("Undelete dataset to edit attributes")}}}this.editButton=new IconButtonView({model:new IconButton(h)});return this.editButton.render().$el},_render_deleteButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.deleteButton=null;return null}var g=this,j="historyItemDeleter-"+g.model.get("id"),h=g.urls["delete"],i={title:_l("Delete"),href:h,id:j,icon_class:"delete",on_click:function(){g.$el.find(".menu-button.delete").trigger("mouseout");g.model["delete"]()}};if(this.model.get("deleted")||this.model.get("purged")){i={title:_l("Dataset is already deleted"),icon_class:"delete",enabled:false}}this.deleteButton=new IconButtonView({model:new IconButton(i)});return this.deleteButton.render().$el},_render_hdaSummary:function(){var g=_.extend(this.model.toJSON(),{urls:this.urls});if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){_.extend(g,{dbkey_unknown_and_editable:true})}return a.HDABaseView.templates.hdaSummary(g)},_render_errButton:function(){if(this.model.get("state")!==d.HistoryDatasetAssociation.STATES.ERROR){this.errButton=null;return null}this.errButton=new IconButtonView({model:new IconButton({title:_l("View or report this error"),href:this.urls.report_error,target:"galaxy_main",icon_class:"bug"})});return this.errButton.render().$el},_render_rerunButton:function(){this.rerunButton=new IconButtonView({model:new IconButton({title:_l("Run this job again"),href:this.urls.rerun,target:"galaxy_main",icon_class:"arrow-circle"})});return this.rerunButton.render().$el},_render_visualizationsButton:function(){var g=this.model.get("visualizations");if((!this.model.hasData())||(_.isEmpty(g))){this.visualizationsButton=null;return null}if(_.isObject(g[0])){return this._render_visualizationsFrameworkButton(g)}if(!this.urls.visualization){this.visualizationsButton=null;return null}var i=this.model.get("dbkey"),l=this.urls.visualization,j={},m={dataset_id:this.model.get("id"),hda_ldda:"hda"};if(i){m.dbkey=i}this.visualizationsButton=new IconButtonView({model:new IconButton({title:_l("Visualize"),href:this.urls.visualization,icon_class:"chart_curve"})});var h=this.visualizationsButton.render().$el;h.addClass("visualize-icon");function k(n){switch(n){case"trackster":return b(l,m,i);case"scatterplot":return e(l,m);default:return function(){Galaxy.frame_manager.frame_new({title:"Visualization",type:"url",content:l+"/"+n+"?"+$.param(m)})}}}if(g.length===1){h.attr("title",g[0]);h.click(k(g[0]))}else{_.each(g,function(o){var n=o.charAt(0).toUpperCase()+o.slice(1);j[_l(n)]=k(o)});make_popupmenu(h,j)}return h},_render_visualizationsFrameworkButton:function(g){if(!(this.model.hasData())||!(g&&!_.isEmpty(g))){this.visualizationsButton=null;return null}this.visualizationsButton=new IconButtonView({model:new IconButton({title:_l("Visualize"),icon_class:"chart_curve"})});var i=this.visualizationsButton.render().$el;i.addClass("visualize-icon");if(_.keys(g).length===1){i.attr("title",_.keys(g)[0]);i.attr("href",_.values(g)[0])}else{var j=[];_.each(g,function(k){j.push(k)});var h=new PopupMenu(i,j)}return i},_render_secondaryActionButtons:function(h){var i=$("<div/>"),g=this;i.attr("style","float: right;").attr("id","secondary-actions-"+this.model.get("id"));_.each(h,function(j){i.append(j.call(g))});return i},_render_tagButton:function(){if(!this.hasUser||!this.urls.tags.get){this.tagButton=null;return null}this.tagButton=new IconButtonView({model:new IconButton({title:_l("Edit dataset tags"),target:"galaxy_main",href:this.urls.tags.get,icon_class:"tags"})});return this.tagButton.render().$el},_render_annotateButton:function(){if(!this.hasUser||!this.urls.annotation.get){this.annotateButton=null;return null}this.annotateButton=new IconButtonView({model:new IconButton({title:_l("Edit dataset annotation"),target:"galaxy_main",icon_class:"annotate"})});return this.annotateButton.render().$el},_render_tagArea:function(){if(!this.urls.tags.set){return null}return $(f.templates.tagArea(_.extend(this.model.toJSON(),{urls:this.urls})).trim())},_render_annotationArea:function(){if(!this.urls.annotation.get){return null}return $(f.templates.annotationArea(_.extend(this.model.toJSON(),{urls:this.urls})).trim())},_render_body_error:function(g){a.HDABaseView.prototype._render_body_error.call(this,g);var h=g.find("#primary-actions-"+this.model.get("id"));h.prepend(this._render_errButton())},_render_body_ok:function(g){g.append(this._render_hdaSummary());if(this.model.isDeletedOrPurged()){g.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton,this._render_rerunButton]));return}g.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton,this._render_rerunButton,this._render_visualizationsButton]));g.append(this._render_secondaryActionButtons([this._render_tagButton,this._render_annotateButton]));g.append('<div class="clear"/>');g.append(this._render_tagArea());g.append(this._render_annotationArea());g.append(this._render_displayAppArea());this._render_displayApps(g);g.append(this._render_peek())},events:{"click .historyItemTitle":"toggleBodyVisibility","click .historyItemUndelete":function(g){this.model.undelete();return false},"click .historyItemUnhide":function(g){this.model.unhide();return false},"click .historyItemPurge":"confirmPurge","click a.icon-button.tags":"loadAndDisplayTags","click a.icon-button.annotate":"loadAndDisplayAnnotation"},confirmPurge:function c(g){this.model.purge({url:this.urls.purge});return false},loadAndDisplayTags:function(i){this.log(this+".loadAndDisplayTags",i);var g=this,j=this.$el.find(".tag-area"),h=j.find(".tag-elt");if(j.is(":hidden")){if(!jQuery.trim(h.html())){$.ajax({url:this.urls.tags.get,error:function(m,k,l){g.log("Tagging failed",m,k,l);g.trigger("error",g,m,{},_l("Tagging failed"))},success:function(k){h.html(k);h.find("[title]").tooltip();j.slideDown(g.fxSpeed)}})}else{j.slideDown(g.fxSpeed)}}else{j.slideUp(g.fxSpeed)}return false},loadAndDisplayAnnotation:function(i){this.log(this+".loadAndDisplayAnnotation",i);var g=this,k=this.$el.find(".annotation-area"),j=k.find(".annotation-elt"),h=this.urls.annotation.set;if(k.is(":hidden")){if(!jQuery.trim(j.html())){$.ajax({url:this.urls.annotation.get,error:function(){g.log("Annotation failed",xhr,status,error);g.trigger("error",g,xhr,{},_l("Annotation failed"))},success:function(l){if(l===""){l="<em>"+_l("Describe or add notes to dataset")+"</em>"}j.html(l);k.find("[title]").tooltip();async_save_text(j.attr("id"),j.attr("id"),h,"new_annotation",18,true,4);k.slideDown(g.fxSpeed)}})}else{k.slideDown(g.fxSpeed)}}else{k.slideUp(g.fxSpeed)}return false},toString:function(){var g=(this.model)?(this.model+""):("(no model)");return"HDAView("+g+")"}});f.templates={tagArea:Handlebars.templates["template-hda-tagArea"],annotationArea:Handlebars.templates["template-hda-annotationArea"]};function e(g,h){action=function(){Galaxy.frame_manager.frame_new({title:"Scatterplot",type:"url",content:g+"/scatterplot?"+$.param(h),location:"center"});$("div.popmenu-wrapper").remove();return false};return action}function b(g,i,h){return function(){var j={};if(h){j["f-dbkey"]=h}$.ajax({url:g+"/list_tracks?"+$.param(j),dataType:"html",error:function(){alert(("Could not add this dataset to browser")+".")},success:function(k){var l=window.parent;l.Galaxy.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){l.Galaxy.modal.hide()},"View in saved visualization":function(){l.Galaxy.modal.show({title:"Add Data to Saved Visualization",body:k,buttons:{Cancel:function(){l.Galaxy.modal.hide()},"Add to visualization":function(){$(l.document).find("input[name=id]:checked").each(function(){l.Galaxy.modal.hide();var m=$(this).val();i.id=m;l.Galaxy.frame_manager.frame_new({title:"Trackster",type:"url",content:g+"/trackster?"+$.param(i)})})}}})},"View in new visualization":function(){l.Galaxy.modal.hide();var m=g+"/trackster?"+$.param(i);l.Galaxy.frame_manager.frame_new({title:"Trackster",type:"url",content:m})}}})}});return false}}return{HDAEditView:f,}});
\ No newline at end of file
+define(["mvc/dataset/hda-model","mvc/dataset/hda-base"],function(d,a){var f=a.HDABaseView.extend(LoggableMixin).extend({initialize:function(g){a.HDABaseView.prototype.initialize.call(this,g);this.hasUser=g.hasUser;this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton,this._render_rerunButton]},_setUpBehaviors:function(g){a.HDABaseView.prototype._setUpBehaviors.call(this,g)},_render_warnings:function(){return $(jQuery.trim(a.HDABaseView.templates.messages(_.extend(this.model.toJSON(),{urls:this.urls}))))},_render_titleButtons:function(){var g=$('<div class="historyItemButtons"></div>');g.append(this._render_displayButton());g.append(this._render_editButton());g.append(this._render_deleteButton());return g},_render_editButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.editButton=null;return null}var i=this.model.get("purged"),g=this.model.get("deleted"),h={title:_l("Edit Attributes"),href:this.urls.edit,target:"galaxy_main",icon_class:"edit"};if(g||i){h.enabled=false;if(i){h.title=_l("Cannot edit attributes of datasets removed from disk")}else{if(g){h.title=_l("Undelete dataset to edit attributes")}}}this.editButton=new IconButtonView({model:new IconButton(h)});return this.editButton.render().$el},_render_deleteButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.deleteButton=null;return null}var g=this,j="historyItemDeleter-"+g.model.get("id"),h=g.urls["delete"],i={title:_l("Delete"),href:h,id:j,icon_class:"delete",on_click:function(){g.$el.find(".menu-button.delete").trigger("mouseout");g.model["delete"]()}};if(this.model.get("deleted")||this.model.get("purged")){i={title:_l("Dataset is already deleted"),icon_class:"delete",enabled:false}}this.deleteButton=new IconButtonView({model:new IconButton(i)});return this.deleteButton.render().$el},_render_hdaSummary:function(){var g=_.extend(this.model.toJSON(),{urls:this.urls});if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){_.extend(g,{dbkey_unknown_and_editable:true})}return a.HDABaseView.templates.hdaSummary(g)},_render_errButton:function(){if(this.model.get("state")!==d.HistoryDatasetAssociation.STATES.ERROR){this.errButton=null;return null}this.errButton=new IconButtonView({model:new IconButton({title:_l("View or report this error"),href:this.urls.report_error,target:"galaxy_main",icon_class:"bug"})});return this.errButton.render().$el},_render_rerunButton:function(){this.rerunButton=new IconButtonView({model:new IconButton({title:_l("Run this job again"),href:this.urls.rerun,target:"galaxy_main",icon_class:"arrow-circle"})});return this.rerunButton.render().$el},_render_visualizationsButton:function(){var g=this.model.get("visualizations");if((!this.model.hasData())||(_.isEmpty(g))){this.visualizationsButton=null;return null}if(_.isObject(g[0])){return this._render_visualizationsFrameworkButton(g)}if(!this.urls.visualization){this.visualizationsButton=null;return null}var i=this.model.get("dbkey"),l=this.urls.visualization,j={},m={dataset_id:this.model.get("id"),hda_ldda:"hda"};if(i){m.dbkey=i}this.visualizationsButton=new IconButtonView({model:new IconButton({title:_l("Visualize"),href:this.urls.visualization,icon_class:"chart_curve"})});var h=this.visualizationsButton.render().$el;h.addClass("visualize-icon");function k(n){switch(n){case"trackster":return b(l,m,i);case"scatterplot":return e(l,m);default:return function(){Galaxy.frame_manager.frame_new({title:"Visualization",type:"url",content:l+"/"+n+"?"+$.param(m)})}}}if(g.length===1){h.attr("title",g[0]);h.click(k(g[0]))}else{_.each(g,function(o){var n=o.charAt(0).toUpperCase()+o.slice(1);j[_l(n)]=k(o)});make_popupmenu(h,j)}return h},_render_visualizationsFrameworkButton:function(g){if(!(this.model.hasData())||!(g&&!_.isEmpty(g))){this.visualizationsButton=null;return null}this.visualizationsButton=new IconButtonView({model:new IconButton({title:_l("Visualize"),icon_class:"chart_curve"})});var i=this.visualizationsButton.render().$el;i.addClass("visualize-icon");if(_.keys(g).length===1){i.attr("title",_.keys(g)[0]);i.attr("href",_.values(g)[0])}else{var j=[];_.each(g,function(k){j.push(k)});var h=new PopupMenu(i,j)}return i},_render_secondaryActionButtons:function(h){var i=$("<div/>"),g=this;i.attr("style","float: right;").attr("id","secondary-actions-"+this.model.get("id"));_.each(h,function(j){i.append(j.call(g))});return i},_render_tagButton:function(){if(!this.hasUser||!this.urls.tags.get){this.tagButton=null;return null}this.tagButton=new IconButtonView({model:new IconButton({title:_l("Edit dataset tags"),target:"galaxy_main",href:this.urls.tags.get,icon_class:"tags"})});return this.tagButton.render().$el},_render_annotateButton:function(){if(!this.hasUser||!this.urls.annotation.get){this.annotateButton=null;return null}this.annotateButton=new IconButtonView({model:new IconButton({title:_l("Edit dataset annotation"),target:"galaxy_main",icon_class:"annotate"})});return this.annotateButton.render().$el},_render_body_error:function(g){a.HDABaseView.prototype._render_body_error.call(this,g);var h=g.find("#primary-actions-"+this.model.get("id"));h.prepend(this._render_errButton())},_render_body_ok:function(g){g.append(this._render_hdaSummary());if(this.model.isDeletedOrPurged()){g.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton,this._render_rerunButton]));return}g.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton,this._render_rerunButton,this._render_visualizationsButton]));g.append(this._render_secondaryActionButtons([this._render_tagButton,this._render_annotateButton]));g.append('<div class="clear"/>');g.append(this._render_tagArea());g.append(this._render_annotationArea());g.append(this._render_displayAppArea());this._render_displayApps(g);g.append(this._render_peek())},events:{"click .historyItemTitle":"toggleBodyVisibility","click .historyItemUndelete":function(g){this.model.undelete();return false},"click .historyItemUnhide":function(g){this.model.unhide();return false},"click .historyItemPurge":"confirmPurge","click a.icon-button.tags":"loadAndDisplayTags","click a.icon-button.annotate":"loadAndDisplayAnnotation"},confirmPurge:function c(g){this.model.purge({url:this.urls.purge});return false},_render_tagArea:function(){if(!this.hasUser||!this.urls.tags.set){return null}return $(f.templates.tagArea(_.extend(this.model.toJSON(),{urls:this.urls})).trim())},loadAndDisplayTags:function(i){this.log(this+".loadAndDisplayTags",i);var g=this,j=this.$el.find(".tag-area"),h=j.find(".tag-elt");if(j.is(":hidden")){if(!jQuery.trim(h.html())){$.ajax({url:this.urls.tags.get,error:function(m,k,l){g.log("Tagging failed",m,k,l);g.trigger("error",g,m,{},_l("Tagging failed"))},success:function(k){h.html(k);h.find("[title]").tooltip();j.slideDown(g.fxSpeed)}})}else{j.slideDown(g.fxSpeed)}}else{j.slideUp(g.fxSpeed)}return false},_render_annotationArea:function(){if(!this.hasUser||!this.urls.annotation.get){return null}return $(f.templates.annotationArea(_.extend(this.model.toJSON(),{urls:this.urls})).trim())},loadAndDisplayAnnotation:function(i){this.log(this+".loadAndDisplayAnnotation",i);var g=this,k=this.$el.find(".annotation-area"),j=k.find(".annotation-elt"),h=this.urls.annotation.set;if(k.is(":hidden")){if(!jQuery.trim(j.html())){$.ajax({url:this.urls.annotation.get,error:function(){g.log("Annotation failed",xhr,status,error);g.trigger("error",g,xhr,{},_l("Annotation failed"))},success:function(l){if(l===""){l="<em>"+_l("Describe or add notes to dataset")+"</em>"}j.html(l);k.find("[title]").tooltip();async_save_text(j.attr("id"),j.attr("id"),h,"new_annotation",18,true,4);k.slideDown(g.fxSpeed)}})}else{k.slideDown(g.fxSpeed)}}else{k.slideUp(g.fxSpeed)}return false},toString:function(){var g=(this.model)?(this.model+""):("(no model)");return"HDAView("+g+")"}});f.templates={tagArea:Handlebars.templates["template-hda-tagArea"],annotationArea:Handlebars.templates["template-hda-annotationArea"]};function e(g,h){action=function(){Galaxy.frame_manager.frame_new({title:"Scatterplot",type:"url",content:g+"/scatterplot?"+$.param(h),location:"center"});$("div.popmenu-wrapper").remove();return false};return action}function b(g,i,h){return function(){var j={};if(h){j["f-dbkey"]=h}$.ajax({url:g+"/list_tracks?"+$.param(j),dataType:"html",error:function(){alert(("Could not add this dataset to browser")+".")},success:function(k){var l=window.parent;l.Galaxy.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){l.Galaxy.modal.hide()},"View in saved visualization":function(){l.Galaxy.modal.show({title:"Add Data to Saved Visualization",body:k,buttons:{Cancel:function(){l.Galaxy.modal.hide()},"Add to visualization":function(){$(l.document).find("input[name=id]:checked").each(function(){l.Galaxy.modal.hide();var m=$(this).val();i.id=m;l.Galaxy.frame_manager.frame_new({title:"Trackster",type:"url",content:g+"/trackster?"+$.param(i)})})}}})},"View in new visualization":function(){l.Galaxy.modal.hide();var m=g+"/trackster?"+$.param(i);l.Galaxy.frame_manager.frame_new({title:"Trackster",type:"url",content:m})}}})}});return false}}return{HDAEditView:f}});
\ No newline at end of file
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/packed/mvc/dataset/hda-model.js
--- a/static/scripts/packed/mvc/dataset/hda-model.js
+++ b/static/scripts/packed/mvc/dataset/hda-model.js
@@ -1,1 +1,1 @@
-define([],function(){var d=Backbone.Model.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"new",deleted:false,visible:true,accessible:true,purged:false,data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:""},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("history_id")+"/contents/"+this.get("id")},urls:function(){var j=this.get("id");if(!j){return{}}var h={"delete":"/datasets/"+j+"/delete_async",purge:"/datasets/"+j+"/purge_async",unhide:"/datasets/"+j+"/unhide",undelete:"/datasets/"+j+"/undelete",display:"/datasets/"+j+"/display/?preview=True",download:"/datasets/"+j+"/display?to_ext="+this.get("file_ext"),edit:"/datasets/"+j+"/edit",report_error:"/dataset/errors?id="+j,rerun:"/tool_runner/rerun?id="+j,show_params:"/datasets/"+j+"/show_params",visualization:"/visualization",annotation:{get:"/dataset/get_annotation_async?id="+j,set:"/dataset/annotate_async?id="+j},tags:{get:"/tag/get_tagging_elt_async?item_id="+j+"&item_class=HistoryDatasetAssociation",set:"/tag/retag?item_id="+j+"&item_class=HistoryDatasetAssociation"}};var i=this.get("meta_files");if(i){h.meta_download=_.map(i,function(k){return{url:"/dataset/get_metadata_file?hda_id="+j+"&metadata_name="+k.file_type,file_type:k.file_type}})}return h},initialize:function(h){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",d.STATES.NOT_VIEWABLE)}this._setUpListeners()},_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"))}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(i,j){var h=true;if((!i)&&(this.get("deleted")||this.get("purged"))){h=false}if((!j)&&(!this.get("visible"))){h=false}return h},hidden:function(){return !this.get("visible")},inReadyState:function(){var h=_.contains(d.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 c(h){return this.save({deleted:true},h)},undelete:function a(h){return this.save({deleted:false},h)},hide:function b(h){return this.save({visible:false},h)},unhide:function g(h){return this.save({visible:true},h)},purge:function f(h){var i=this,j=jQuery.ajax(h);j.done(function(m,k,l){i.set("purged",true)});j.fail(function(o,k,n){var l=_l("Unable to purge this 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,_l(l),{error:l})})},searchKeys:["name","file_ext","genome_build","misc_blurb","misc_info","annotation","tags"],search:function(h){var i=this;h=h.toLowerCase();return _.filter(this.searchKeys,function(k){var j=i.get(k);return(_.isString(j)&&j.toLowerCase().indexOf(h)!==-1)})},matches:function(h){return !!this.search(h).length},toString:function(){var h=this.get("id")||"";if(this.get("name")){h=this.get("hid")+' :"'+this.get("name")+'",'+h}return"HDA("+h+")"}});d.STATES={UPLOAD:"upload",QUEUED:"queued",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",PAUSED:"paused",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};d.READY_STATES=[d.STATES.NEW,d.STATES.OK,d.STATES.EMPTY,d.STATES.PAUSED,d.STATES.FAILED_METADATA,d.STATES.NOT_VIEWABLE,d.STATES.DISCARDED,d.STATES.ERROR];d.NOT_READY_STATES=[d.STATES.UPLOAD,d.STATES.QUEUED,d.STATES.RUNNING,d.STATES.SETTING_METADATA];var e=Backbone.Collection.extend(LoggableMixin).extend({model:d,urlRoot:"/api/histories",url:function(){return this.urlRoot+"/"+this.historyId+"/contents"},initialize:function(i,h){h=h||{};this.historyId=h.historyId;this._setUpListeners()},_setUpListeners:function(){},ids:function(){return this.map(function(h){return h.id})},notReady:function(){return this.filter(function(h){return !h.inReadyState()})},running:function(){var h=[];this.each(function(i){if(!i.inReadyState()){h.push(i.get("id"))}});return h},getByHid:function(h){return _.first(this.filter(function(i){return i.get("hid")===h}))},getVisible:function(h,i){return this.filter(function(j){return j.isVisible(h,i)})},fetchAllDetails:function(){return this.fetch({data:{details:"all"}})},matches:function(h){return this.filter(function(i){return i.matches(h)})},set:function(j,h){var i=this;j=_.map(j,function(l){var m=i.get(l.id);if(!m){return l}var k=m.toJSON();_.extend(k,l);return k});Backbone.Collection.prototype.set.call(this,j,h)},toString:function(){return("HDACollection()")}});return{HistoryDatasetAssociation:d,HDACollection:e}});
\ No newline at end of file
+define([],function(){var d=Backbone.Model.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"new",deleted:false,visible:true,accessible:true,purged:false,data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:""},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("history_id")+"/contents/"+this.get("id")},urls:function(){var j=this.get("id");if(!j){return{}}var h={purge:galaxy_config.root+"datasets/"+j+"/purge_async",display:galaxy_config.root+"datasets/"+j+"/display/?preview=True",download:galaxy_config.root+"datasets/"+j+"/display?to_ext="+this.get("file_ext"),edit:galaxy_config.root+"datasets/"+j+"/edit",report_error:galaxy_config.root+"dataset/errors?id="+j,rerun:galaxy_config.root+"tool_runner/rerun?id="+j,show_params:galaxy_config.root+"datasets/"+j+"/show_params",visualization:galaxy_config.root+"visualization",annotation:{get:galaxy_config.root+"dataset/get_annotation_async?id="+j,set:galaxy_config.root+"dataset/annotate_async?id="+j},tags:{get:galaxy_config.root+"tag/get_tagging_elt_async?item_id="+j+"&item_class=HistoryDatasetAssociation",set:galaxy_config.root+"tag/retag?item_id="+j+"&item_class=HistoryDatasetAssociation"}};var i=this.get("meta_files");if(i){h.meta_download=_.map(i,function(k){return{url:galaxy_config.root+"dataset/get_metadata_file?hda_id="+j+"&metadata_name="+k.file_type,file_type:k.file_type}})}return h},initialize:function(h){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",d.STATES.NOT_VIEWABLE)}this._setUpListeners()},_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"))}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(i,j){var h=true;if((!i)&&(this.get("deleted")||this.get("purged"))){h=false}if((!j)&&(!this.get("visible"))){h=false}return h},hidden:function(){return !this.get("visible")},inReadyState:function(){var h=_.contains(d.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 c(h){return this.save({deleted:true},h)},undelete:function a(h){return this.save({deleted:false},h)},hide:function b(h){return this.save({visible:false},h)},unhide:function g(h){return this.save({visible:true},h)},purge:function f(h){var i=this,j=jQuery.ajax(h);j.done(function(m,k,l){i.set("purged",true)});j.fail(function(o,k,n){var l=_l("Unable to purge this 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,_l(l),{error:l})})},searchKeys:["name","file_ext","genome_build","misc_blurb","misc_info","annotation","tags"],search:function(h){var i=this;h=h.toLowerCase();return _.filter(this.searchKeys,function(k){var j=i.get(k);return(_.isString(j)&&j.toLowerCase().indexOf(h)!==-1)})},matches:function(h){return !!this.search(h).length},toString:function(){var h=this.get("id")||"";if(this.get("name")){h=this.get("hid")+' :"'+this.get("name")+'",'+h}return"HDA("+h+")"}});d.STATES={UPLOAD:"upload",QUEUED:"queued",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",PAUSED:"paused",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};d.READY_STATES=[d.STATES.NEW,d.STATES.OK,d.STATES.EMPTY,d.STATES.PAUSED,d.STATES.FAILED_METADATA,d.STATES.NOT_VIEWABLE,d.STATES.DISCARDED,d.STATES.ERROR];d.NOT_READY_STATES=[d.STATES.UPLOAD,d.STATES.QUEUED,d.STATES.RUNNING,d.STATES.SETTING_METADATA];var e=Backbone.Collection.extend(LoggableMixin).extend({model:d,urlRoot:galaxy_config.root+"api/histories",url:function(){return this.urlRoot+"/"+this.historyId+"/contents"},initialize:function(i,h){h=h||{};this.historyId=h.historyId;this._setUpListeners()},_setUpListeners:function(){},ids:function(){return this.map(function(h){return h.id})},notReady:function(){return this.filter(function(h){return !h.inReadyState()})},running:function(){var h=[];this.each(function(i){if(!i.inReadyState()){h.push(i.get("id"))}});return h},getByHid:function(h){return _.first(this.filter(function(i){return i.get("hid")===h}))},getVisible:function(h,i){return this.filter(function(j){return j.isVisible(h,i)})},fetchAllDetails:function(){return this.fetch({data:{details:"all"}})},matches:function(h){return this.filter(function(i){return i.matches(h)})},set:function(j,h){var i=this;j=_.map(j,function(l){var m=i.get(l.id);if(!m){return l}var k=m.toJSON();_.extend(k,l);return k});Backbone.Collection.prototype.set.call(this,j,h)},toString:function(){return("HDACollection()")}});return{HistoryDatasetAssociation:d,HDACollection:e}});
\ No newline at end of file
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/packed/mvc/history/history-model.js
--- a/static/scripts/packed/mvc/history/history-model.js
+++ b/static/scripts/packed/mvc/history/history-model.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/hda-model"],function(a){var c=Backbone.Model.extend(LoggableMixin).extend({defaults:{model_class:"History",id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:"api/histories",renameUrl:function(){var e=this.get("id");if(!e){return undefined}return"/history/rename_async?id="+this.get("id")},annotateUrl:function(){var e=this.get("id");if(!e){return undefined}return"/history/annotate_async?id="+this.get("id")},tagUrl:function(){var e=this.get("id");if(!e){return undefined}return"/tag/get_tagging_elt_async?item_id="+this.get("id")+"&item_class=History"},initialize:function(f,g,e){e=e||{};this.logger=e.logger||null;this.log(this+".initialize:",f,g,e);this.hdas=new a.HDACollection(g||[],{historyId:this.get("id")});if(g&&_.isArray(g)){this.hdas.reset(g)}this._setUpListeners();this.checkForUpdates()},_setUpListeners:function(){this.on("error",function(f,i,e,h,g){this.errorHandler(f,i,e,h,g)});if(this.hdas){this.listenTo(this.hdas,"error",function(){this.trigger.apply(this,["error:hdas"].concat(jQuery.makeArray(arguments)))})}this.on("change:id",function(f,e){if(this.hdas){this.hdas.historyId=e}},this)},errorHandler:function(f,i,e,h,g){this.clearUpdateTimeout()},hasUser:function(){var e=this.get("user");return !!(e&&e.id)},checkForUpdates:function(e){if(this.hdas.running().length){this.setUpdateTimeout()}else{this.trigger("ready");if(_.isFunction(e)){e.call(this)}}return this},setUpdateTimeout:function(e){e=e||c.UPDATE_DELAY;var f=this;this.clearUpdateTimeout();this.updateTimeoutId=setTimeout(function(){f.refresh()},e);return this.updateTimeoutId},clearUpdateTimeout:function(){if(this.updateTimeoutId){clearTimeout(this.updateTimeoutId);this.updateTimeoutId=null}},refresh:function(f,e){f=f||[];e=e||{};var g=this;e.data=e.data||{};if(f.length){e.data.details=f.join(",")}var h=this.hdas.fetch(e);h.done(function(i){g.checkForUpdates(function(){this.fetch()})});return h},toString:function(){return"History("+this.get("id")+","+this.get("name")+")"}});c.UPDATE_DELAY=4000;c.getHistoryData=function d(f,p){p=p||{};var j=p.hdaDetailIds||[];var l=jQuery.Deferred(),k=null;function g(q){return jQuery.ajax("/api/histories/"+f)}function e(q){if(!q||!q.state_ids){return 0}return _.reduce(q.state_ids,function(r,t,s){return r+t.length},0)}function o(r){if(!e(r)){return[]}if(_.isFunction(j)){j=j(r)}var q=(j.length)?({details:j.join(",")}):({});return jQuery.ajax("/api/histories/"+r.id+"/contents",{data:q})}var n=p.historyFn||g,m=p.hdaFn||o;var i=n(f);i.done(function(q){k=q;l.notify({status:"history data retrieved",historyJSON:k})});i.fail(function(s,q,r){l.reject(s,"loading the history")});var h=i.then(m);h.then(function(q){l.notify({status:"dataset data retrieved",historyJSON:k,hdaJSON:q});l.resolve(k,q)});h.fail(function(s,q,r){l.reject(s,"loading the datasets",{history:k})});return l};var b=Backbone.Collection.extend(LoggableMixin).extend({model:c,urlRoot:"api/histories"});return{History:c,HistoryCollection:b}});
\ No newline at end of file
+define(["mvc/dataset/hda-model"],function(a){var c=Backbone.Model.extend(LoggableMixin).extend({defaults:{model_class:"History",id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:galaxy_config.root+"api/histories",renameUrl:function(){var e=this.get("id");if(!e){return undefined}return galaxy_config.root+"history/rename_async?id="+this.get("id")},annotateUrl:function(){var e=this.get("id");if(!e){return undefined}return galaxy_config.root+"history/annotate_async?id="+this.get("id")},tagUrl:function(){var e=this.get("id");if(!e){return undefined}return galaxy_config.root+"tag/get_tagging_elt_async?item_id="+this.get("id")+"&item_class=History"},initialize:function(f,g,e){e=e||{};this.logger=e.logger||null;this.log(this+".initialize:",f,g,e);this.hdas=new a.HDACollection(g||[],{historyId:this.get("id")});if(g&&_.isArray(g)){this.hdas.reset(g)}this._setUpListeners();this.updateTimeoutId=null;this.checkForUpdates()},_setUpListeners:function(){this.on("error",function(f,i,e,h,g){this.errorHandler(f,i,e,h,g)});if(this.hdas){this.listenTo(this.hdas,"error",function(){this.trigger.apply(this,["error:hdas"].concat(jQuery.makeArray(arguments)))})}this.on("change:id",function(f,e){if(this.hdas){this.hdas.historyId=e}},this)},errorHandler:function(f,i,e,h,g){this.clearUpdateTimeout()},hasUser:function(){var e=this.get("user");return !!(e&&e.id)},checkForUpdates:function(e){if(this.hdas.running().length){this.setUpdateTimeout()}else{this.trigger("ready");if(_.isFunction(e)){e.call(this)}}return this},setUpdateTimeout:function(e){e=e||c.UPDATE_DELAY;var f=this;this.clearUpdateTimeout();this.updateTimeoutId=setTimeout(function(){f.refresh()},e);return this.updateTimeoutId},clearUpdateTimeout:function(){if(this.updateTimeoutId){clearTimeout(this.updateTimeoutId);this.updateTimeoutId=null}},refresh:function(f,e){f=f||[];e=e||{};var g=this;e.data=e.data||{};if(f.length){e.data.details=f.join(",")}var h=this.hdas.fetch(e);h.done(function(i){g.checkForUpdates(function(){this.fetch()})});return h},toString:function(){return"History("+this.get("id")+","+this.get("name")+")"}});c.UPDATE_DELAY=4000;c.getHistoryData=function d(f,p){p=p||{};var j=p.hdaDetailIds||[];var l=jQuery.Deferred(),k=null;function g(q){return jQuery.ajax(galaxy_config.root+"api/histories/"+f)}function e(q){if(!q||!q.state_ids){return 0}return _.reduce(q.state_ids,function(r,t,s){return r+t.length},0)}function o(r){if(!e(r)){return[]}if(_.isFunction(j)){j=j(r)}var q=(j.length)?({details:j.join(",")}):({});return jQuery.ajax(galaxy_config.root+"api/histories/"+r.id+"/contents",{data:q})}var n=p.historyFn||g,m=p.hdaFn||o;var i=n(f);i.done(function(q){k=q;l.notify({status:"history data retrieved",historyJSON:k})});i.fail(function(s,q,r){l.reject(s,"loading the history")});var h=i.then(m);h.then(function(q){l.notify({status:"dataset data retrieved",historyJSON:k,hdaJSON:q});l.resolve(k,q)});h.fail(function(s,q,r){l.reject(s,"loading the datasets",{history:k})});return l};var b=Backbone.Collection.extend(LoggableMixin).extend({model:c,urlRoot:galaxy_config.root+"api/histories"});return{History:c,HistoryCollection:b}});
\ No newline at end of file
diff -r 7f70f02747d374ebf1804a1ae380cb27968043b0 -r e66076ed4678c1ad15db09c1d220a624e2047a79 static/scripts/packed/mvc/history/history-panel.js
--- a/static/scripts/packed/mvc/history/history-panel.js
+++ b/static/scripts/packed/mvc/history/history-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-model","mvc/dataset/hda-base","mvc/dataset/hda-edit"],function(d,b,a){var c=Backbone.View.extend(LoggableMixin).extend({HDAView:a.HDAEditView,tagName:"div",className:"history-panel",fxSpeed:300,events:{"click #history-tag":"loadAndDisplayTags","click #message-container":"clearMessages"},initialize:function(e){e=e||{};if(e.logger){this.logger=e.logger}this.log(this+".initialize:",e);this._setUpListeners();this.hdaViews={};this.urls={};this.indicator=new LoadingIndicator(this.$el);if(this.model){this._setUpWebStorage(e.initiallyExpanded,e.show_deleted,e.show_hidden);this._setUpModelEventHandlers()}if(e.onready){e.onready.call(this)}},_setUpListeners:function(){this.on("error",function(f,i,e,h,g){this.errorHandler(f,i,e,h,g)});this.on("loading-history",function(){this.showLoadingIndicator()});this.on("loading-done",function(){this.hideLoadingIndicator()});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});this.on("switched-history current-history new-history",function(){if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});if(this.logger){this.on("all",function(e){this.log(this+"",arguments)},this)}},errorHandler:function(g,j,f,i,h){var e=this._parseErrorMessage(g,j,f,i,h);if(j&&j.status===0&&j.readyState===0){}else{if(j&&j.status===502){}else{if(!this.$el.find("#message-container").is(":visible")){this.once("rendered",function(){this.displayMessage("error",e.message,e.details)})}else{this.displayMessage("error",e.message,e.details)}}}},_parseErrorMessage:function(h,l,g,k,j){var f=Galaxy.currUser,e={message:this._bePolite(k),details:{user:(f instanceof User)?(f.toJSON()):(f+""),source:(h instanceof Backbone.Model)?(h.toJSON()):(h+""),xhr:l,options:(l)?(_.omit(g,"xhr")):(g)}};_.extend(e.details,j||{});if(l&&_.isFunction(l.getAllResponseHeaders)){var i=l.getAllResponseHeaders();i=_.compact(i.split("\n"));i=_.map(i,function(m){return m.split(": ")});e.details.xhr.responseHeaders=_.object(i)}return e},_bePolite:function(e){e=e||_l("An error occurred while getting updates from the server");return e+". "+_l("Please contact a Galaxy administrator if the problem persists.")},_loadHistoryFromXHR:function(g,f){var e=this;g.then(function(h,i){e.setModel(h,i,f)});g.fail(function(i,h){e.render()});return g},setModel:function(g,e,f){f=f||{};if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.hdas)}this.hdaViews={};if(Galaxy&&Galaxy.currUser){g.user=Galaxy.currUser.toJSON()}this.model=new d.History(g,e,f);this._setUpWebStorage(f.initiallyExpanded,f.show_deleted,f.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this);this.render();return this},loadHistory:function(h,g,f,k,i){this.trigger("loading-history",this);g=g||{};var e=this;var j=d.History.getHistoryData(h,{historyFn:f,hdaFn:k,hdaDetailIds:g.initiallyExpanded||i});return this._loadHistoryFromXHR(j,g).fail(function(n,l,m){e.trigger("error",e,n,g,_l("An error was encountered while "+l),{historyId:h,history:m||{}})}).always(function(){e.trigger("loading-done",e)})},loadHistoryWithHDADetails:function(h,g,f,j){var e=this,i=function(k){return e.getExpandedHdaIds(k.id)};return this.loadHistory(h,g,f,j,i)},switchToHistory:function(h,g){var e=this,f=function(){return jQuery.post("/api/histories/"+h+"/set_as_current")};return this.loadHistoryWithHDADetails(h,g,f).then(function(j,i){e.trigger("switched-history",e)})},loadCurrentHistory:function(f){var e=this;return this.loadHistoryWithHDADetails("current",f).then(function(h,g){e.trigger("current-history",e)})},createNewHistory:function(g){var e=this,f=function(){return jQuery.post("/api/histories",{current:true})};return this.loadHistory(undefined,g,f).then(function(i,h){e.trigger("new-history",e)})},refreshHdas:function(f,e){if(this.model){return this.model.refresh(f,e)}return $.when()},_getStorageKey:function(e){if(!e){throw new Error("_getStorageKey needs valid id: "+e)}return("history:"+e)},_setUpWebStorage:function(f,e,g){this.storage=new PersistentStorage(this._getStorageKey(this.model.get("id")),{expandedHdas:{},show_deleted:false,show_hidden:false});this.log(this+" (prev) storage:",JSON.stringify(this.storage.get(),null,2));if(f){this.storage.set("exandedHdas",f)}if((e===true)||(e===false)){this.storage.set("show_deleted",e)}if((g===true)||(g===false)){this.storage.set("show_hidden",g)}this.show_deleted=this.storage.get("show_deleted");this.show_hidden=this.storage.get("show_hidden");this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get())},clearWebStorage:function(){for(var e in sessionStorage){if(e.indexOf("HistoryView.")===0){sessionStorage.removeItem(e)}}},getStoredOptions:function(f){if(!f||f==="current"){return(this.storage)?(this.storage.get()):({})}var e=sessionStorage.getItem(this._getStorageKey(f));return(e===null)?({}):(JSON.parse(e))},getExpandedHdaIds:function(e){var f=this.getStoredOptions(e).expandedHdas;return((_.isEmpty(f))?([]):(_.keys(f)))},_setUpModelEventHandlers:function(){this.model.on("error error:hdas",function(f,h,e,g){this.errorHandler(f,h,e,g)},this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);if(Galaxy&&Galaxy.quotaMeter){this.listenTo(this.model,"change:nice_size",function(){Galaxy.quotaMeter.update()})}this.model.hdas.on("add",this.addHdaView,this);this.model.hdas.on("change:deleted",this.handleHdaDeletionChange,this);this.model.hdas.on("change:visible",this.handleHdaVisibleChange,this);this.model.hdas.on("change:purged",function(e){this.model.fetch()},this);this.model.hdas.on("state:ready",function(f,g,e){if((!f.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(f.get("id"))}},this)},addHdaView:function(h){this.log("add."+this,h);var f=this;if(!h.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return}$({}).queue([function g(j){var i=f.$el.find("#emptyHistoryMessage");if(i.is(":visible")){i.fadeOut(f.fxSpeed,j)}else{j()}},function e(j){f.scrollToTop();var i=f.$el.find("#"+f.model.get("id")+"-datasets");f.createHdaView(h).$el.hide().prependTo(i).slideDown(f.fxSpeed)}])},createHdaView:function(g){var f=g.get("id"),e=this.storage.get("expandedHdas").get(f),h=new this.HDAView({model:g,expanded:e,hasUser:this.model.hasUser(),logger:this.logger});this._setUpHdaListeners(h);this.hdaViews[f]=h;return h.render()},handleHdaDeletionChange:function(e){if(e.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(e.get("id"))}},handleHdaVisibleChange:function(e){if(e.hidden()&&!this.storage.get("show_hidden")){this.removeHdaView(e.get("id"))}},removeHdaView:function(g){var e=this,f=this.hdaViews[g];if(!f){return}f.$el.fadeOut(e.fxSpeed,function(){f.remove();delete e.hdaViews[g];if(_.isEmpty(e.hdaViews)){e.$el.find("#emptyHistoryMessage").fadeIn(e.fxSpeed)}})},render:function(g){var e=this,f;if(this.model){f=this.renderModel()}else{f=this.renderWithoutModel()}$(e).queue("fx",[function(h){if(e.$el.is(":visible")){e.$el.fadeOut(e.fxSpeed,h)}else{h()}},function(h){e.$el.empty();if(f){e.$el.append(f.children())}e.$el.fadeIn(e.fxSpeed,h)},function(h){e._setUpBehaviours();if(g){g.call(this)}}]);return this},renderModel:function(){var e=$("<div/>");e.append(c.templates.historyPanel(this.model.toJSON()));e.find("[title]").tooltip({placement:"bottom"});if(!this.model.hdas.length||!this.renderItems(e.find("#"+this.model.get("id")+"-datasets"))){e.find("#emptyHistoryMessage").show()}return e},renderWithoutModel:function(){var e=$("<div/>"),f=$("<div/>").attr("id","message-container").css({"margin-left":"4px","margin-right":"4px"});return e.append(f)},renderItems:function(f){this.hdaViews={};var e=this,g=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"));_.each(g,function(j){var i=j.get("id"),h=e.storage.get("expandedHdas").get(i);e.hdaViews[i]=new e.HDAView({model:j,expanded:h,hasUser:e.model.hasUser(),logger:e.logger});e._setUpHdaListeners(e.hdaViews[i]);f.prepend(e.hdaViews[i].render().$el)});return g.length},_setUpHdaListeners:function(f){var e=this;f.on("body-expanded",function(g){e.storage.get("expandedHdas").set(g,true)});f.on("body-collapsed",function(g){e.storage.get("expandedHdas").deleteKey(g)});f.on("error",function(h,j,g,i){e.errorHandler(h,j,g,i)})},_setUpBehaviours:function(){if(!this.model||!(this.model.get("user")&&this.model.get("user").email)){return}var e=this,f=this.$("#history-annotation-area");this.$("#history-annotate").click(function(){if(f.is(":hidden")){f.slideDown(e.fxSpeed)}else{f.slideUp(e.fxSpeed)}return false});async_save_text("history-name-container","history-name",this.model.renameUrl(),"new_name",18);async_save_text("history-annotation-container","history-annotation",this.model.annotateUrl(),"new_annotation",18,true,4)},updateHistoryDiskSize:function(){this.$el.find("#history-size").text(this.model.get("nice_size"))},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(e){e.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},toggleShowDeleted:function(){this.storage.set("show_deleted",!this.storage.get("show_deleted"));this.render();return this.storage.get("show_deleted")},toggleShowHidden:function(){this.storage.set("show_hidden",!this.storage.get("show_hidden"));this.render();return this.storage.get("show_hidden")},loadAndDisplayTags:function(g){this.log(this+".loadAndDisplayTags",g);var e=this,h=this.$el.find("#history-tag-area"),f=h.find(".tag-elt");this.log("\t tagArea",h," tagElt",f);if(h.is(":hidden")){if(!jQuery.trim(f.html())){$.ajax({url:e.model.tagUrl(),error:function(k,j,i){e.log("Error loading tag area html",k,j,i);e.trigger("error",e,k,null,_l("Error loading tags"))},success:function(i){f.html(i);f.find("[title]").tooltip();h.slideDown(e.fxSpeed)}})}else{h.slideDown(e.fxSpeed)}}else{h.slideUp(e.fxSpeed)}return false},showLoadingIndicator:function(f,e,g){e=(e!==undefined)?(e):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,g)}else{this.$el.fadeOut(e);this.indicator.show(e,g)}},hideLoadingIndicator:function(e,f){e=(e!==undefined)?(e):(this.fxSpeed);if(this.indicator){this.indicator.hide(e,f)}},displayMessage:function(j,k,i){var g=this;this.scrollToTop();var h=this.$el.find("#message-container"),e=$("<div/>").addClass(j+"message").html(k);if(!_.isEmpty(i)){var f=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(g.messageToModalOptions(j,k,i));return false});e.append(" ",f)}return h.html(e)},messageToModalOptions:function(i,k,h){var e=this,j=$("<div/>"),g={title:"Details"};function f(l){l=_.omit(l,_.functions(l));return["<table>",_.map(l,function(n,m){n=(_.isObject(n))?(f(n)):(n);return'<tr><td style="vertical-align: top; color: grey">'+m+'</td><td style="padding-left: 8px">'+n+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(h)){g.body=j.append(f(h))}else{g.body=j.html(h)}g.buttons={Ok:function(){Galaxy.modal.hide();e.clearMessages()}};return g},clearMessages:function(){var e=this.$el.find("#message-container");e.empty()},scrollPosition:function(){return this.$el.parent().scrollTop()},scrollTo:function(e){this.$el.parent().scrollTop(e)},scrollToTop:function(){this.$el.parent().scrollTop(0);return this},scrollIntoView:function(f,g){if(!g){this.$el.parent().parent().scrollTop(f);return this}var e=window,h=this.$el.parent().parent(),j=$(e).innerHeight(),i=(j/2)-(g/2);$(h).scrollTop(f-i);return this},scrollToId:function(f){if((!f)||(!this.hdaViews[f])){return this}var e=this.hdaViews[f].$el;this.scrollIntoView(e.offset().top,e.outerHeight());return this},scrollToHid:function(e){var f=this.model.hdas.getByHid(e);if(!f){return this}return this.scrollToId(f.id)},connectToQuotaMeter:function(e){if(!e){return this}this.listenTo(e,"quota:over",this.showQuotaMessage);this.listenTo(e,"quota:under",this.hideQuotaMessage);this.on("rendered rendered:initial",function(){if(e&&e.isOverQuota()){this.showQuotaMessage()}});return this},showQuotaMessage:function(){var e=this.$el.find("#quota-message-container");if(e.is(":hidden")){e.slideDown(this.fxSpeed)}},hideQuotaMessage:function(){var e=this.$el.find("#quota-message-container");if(!e.is(":hidden")){e.slideUp(this.fxSpeed)}},connectToOptionsMenu:function(e){if(!e){return this}this.on("new-storage",function(g,f){if(e&&g){e.findItemByHtml(_l("Include Deleted Datasets")).checked=g.get("show_deleted");e.findItemByHtml(_l("Include Hidden Datasets")).checked=g.get("show_hidden")}});return this},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});c.templates={historyPanel:Handlebars.templates["template-history-historyPanel"]};return{HistoryPanel:c}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/dataset/hda-base","mvc/dataset/hda-edit"],function(d,b,a){var c=Backbone.View.extend(LoggableMixin).extend({HDAView:a.HDAEditView,tagName:"div",className:"history-panel",fxSpeed:300,events:{"click #history-tag":"loadAndDisplayTags","click #message-container":"clearMessages"},initialize:function(e){e=e||{};if(e.logger){this.logger=e.logger}this.log(this+".initialize:",e);this._setUpListeners();this.hdaViews={};this.urls={};this.indicator=new LoadingIndicator(this.$el);if(this.model){this._setUpWebStorage(e.initiallyExpanded,e.show_deleted,e.show_hidden);this._setUpModelEventHandlers()}if(e.onready){e.onready.call(this)}},_setUpListeners:function(){this.on("error",function(f,i,e,h,g){this.errorHandler(f,i,e,h,g)});this.on("loading-history",function(){this.showLoadingIndicator()});this.on("loading-done",function(){this.hideLoadingIndicator()});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});this.on("switched-history current-history new-history",function(){if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});if(this.logger){this.on("all",function(e){this.log(this+"",arguments)},this)}},errorHandler:function(g,j,f,i,h){var e=this._parseErrorMessage(g,j,f,i,h);if(j&&j.status===0&&j.readyState===0){}else{if(j&&j.status===502){}else{if(!this.$el.find("#message-container").is(":visible")){this.once("rendered",function(){this.displayMessage("error",e.message,e.details)})}else{this.displayMessage("error",e.message,e.details)}}}},_parseErrorMessage:function(h,l,g,k,j){var f=Galaxy.currUser,e={message:this._bePolite(k),details:{user:(f instanceof User)?(f.toJSON()):(f+""),source:(h instanceof Backbone.Model)?(h.toJSON()):(h+""),xhr:l,options:(l)?(_.omit(g,"xhr")):(g)}};_.extend(e.details,j||{});if(l&&_.isFunction(l.getAllResponseHeaders)){var i=l.getAllResponseHeaders();i=_.compact(i.split("\n"));i=_.map(i,function(m){return m.split(": ")});e.details.xhr.responseHeaders=_.object(i)}return e},_bePolite:function(e){e=e||_l("An error occurred while getting updates from the server");return e+". "+_l("Please contact a Galaxy administrator if the problem persists.")},loadCurrentHistory:function(f){var e=this;return this.loadHistoryWithHDADetails("current",f).then(function(h,g){e.trigger("current-history",e)})},switchToHistory:function(h,g){var e=this,f=function(){return jQuery.post(galaxy_config.root+"api/histories/"+h+"/set_as_current")};return this.loadHistoryWithHDADetails(h,g,f).then(function(j,i){e.trigger("switched-history",e)})},createNewHistory:function(g){var e=this,f=function(){return jQuery.post(galaxy_config.root+"api/histories",{current:true})};return this.loadHistory(undefined,g,f).then(function(i,h){e.trigger("new-history",e)})},loadHistoryWithHDADetails:function(h,g,f,j){var e=this,i=function(k){return e.getExpandedHdaIds(k.id)};return this.loadHistory(h,g,f,j,i)},loadHistory:function(h,g,f,k,i){this.trigger("loading-history",this);g=g||{};var e=this;var j=d.History.getHistoryData(h,{historyFn:f,hdaFn:k,hdaDetailIds:g.initiallyExpanded||i});return this._loadHistoryFromXHR(j,g).fail(function(n,l,m){e.trigger("error",e,n,g,_l("An error was encountered while "+l),{historyId:h,history:m||{}})}).always(function(){e.trigger("loading-done",e)})},_loadHistoryFromXHR:function(g,f){var e=this;g.then(function(h,i){e.setModel(h,i,f)});g.fail(function(i,h){e.render()});return g},setModel:function(g,e,f){f=f||{};if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.hdas)}this.hdaViews={};if(Galaxy&&Galaxy.currUser){g.user=Galaxy.currUser.toJSON()}this.model=new d.History(g,e,f);this._setUpWebStorage(f.initiallyExpanded,f.show_deleted,f.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this);this.render();return this},refreshHdas:function(f,e){if(this.model){return this.model.refresh(f,e)}return $.when()},_setUpWebStorage:function(f,e,g){this.storage=new PersistentStorage(this._getStorageKey(this.model.get("id")),{expandedHdas:{},show_deleted:false,show_hidden:false});this.log(this+" (prev) storage:",JSON.stringify(this.storage.get(),null,2));if(f){this.storage.set("exandedHdas",f)}if((e===true)||(e===false)){this.storage.set("show_deleted",e)}if((g===true)||(g===false)){this.storage.set("show_hidden",g)}this.show_deleted=this.storage.get("show_deleted");this.show_hidden=this.storage.get("show_hidden");this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get())},_getStorageKey:function(e){if(!e){throw new Error("_getStorageKey needs valid id: "+e)}return("history:"+e)},clearWebStorage:function(){for(var e in sessionStorage){if(e.indexOf("HistoryView.")===0){sessionStorage.removeItem(e)}}},getStoredOptions:function(f){if(!f||f==="current"){return(this.storage)?(this.storage.get()):({})}var e=sessionStorage.getItem(this._getStorageKey(f));return(e===null)?({}):(JSON.parse(e))},getExpandedHdaIds:function(e){var f=this.getStoredOptions(e).expandedHdas;return((_.isEmpty(f))?([]):(_.keys(f)))},_setUpModelEventHandlers:function(){this.model.on("error error:hdas",function(f,h,e,g){this.errorHandler(f,h,e,g)},this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);if(Galaxy&&Galaxy.quotaMeter){this.listenTo(this.model,"change:nice_size",function(){Galaxy.quotaMeter.update()})}this.model.hdas.on("add",this.addHdaView,this);this.model.hdas.on("change:deleted",this.handleHdaDeletionChange,this);this.model.hdas.on("change:visible",this.handleHdaVisibleChange,this);this.model.hdas.on("change:purged",function(e){this.model.fetch()},this);this.model.hdas.on("state:ready",function(f,g,e){if((!f.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(this.hdaViews[f.id])}},this)},addHdaView:function(h){this.log("add."+this,h);var f=this;if(!h.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return}$({}).queue([function g(j){var i=f.$el.find("#emptyHistoryMessage");if(i.is(":visible")){i.fadeOut(f.fxSpeed,j)}else{j()}},function e(j){f.scrollToTop();var i=f.$el.find("#"+f.model.get("id")+"-datasets");f.createHdaView(h).$el.hide().prependTo(i).slideDown(f.fxSpeed)}])},createHdaView:function(g){var f=g.get("id"),e=this.storage.get("expandedHdas").get(f),h=new this.HDAView({model:g,expanded:e,hasUser:this.model.hasUser(),logger:this.logger});this._setUpHdaListeners(h);this.hdaViews[f]=h;return h.render()},_setUpHdaListeners:function(f){var e=this;f.on("body-expanded",function(g){e.storage.get("expandedHdas").set(g,true)});f.on("body-collapsed",function(g){e.storage.get("expandedHdas").deleteKey(g)});f.on("error",function(h,j,g,i){e.errorHandler(h,j,g,i)})},handleHdaDeletionChange:function(e){if(e.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(this.hdaViews[e.id])}},handleHdaVisibleChange:function(e){if(e.hidden()&&!this.storage.get("show_hidden")){this.removeHdaView(this.hdaViews[e.id])}},removeHdaView:function(f){if(!f){return}var e=this;f.$el.fadeOut(e.fxSpeed,function(){f.off();f.remove();delete e.hdaViews[f.model.id];if(_.isEmpty(e.hdaViews)){e.$el.find("#emptyHistoryMessage").fadeIn(e.fxSpeed)}})},render:function(g){var e=this,f;if(this.model){f=this.renderModel()}else{f=this.renderWithoutModel()}$(e).queue("fx",[function(h){if(e.$el.is(":visible")){e.$el.fadeOut(e.fxSpeed,h)}else{h()}},function(h){e.$el.empty();if(f){e.$el.append(f.children())}e.$el.fadeIn(e.fxSpeed,h)},function(h){e._setUpBehaviours();if(g){g.call(this)}e.trigger("rendered",this)}]);return this},renderModel:function(){var e=$("<div/>");e.append(c.templates.historyPanel(this.model.toJSON()));e.find("[title]").tooltip({placement:"bottom"});if(!this.model.hdas.length||!this.renderItems(e.find("#"+this.model.get("id")+"-datasets"))){e.find("#emptyHistoryMessage").show()}return e},renderWithoutModel:function(){var e=$("<div/>"),f=$("<div/>").attr("id","message-container").css({"margin-left":"4px","margin-right":"4px"});return e.append(f)},renderItems:function(f){this.hdaViews={};var e=this,g=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"));_.each(g,function(h){f.prepend(e.createHdaView(h).$el)});return g.length},_setUpBehaviours:function(){if(!this.model||!(this.model.get("user")&&this.model.get("user").email)){return}var e=this,f=this.$("#history-annotation-area");this.$("#history-annotate").click(function(){if(f.is(":hidden")){f.slideDown(e.fxSpeed)}else{f.slideUp(e.fxSpeed)}return false});async_save_text("history-name-container","history-name",this.model.renameUrl(),"new_name",18);async_save_text("history-annotation-container","history-annotation",this.model.annotateUrl(),"new_annotation",18,true,4)},updateHistoryDiskSize:function(){this.$el.find("#history-size").text(this.model.get("nice_size"))},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(e){e.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},toggleShowDeleted:function(){this.storage.set("show_deleted",!this.storage.get("show_deleted"));this.render();return this.storage.get("show_deleted")},toggleShowHidden:function(){this.storage.set("show_hidden",!this.storage.get("show_hidden"));this.render();return this.storage.get("show_hidden")},loadAndDisplayTags:function(g){this.log(this+".loadAndDisplayTags",g);var e=this,h=this.$el.find("#history-tag-area"),f=h.find(".tag-elt");this.log("\t tagArea",h," tagElt",f);if(h.is(":hidden")){if(!jQuery.trim(f.html())){$.ajax({url:e.model.tagUrl(),error:function(k,j,i){e.log("Error loading tag area html",k,j,i);e.trigger("error",e,k,null,_l("Error loading tags"))},success:function(i){f.html(i);f.find("[title]").tooltip();h.slideDown(e.fxSpeed)}})}else{h.slideDown(e.fxSpeed)}}else{h.slideUp(e.fxSpeed)}return false},showLoadingIndicator:function(f,e,g){e=(e!==undefined)?(e):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,g)}else{this.$el.fadeOut(e);this.indicator.show(e,g)}},hideLoadingIndicator:function(e,f){e=(e!==undefined)?(e):(this.fxSpeed);if(this.indicator){this.indicator.hide(e,f)}},displayMessage:function(j,k,i){var g=this;this.scrollToTop();var h=this.$el.find("#message-container"),e=$("<div/>").addClass(j+"message").html(k);if(!_.isEmpty(i)){var f=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(g.messageToModalOptions(j,k,i));return false});e.append(" ",f)}return h.html(e)},messageToModalOptions:function(i,k,h){var e=this,j=$("<div/>"),g={title:"Details"};function f(l){l=_.omit(l,_.functions(l));return["<table>",_.map(l,function(n,m){n=(_.isObject(n))?(f(n)):(n);return'<tr><td style="vertical-align: top; color: grey">'+m+'</td><td style="padding-left: 8px">'+n+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(h)){g.body=j.append(f(h))}else{g.body=j.html(h)}g.buttons={Ok:function(){Galaxy.modal.hide();e.clearMessages()}};return g},clearMessages:function(){var e=this.$el.find("#message-container");e.empty()},scrollPosition:function(){return this.$el.parent().scrollTop()},scrollTo:function(e){this.$el.parent().scrollTop(e)},scrollToTop:function(){this.$el.parent().scrollTop(0);return this},scrollIntoView:function(f,g){if(!g){this.$el.parent().parent().scrollTop(f);return this}var e=window,h=this.$el.parent().parent(),j=$(e).innerHeight(),i=(j/2)-(g/2);$(h).scrollTop(f-i);return this},scrollToId:function(f){if((!f)||(!this.hdaViews[f])){return this}var e=this.hdaViews[f].$el;this.scrollIntoView(e.offset().top,e.outerHeight());return this},scrollToHid:function(e){var f=this.model.hdas.getByHid(e);if(!f){return this}return this.scrollToId(f.id)},connectToQuotaMeter:function(e){if(!e){return this}this.listenTo(e,"quota:over",this.showQuotaMessage);this.listenTo(e,"quota:under",this.hideQuotaMessage);this.on("rendered rendered:initial",function(){if(e&&e.isOverQuota()){this.showQuotaMessage()}});return this},showQuotaMessage:function(){var e=this.$el.find("#quota-message-container");if(e.is(":hidden")){e.slideDown(this.fxSpeed)}},hideQuotaMessage:function(){var e=this.$el.find("#quota-message-container");if(!e.is(":hidden")){e.slideUp(this.fxSpeed)}},connectToOptionsMenu:function(e){if(!e){return this}this.on("new-storage",function(g,f){if(e&&g){e.findItemByHtml(_l("Include Deleted Datasets")).checked=g.get("show_deleted");e.findItemByHtml(_l("Include Hidden Datasets")).checked=g.get("show_hidden")}});return this},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});c.templates={historyPanel:Handlebars.templates["template-history-historyPanel"]};return{HistoryPanel: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.
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d3cc9a975d0e/
Changeset: d3cc9a975d0e
User: jgoecks
Date: 2013-10-23 18:22:43
Summary: Use galaxy_config.root for history URLs to support URL rewriting.
Affected #: 2 files
diff -r 5d138db3d1e52e364fd3c69c321ea44bac8373eb -r d3cc9a975d0e9aa1a91fc19ef33c5d3fa53d19fd static/scripts/mvc/history/history-model.js
--- a/static/scripts/mvc/history/history-model.js
+++ b/static/scripts/mvc/history/history-model.js
@@ -207,7 +207,7 @@
function getHistory( id ){
// get the history data
//return jQuery.ajax( '/generate_json_error' );
- return jQuery.ajax( '/api/histories/' + historyId );
+ return jQuery.ajax( galaxy_config.root + 'api/histories/' + historyId );
}
function countHdasFromHistory( historyData ){
// get the number of hdas accrd. to the history
@@ -225,7 +225,7 @@
hdaDetailIds = hdaDetailIds( historyData );
}
var data = ( hdaDetailIds.length )?( { details : hdaDetailIds.join( ',' ) } ):( {} );
- return jQuery.ajax( '/api/histories/' + historyData.id + '/contents', { data: data });
+ return jQuery.ajax( galaxy_config.root + 'api/histories/' + historyData.id + '/contents', { data: data });
//return jQuery.ajax( '/generate_json_error' );
}
diff -r 5d138db3d1e52e364fd3c69c321ea44bac8373eb -r d3cc9a975d0e9aa1a91fc19ef33c5d3fa53d19fd static/scripts/mvc/history/history-panel.js
--- a/static/scripts/mvc/history/history-panel.js
+++ b/static/scripts/mvc/history/history-panel.js
@@ -291,7 +291,7 @@
var panel = this,
historyFn = function(){
// make this current and get history data with one call
- return jQuery.post( '/api/histories/' + historyId + '/set_as_current' );
+ return jQuery.post( galaxy_config.root + 'api/histories/' + historyId + '/set_as_current' );
};
return this.loadHistoryWithHDADetails( historyId, attributes, historyFn )
.then(function( historyData, hdaData ){
@@ -314,7 +314,7 @@
var panel = this,
historyFn = function(){
// get history data from posting a new history (and setting it to current)
- return jQuery.post( '/api/histories', { current: true });
+ return jQuery.post( galaxy_config.root + 'api/histories', { current: true });
};
// id undefined bc there is no historyId yet - the server will provide
// (no need for details - nothing expanded in new history)
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.