1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/cf2313ae788d/ Changeset: cf2313ae788d User: carlfeberhard Date: 2013-04-10 01:17:51 Summary: history panel: handle errors better on the client side, remove alerts, continue update attempts if error is 'Bad Gateway' Affected #: 15 files diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed lib/galaxy/webapps/galaxy/api/histories.py --- a/lib/galaxy/webapps/galaxy/api/histories.py +++ b/lib/galaxy/webapps/galaxy/api/histories.py @@ -59,6 +59,7 @@ if trans.user and len( trans.user.galaxy_sessions ) > 0: # Most recent active history for user sessions, not deleted history = trans.user.galaxy_sessions[0].histories[-1].history + history_id = trans.security.encode_id( history.id ) else: return None else: diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed lib/galaxy/webapps/galaxy/api/history_contents.py --- a/lib/galaxy/webapps/galaxy/api/history_contents.py +++ b/lib/galaxy/webapps/galaxy/api/history_contents.py @@ -43,14 +43,10 @@ else: history = self.get_history( trans, history_id, check_ownership=True, check_accessible=True ) - # build the return hda data list + # if ids, return _FULL_ data (as show) for each id passed if ids: - # if ids, return _FULL_ data (as show) for each id passed - #NOTE: this might not be the best form (passing all info), - # but we(I?) need an hda collection with full data somewhere ids = ids.split( ',' ) - for hda in history.datasets: - #TODO: curr. ordered by history, change to order from ids list + for index, hda in enumerate( history.datasets ): encoded_hda_id = trans.security.encode_id( hda.id ) if encoded_hda_id in ids: #TODO: share code with show @@ -63,21 +59,19 @@ except Exception, exc: # don't fail entire list if hda err's, record and move on - # (making sure http recvr knows it's err'd) - trans.response.status = 500 log.error( "Error in history API at listing contents with history %s, hda %s: (%s) %s", - history_id, encoded_hda_id, type( exc ), str( exc ) ) - rval.append( self._exception_as_hda_dict( trans, encoded_hda_id, exc ) ) + history_id, encoded_hda_id, type( exc ), str( exc ), exc_info=True ) + rval.append( self.get_hda_dict_with_error( trans, hda, str( exc ) ) ) + # if no ids passed, return a _SUMMARY_ of _all_ datasets in the history else: - # if no ids passed, return a _SUMMARY_ of _all_ datasets in the history for hda in history.datasets: rval.append( self._summary_hda_dict( trans, history_id, hda ) ) except Exception, e: # for errors that are not specific to one hda (history lookup or summary list) rval = "Error in history API at listing contents: " + str( e ) - log.error( rval + ": %s, %s" % ( type( e ), str( e ) ) ) + log.error( rval + ": %s, %s" % ( type( e ), str( e ) ), exc_info=True ) trans.response.status = 500 return rval @@ -102,21 +96,6 @@ 'url' : url_for( 'history_content', history_id=history_id, id=encoded_id, ), } - #TODO: move to model or Mixin - def _exception_as_hda_dict( self, trans, hda_id, exception ): - """ - Returns a dictionary for an HDA that raised an exception when it's - dictionary was being built. - """ - return { - 'id' : hda_id, - 'state' : trans.app.model.Dataset.states.ERROR, - 'visible' : True, - 'misc_info' : str( exception ), - 'misc_blurb': 'Failed to retrieve dataset information.', - 'error' : str( exception ) - } - @web.expose_api_anonymous def show( self, trans, id, history_id, **kwd ): """ diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed lib/galaxy/webapps/galaxy/controllers/tag.py --- a/lib/galaxy/webapps/galaxy/controllers/tag.py +++ b/lib/galaxy/webapps/galaxy/controllers/tag.py @@ -1,11 +1,15 @@ """ -Tags Controller: handles tagging/untagging of entities and provides autocomplete support. +Tags Controller: handles tagging/untagging of entities +and provides autocomplete support. """ -import logging -from galaxy.web.base.controller import * + from sqlalchemy.sql.expression import func, and_ from sqlalchemy.sql import select +from galaxy import web +from galaxy.web.base.controller import BaseUIController, UsesTagsMixin + +import logging log = logging.getLogger( __name__ ) class TagsController ( BaseUIController, UsesTagsMixin ): @@ -13,7 +17,9 @@ @web.expose @web.require_login( "edit item tags" ) def get_tagging_elt_async( self, trans, item_id, item_class, elt_context="" ): - """ Returns HTML for editing an item's tags. """ + """ + Returns HTML for editing an item's tags. + """ item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) ) if not item: return trans.show_error_message( "No item of class %s with id %s " % ( item_class, item_id ) ) @@ -26,10 +32,13 @@ input_size="22", tag_click_fn="default_tag_click_fn", use_toggle_link=False ) + @web.expose @web.require_login( "add tag to an item" ) def add_tag_async( self, trans, item_id=None, item_class=None, new_tag=None, context=None ): - """ Add tag to an item. """ + """ + Add tag to an item. + """ # Apply tag. item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) ) user = trans.user @@ -38,10 +47,13 @@ # Log. params = dict( item_id=item.id, item_class=item_class, tag=new_tag ) trans.log_action( user, unicode( "tag" ), context, params ) + @web.expose @web.require_login( "remove tag from an item" ) def remove_tag_async( self, trans, item_id=None, item_class=None, tag_name=None, context=None ): - """ Remove tag from an item. """ + """ + Remove tag from an item. + """ # Remove tag. item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) ) user = trans.user @@ -50,21 +62,27 @@ # Log. params = dict( item_id=item.id, item_class=item_class, tag=tag_name ) trans.log_action( user, unicode( "untag" ), context, params ) + # Retag an item. All previous tags are deleted and new tags are applied. #@web.expose @web.require_login( "Apply a new set of tags to an item; previous tags are deleted." ) def retag_async( self, trans, item_id=None, item_class=None, new_tags=None ): - """ Apply a new set of tags to an item; previous tags are deleted. """ + """ + Apply a new set of tags to an item; previous tags are deleted. + """ # Apply tags. item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) ) user = trans.user self.get_tag_handler( trans ).delete_item_tags( trans, item ) self.get_tag_handler( trans ).apply_item_tags( trans, user, item, new_tags.encode( 'utf-8' ) ) - trans.sa_session.flush() + trans.sa_session.flush() + @web.expose @web.require_login( "get autocomplete data for an item's tags" ) def tag_autocomplete_data( self, trans, q=None, limit=None, timestamp=None, item_id=None, item_class=None ): - """ Get autocomplete data for an item's tags. """ + """ + Get autocomplete data for an item's tags. + """ # Get item, do security check, and get autocomplete data. item = None if item_id is not None: @@ -76,6 +94,7 @@ return self._get_tag_autocomplete_names( trans, q, limit, timestamp, user, item, item_class ) else: return self._get_tag_autocomplete_values( trans, q, limit, timestamp, user, item, item_class ) + def _get_tag_autocomplete_names( self, trans, q, limit, timestamp, user=None, item=None, item_class=None ): """ Returns autocomplete data for tag names ordered from most frequently used to @@ -115,6 +134,7 @@ tag_names = self._get_usernames_for_tag( trans, trans.user, tag, item_class, item_tag_assoc_class ) ac_data += tag_names[0] + "|" + tag_names[0] + "\n" return ac_data + def _get_tag_autocomplete_values( self, trans, q, limit, timestamp, user=None, item=None, item_class=None ): """ Returns autocomplete data for tag values ordered from most frequently used to @@ -155,6 +175,7 @@ for row in result_set: ac_data += tag_uname + ":" + row[0] + "|" + row[0] + "\n" return ac_data + def _get_usernames_for_tag( self, trans, user, tag, item_class, item_tag_assoc_class ): """ Returns an ordered list of the user names for a tag; list is ordered from @@ -176,8 +197,11 @@ for row in result_set: user_tag_names.append( row[0] ) return user_tag_names + def _get_item( self, trans, item_class_name, id ): - """ Get an item based on type and id. """ + """ + Get an item based on type and id. + """ item_class = self.get_tag_handler( trans ).item_tag_assoc_info[item_class_name].item_class item = trans.sa_session.query( item_class ).filter( "id=" + str( id ) )[0] return item diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed static/scripts/mvc/dataset/hda-edit.js --- a/static/scripts/mvc/dataset/hda-edit.js +++ b/static/scripts/mvc/dataset/hda-edit.js @@ -456,7 +456,8 @@ //BUG: broken with latest //TODO: this is a drop in from history.mako - should use MV as well this.log( this + '.loadAndDisplayTags', event ); - var tagArea = this.$el.find( '.tag-area' ), + var view = this, + tagArea = this.$el.find( '.tag-area' ), tagElt = tagArea.find( '.tag-elt' ); // Show or hide tag area; if showing tag area and it's empty, fill it. @@ -466,7 +467,10 @@ $.ajax({ //TODO: the html from this breaks a couple of times url: this.urls.tags.get, - error: function() { alert( _l( "Tagging failed" ) ); }, + error: function( xhr, status, error ){ + view.log( "Tagging failed", xhr, status, error ); + view.trigger( 'error', _l( "Tagging failed" ), xhr, status, error ); + }, success: function(tag_elt_html) { tagElt.html(tag_elt_html); tagElt.find(".tooltip").tooltip(); diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed static/scripts/mvc/dataset/hda-model.js --- a/static/scripts/mvc/dataset/hda-model.js +++ b/static/scripts/mvc/dataset/hda-model.js @@ -49,7 +49,6 @@ deleted : false, purged : false, visible : true, - // based on trans.user (is_admin or security_agent.can_access_dataset( <user_roles>, hda.dataset )) accessible : true }, @@ -57,7 +56,7 @@ urlRoot: 'api/histories/', url : function(){ //TODO: get this via url router - return 'api/histories/' + this.get( 'history_id' ) + '/contents/' + this.get( 'id' ); + return this.urlRoot + this.get( 'history_id' ) + '/contents/' + this.get( 'id' ); //TODO: this breaks on save() }, diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed static/scripts/mvc/history/history-model.js --- a/static/scripts/mvc/history/history-model.js +++ b/static/scripts/mvc/history/history-model.js @@ -21,18 +21,12 @@ // values from api (may need more) defaults : { - id : '', - name : '', - state : '', + id : null, + name : 'Unnamed History', + state : 'new', diskSize : 0, - deleted : false, - - //tags : [], - annotation : null, - - //TODO: message? how to get over the api? - message : null + deleted : false }, //TODO: hardcoded @@ -40,7 +34,7 @@ /** url for fetch */ url : function(){ // api location of history resource - return 'api/histories/' + this.get( 'id' ); + return this.urlRoot + this.get( 'id' ); }, /** Set up the hdas collection @@ -48,30 +42,20 @@ * @param {Object[]} initialHdas array of model data for this History's HDAs * @see BaseModel#initialize */ - initialize : function( initialSettings, initialHdas ){ + initialize : function( initialSettings, initialHdas, logger ){ + logger = logger || null; this.log( this + ".initialize:", initialSettings, initialHdas ); /** HDACollection of the HDAs contained in this history. */ this.hdas = new HDACollection(); // if we've got hdas passed in the constructor, load them and set up updates if needed - if( initialHdas ){ - if( _.isArray( initialHdas ) ){ - this.hdas.reset( initialHdas ); - this.checkForUpdates(); - //TODO: don't call if force_history_refresh - if( this.hdas.length > 0 ){ - this.updateDisplayApplications(); - } - - // handle errors in initialHdas - //TODO: errors from the api shouldn't be plain strings... - //TODO: remove when mappers and hda_dict are unified (or move to alt history) - } else if( _.isString( initialHdas ) ){ - this.log( 'error in initialHdas: ', initialHdas ); - Galaxy.show_modal( _l( 'Error loading datasets for history' ), initialHdas, - { 'Ok': function(){ Galaxy.hide_modal(); } } ); - //TODO: retry (via ajax), report + if( initialHdas && _.isArray( initialHdas ) ){ + this.hdas.reset( initialHdas ); + this.checkForUpdates(); + //TODO: don't call if force_history_refresh + if( this.hdas.length > 0 ){ + this.updateDisplayApplications(); } } @@ -87,52 +71,11 @@ } }, this ); - // events - //this.on( 'change', function( currModel, changedList ){ - // this.log( this + ' has changed:', currModel, changedList ); - //}); - //this.bind( 'all', function( event ){ - // //this.log( this + '', arguments ); - //}); - }, - - /** get data via the api (alternative to sending options, hdas to initialize) - * @param {String} historyId encoded id - * @param {Object[]} success - * @see BaseModel#initialize - */ - //TODO: this needs work - move to more straightforward deferred - // events: loaded, loaded:user, loaded:hdas - loadFromApi : function( historyId, success ){ - var history = this; - - // fetch the history AND the user (mainly to see if they're logged in at this point) - history.attributes.id = historyId; - //TODO:?? really? fetch user here? - jQuery.when( - jQuery.ajax( 'api/users/current' ), - history.fetch() - - ).then( function( userResponse, historyResponse ){ - history.attributes.user = userResponse[0]; //? meh. - - history.trigger( 'loaded:user', userResponse[0] ); - history.trigger( 'loaded', historyResponse[0] ); - - }).then( function(){ - // ...then the hdas (using contents?ids=...) - jQuery.ajax( history.url() + '/contents?' + jQuery.param({ - ids : history.hdaIdsFromStateIds().join( ',' ) - - // reset the collection to the hdas returned - })).success( function( hdas ){ - history.hdas.reset( hdas ); - history.checkForUpdates(); - - history.trigger( 'loaded:hdas', hdas ); - if( success ){ callback( history ); } - }); - }); + if( this.logger ){ + this.bind( 'all', function( event ){ + this.log( this + '', arguments ); + }, this ); + } }, // reduce the state_ids map of hda id lists -> a single list of ids @@ -146,7 +89,7 @@ // get the history's state from it's cummulative ds states, delay + update if needed // events: ready - checkForUpdates : function( datasets ){ + checkForUpdates : function(){ // get overall History state from collection, run updater if History has running/queued hdas // boiling it down on the client to running/not if( this.hdas.running().length ){ @@ -194,7 +137,6 @@ } // set up to keep pulling if this history in run/queue state - //TODO: magic number here if( ( history.get( 'state' ) === HistoryDatasetAssociation.STATES.RUNNING ) || ( history.get( 'state' ) === HistoryDatasetAssociation.STATES.QUEUED ) ){ setTimeout( function(){ @@ -207,11 +149,22 @@ } }).error( function( xhr, status, error ){ + //TODO: use ajax.status handlers here + // keep rolling on a bad gateway - server restart + if( xhr.status === 502 ){ + setTimeout( function(){ + history.log( 'Bad Gateway error. Retrying...' ); + //TODO: someway to throw error on X tries + history.stateUpdater(); + }, History.UPDATE_DELAY ); + // if not interruption by iframe reload //TODO: remove when iframes are removed - if( !( ( xhr.readyState === 0 ) && ( xhr.status === 0 ) ) ){ - alert( _l( 'Error getting history updates from the server:' ) + '\n' + error ); + } else if( !( ( xhr.readyState === 0 ) && ( xhr.status === 0 ) ) ){ history.log( 'stateUpdater error:', error, 'responseText:', xhr.responseText ); + var msg = _l( 'An error occurred while getting updates from the server.' ) + ' ' + + _l( 'Please contact a Galaxy administrator if the problem persists.' ); + history.trigger( 'error', msg, xhr, status, error ); } }); }, @@ -248,9 +201,11 @@ history.updateHdas( errorJson ); } else { - var msg = _l( 'ERROR updating hdas from api history contents' ) + ': '; - history.log( msg, hdaIds, xhr, status, error, errorJson ); - alert( msg + hdaIds.join(',') ); + history.log( 'Error updating hdas from api history contents', + hdaIds, xhr, status, error, errorJson ); + var msg = _l( 'An error occurred while getting dataset details from the server.' ) + ' ' + + _l( 'Please contact a Galaxy administrator if the problem persists.' ); + history.trigger( 'error', msg, xhr, status, error ); } }, diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed static/scripts/mvc/history/history-panel.js --- a/static/scripts/mvc/history/history-panel.js +++ b/static/scripts/mvc/history/history-panel.js @@ -75,7 +75,8 @@ /** event map */ events : { - 'click #history-tag' : 'loadAndDisplayTags' + 'click #history-tag' : 'loadAndDisplayTags', + 'click #message-container' : 'removeMessage' }, // ......................................................................... SET UP @@ -104,10 +105,28 @@ this._setUpWebStorage( attributes.initiallyExpanded, attributes.show_deleted, attributes.show_hidden ); + this._setUpEventHandlers(); + + // set up instance vars + /** map of hda model ids to hda views */ + this.hdaViews = {}; + /** map web controller urls for history related actions */ + this.urls = {}; + }, + + _setUpEventHandlers : function(){ + // ---- model // don't need to re-render entire model on all changes, just render disk size when it changes //this.model.bind( 'change', this.render, this ); this.model.bind( 'change:nice_size', this.updateHistoryDiskSize, this ); + // don't need to re-render entire model on all changes, just render disk size when it changes + this.model.bind( 'error', function( msg, xhr, error, status ){ + this.displayMessage( 'error', msg ); + this.model.attributes.error = undefined; + }, this ); + + // ---- hdas // bind events from the model's hda collection this.model.hdas.bind( 'add', this.add, this ); this.model.hdas.bind( 'reset', this.addAll, this ); @@ -126,15 +145,16 @@ } }, this ); - //this.bind( 'all', function(){ - // this.log( arguments ); - //}, this ); + // ---- self + this.bind( 'error', function( msg, xhr, error, status ){ + this.displayMessage( 'error', msg ); + }); - // set up instance vars - /** map of hda model ids to hda views */ - this.hdaViews = {}; - /** map web controller urls for history related actions */ - this.urls = {}; + if( this.logger ){ + this.bind( 'all', function( event ){ + this.log( this + '', arguments ); + }, this ); + } }, /** Set up client side storage. Currently PersistanStorage keyed under 'HistoryPanel.<id>' @@ -341,6 +361,9 @@ hdaView.bind( 'body-collapsed', function( id ){ historyView.storage.get( 'expandedHdas' ).deleteKey( id ); }); + hdaView.bind( 'error', function( msg, xhr, status, error ){ + historyView.displayMessage( 'error', msg ); + }); }, /** Set up HistoryPanel js/widget behaviours @@ -431,7 +454,8 @@ //TODO: into sub-MV loadAndDisplayTags : function( event ){ this.log( this + '.loadAndDisplayTags', event ); - var tagArea = this.$el.find( '#history-tag-area' ), + var panel = this, + tagArea = this.$el.find( '#history-tag-area' ), tagElt = tagArea.find( '.tag-elt' ); this.log( '\t tagArea', tagArea, ' tagElt', tagElt ); @@ -443,7 +467,10 @@ $.ajax({ //TODO: the html from this breaks a couple of times url: view.urls.tag, - error: function() { alert( _l( "Tagging failed" ) ); }, + error: function( xhr, error, status ) { + panel.log( 'Error loading tag area html', xhr, error, status ); + panel.trigger( 'error', _l( "Tagging failed" ), xhr, error, status ); + }, success: function(tag_elt_html) { //view.log( view + ' tag elt html (ajax)', tag_elt_html ); tagElt.html(tag_elt_html); @@ -463,6 +490,23 @@ return false; }, + /** display a message in the top of the panel + * @param {String} type type of message ('done', 'error', 'warning') + * @param {String} msg the message to display + */ + displayMessage : function( type, msg ){ + var $msgContainer = this.$el.find( '#message-container' ), + $msg = $( '<div/>' ).addClass( type + 'message' ).text( msg ); + $msgContainer.html( $msg ); + }, + + /** Remove a message from the panel + */ + removeMessage : function(){ + var $msgContainer = this.$el.find( '#message-container' ); + $msgContainer.html( null ); + }, + // ......................................................................... MISC /** Return a string rep of the history */ diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed 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 @@ -var HDAEditView=HDABaseView.extend(LoggableMixin).extend({initialize:function(a){HDABaseView.prototype.initialize.call(this,a);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton,this._render_rerunButton]},_setUpBehaviors:function(c){HDABaseView.prototype._setUpBehaviors.call(this,c);var a=this,b=this.urls.purge,d=c.find("#historyItemPurger-"+this.model.get("id"));if(d){d.attr("href",["javascript","void(0)"].join(":"));d.click(function(e){var f=jQuery.ajax(b);f.success(function(i,g,h){a.model.set("purged",true)});f.error(function(h,g,i){alert("("+h.status+") "+_l("Unable to purge this dataset")+":\n"+h)})})}},_render_warnings:function(){return $(jQuery.trim(HDABaseView.templates.messages(_.extend(this.model.toJSON(),{urls:this.urls}))))},_render_titleButtons:function(){var a=$('<div class="historyItemButtons"></div>');a.append(this._render_displayButton());a.append(this._render_editButton());a.append(this._render_deleteButton());return a},_render_editButton:function(){if((this.model.get("state")===HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===HistoryDatasetAssociation.STATES.UPLOAD)||(this.model.get("state")===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.editButton=null;return null}var c=this.model.get("purged"),a=this.model.get("deleted"),b={title:_l("Edit Attributes"),href:this.urls.edit,target:"galaxy_main",icon_class:"edit"};if(a||c){b.enabled=false;if(c){b.title=_l("Cannot edit attributes of datasets removed from disk")}else{if(a){b.title=_l("Undelete dataset to edit attributes")}}}this.editButton=new IconButtonView({model:new IconButton(b)});return this.editButton.render().$el},_render_deleteButton:function(){if((this.model.get("state")===HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.deleteButton=null;return null}var a=this,b=a.urls["delete"],c={title:_l("Delete"),href:b,id:"historyItemDeleter-"+this.model.get("id"),icon_class:"delete",on_click:function(){$.ajax({url:b,type:"POST",error:function(){a.$el.show()},success:function(){a.model.set({deleted:true})}})}};if(this.model.get("deleted")||this.model.get("purged")){c={title:_l("Dataset is already deleted"),icon_class:"delete",enabled:false}}this.deleteButton=new IconButtonView({model:new IconButton(c)});return this.deleteButton.render().$el},_render_hdaSummary:function(){var a=_.extend(this.model.toJSON(),{urls:this.urls});if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){_.extend(a,{dbkey_unknown_and_editable:true})}return HDABaseView.templates.hdaSummary(a)},_render_errButton:function(){if(this.model.get("state")!==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 c=this.model.get("dbkey"),a=this.model.get("visualizations"),f=this.urls.visualization,d={},g={dataset_id:this.model.get("id"),hda_ldda:"hda"};if(c){g.dbkey=c}if(!(this.model.hasData())||!(a&&a.length)||!(f)){this.visualizationsButton=null;return null}this.visualizationsButton=new IconButtonView({model:new IconButton({title:_l("Visualize"),href:f,icon_class:"chart_curve"})});var b=this.visualizationsButton.render().$el;b.addClass("visualize-icon");function e(h){switch(h){case"trackster":return create_trackster_action_fn(f,g,c);case"scatterplot":return create_scatterplot_action_fn(f,g);default:return function(){window.parent.location=f+"/"+h+"?"+$.param(g)}}}if(a.length===1){b.attr("title",a[0]);b.click(e(a[0]))}else{_.each(a,function(i){var h=i.charAt(0).toUpperCase()+i.slice(1);d[_l(h)]=e(i)});make_popupmenu(b,d)}return b},_render_secondaryActionButtons:function(b){var c=$("<div/>"),a=this;c.attr("style","float: right;").attr("id","secondary-actions-"+this.model.get("id"));_.each(b,function(d){c.append(d.call(a))});return c},_render_tagButton:function(){if(!(this.model.hasData())||(!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.model.hasData())||(!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 $(HDAEditView.templates.tagArea(_.extend(this.model.toJSON(),{urls:this.urls})))},_render_annotationArea:function(){if(!this.urls.annotation.get){return null}return $(HDAEditView.templates.annotationArea(_.extend(this.model.toJSON(),{urls:this.urls})))},_render_body_error:function(a){HDABaseView.prototype._render_body_error.call(this,a);var b=a.find("#primary-actions-"+this.model.get("id"));b.prepend(this._render_errButton())},_render_body_ok:function(a){a.append(this._render_hdaSummary());if(this.model.isDeletedOrPurged()){a.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton,this._render_rerunButton]));return}a.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton,this._render_rerunButton,this._render_visualizationsButton]));a.append(this._render_secondaryActionButtons([this._render_tagButton,this._render_annotateButton]));a.append('<div class="clear"/>');a.append(this._render_tagArea());a.append(this._render_annotationArea());a.append(this._render_displayAppArea());this._render_displayApps(a);a.append(this._render_peek())},events:{"click .historyItemTitle":"toggleBodyVisibility","click a.icon-button.tags":"loadAndDisplayTags","click a.icon-button.annotate":"loadAndDisplayAnnotation"},loadAndDisplayTags:function(b){this.log(this+".loadAndDisplayTags",b);var c=this.$el.find(".tag-area"),a=c.find(".tag-elt");if(c.is(":hidden")){if(!jQuery.trim(a.html())){$.ajax({url:this.urls.tags.get,error:function(){alert(_l("Tagging failed"))},success:function(d){a.html(d);a.find(".tooltip").tooltip();c.slideDown("fast")}})}else{c.slideDown("fast")}}else{c.slideUp("fast")}return false},loadAndDisplayAnnotation:function(b){this.log(this+".loadAndDisplayAnnotation",b);var d=this.$el.find(".annotation-area"),c=d.find(".annotation-elt"),a=this.urls.annotation.set;if(d.is(":hidden")){if(!jQuery.trim(c.html())){$.ajax({url:this.urls.annotation.get,error:function(){alert(_l("Annotations failed"))},success:function(e){if(e===""){e="<em>"+_l("Describe or add notes to dataset")+"</em>"}c.html(e);d.find(".tooltip").tooltip();async_save_text(c.attr("id"),c.attr("id"),a,"new_annotation",18,true,4);d.slideDown("fast")}})}else{d.slideDown("fast")}}else{d.slideUp("fast")}return false},toString:function(){var a=(this.model)?(this.model+""):("(no model)");return"HDAView("+a+")"}});HDAEditView.templates={tagArea:Handlebars.templates["template-hda-tagArea"],annotationArea:Handlebars.templates["template-hda-annotationArea"]};function create_scatterplot_action_fn(a,b){action=function(){var d=$(window.parent.document).find("iframe#galaxy_main"),c=a+"/scatterplot?"+$.param(b);d.attr("src",c);$("div.popmenu-wrapper").remove();return false};return action}function create_trackster_action_fn(a,c,b){return function(){var d={};if(b){d["f-dbkey"]=b}$.ajax({url:a+"/list_tracks?"+$.param(d),dataType:"html",error:function(){alert(_l("Could not add this dataset to browser")+".")},success:function(e){var f=window.parent;f.show_modal(_l("View Data in a New or Saved Visualization"),"",{Cancel:function(){f.hide_modal()},"View in saved visualization":function(){f.show_modal(_l("Add Data to Saved Visualization"),e,{Cancel:function(){f.hide_modal()},"Add to visualization":function(){$(f.document).find("input[name=id]:checked").each(function(){var g=$(this).val();c.id=g;f.location=a+"/trackster?"+$.param(c)})}})},"View in new visualization":function(){f.location=a+"/trackster?"+$.param(c)}})}});return false}}; \ No newline at end of file +var HDAEditView=HDABaseView.extend(LoggableMixin).extend({initialize:function(a){HDABaseView.prototype.initialize.call(this,a);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton,this._render_rerunButton]},_setUpBehaviors:function(c){HDABaseView.prototype._setUpBehaviors.call(this,c);var a=this,b=this.urls.purge,d=c.find("#historyItemPurger-"+this.model.get("id"));if(d){d.attr("href",["javascript","void(0)"].join(":"));d.click(function(e){var f=jQuery.ajax(b);f.success(function(i,g,h){a.model.set("purged",true)});f.error(function(h,g,i){alert("("+h.status+") "+_l("Unable to purge this dataset")+":\n"+h)})})}},_render_warnings:function(){return $(jQuery.trim(HDABaseView.templates.messages(_.extend(this.model.toJSON(),{urls:this.urls}))))},_render_titleButtons:function(){var a=$('<div class="historyItemButtons"></div>');a.append(this._render_displayButton());a.append(this._render_editButton());a.append(this._render_deleteButton());return a},_render_editButton:function(){if((this.model.get("state")===HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===HistoryDatasetAssociation.STATES.UPLOAD)||(this.model.get("state")===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.editButton=null;return null}var c=this.model.get("purged"),a=this.model.get("deleted"),b={title:_l("Edit Attributes"),href:this.urls.edit,target:"galaxy_main",icon_class:"edit"};if(a||c){b.enabled=false;if(c){b.title=_l("Cannot edit attributes of datasets removed from disk")}else{if(a){b.title=_l("Undelete dataset to edit attributes")}}}this.editButton=new IconButtonView({model:new IconButton(b)});return this.editButton.render().$el},_render_deleteButton:function(){if((this.model.get("state")===HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.deleteButton=null;return null}var a=this,b=a.urls["delete"],c={title:_l("Delete"),href:b,id:"historyItemDeleter-"+this.model.get("id"),icon_class:"delete",on_click:function(){$.ajax({url:b,type:"POST",error:function(){a.$el.show()},success:function(){a.model.set({deleted:true})}})}};if(this.model.get("deleted")||this.model.get("purged")){c={title:_l("Dataset is already deleted"),icon_class:"delete",enabled:false}}this.deleteButton=new IconButtonView({model:new IconButton(c)});return this.deleteButton.render().$el},_render_hdaSummary:function(){var a=_.extend(this.model.toJSON(),{urls:this.urls});if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){_.extend(a,{dbkey_unknown_and_editable:true})}return HDABaseView.templates.hdaSummary(a)},_render_errButton:function(){if(this.model.get("state")!==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 c=this.model.get("dbkey"),a=this.model.get("visualizations"),f=this.urls.visualization,d={},g={dataset_id:this.model.get("id"),hda_ldda:"hda"};if(c){g.dbkey=c}if(!(this.model.hasData())||!(a&&a.length)||!(f)){this.visualizationsButton=null;return null}this.visualizationsButton=new IconButtonView({model:new IconButton({title:_l("Visualize"),href:f,icon_class:"chart_curve"})});var b=this.visualizationsButton.render().$el;b.addClass("visualize-icon");function e(h){switch(h){case"trackster":return create_trackster_action_fn(f,g,c);case"scatterplot":return create_scatterplot_action_fn(f,g);default:return function(){window.parent.location=f+"/"+h+"?"+$.param(g)}}}if(a.length===1){b.attr("title",a[0]);b.click(e(a[0]))}else{_.each(a,function(i){var h=i.charAt(0).toUpperCase()+i.slice(1);d[_l(h)]=e(i)});make_popupmenu(b,d)}return b},_render_secondaryActionButtons:function(b){var c=$("<div/>"),a=this;c.attr("style","float: right;").attr("id","secondary-actions-"+this.model.get("id"));_.each(b,function(d){c.append(d.call(a))});return c},_render_tagButton:function(){if(!(this.model.hasData())||(!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.model.hasData())||(!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 $(HDAEditView.templates.tagArea(_.extend(this.model.toJSON(),{urls:this.urls})))},_render_annotationArea:function(){if(!this.urls.annotation.get){return null}return $(HDAEditView.templates.annotationArea(_.extend(this.model.toJSON(),{urls:this.urls})))},_render_body_error:function(a){HDABaseView.prototype._render_body_error.call(this,a);var b=a.find("#primary-actions-"+this.model.get("id"));b.prepend(this._render_errButton())},_render_body_ok:function(a){a.append(this._render_hdaSummary());if(this.model.isDeletedOrPurged()){a.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton,this._render_rerunButton]));return}a.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton,this._render_rerunButton,this._render_visualizationsButton]));a.append(this._render_secondaryActionButtons([this._render_tagButton,this._render_annotateButton]));a.append('<div class="clear"/>');a.append(this._render_tagArea());a.append(this._render_annotationArea());a.append(this._render_displayAppArea());this._render_displayApps(a);a.append(this._render_peek())},events:{"click .historyItemTitle":"toggleBodyVisibility","click a.icon-button.tags":"loadAndDisplayTags","click a.icon-button.annotate":"loadAndDisplayAnnotation"},loadAndDisplayTags:function(c){this.log(this+".loadAndDisplayTags",c);var a=this,d=this.$el.find(".tag-area"),b=d.find(".tag-elt");if(d.is(":hidden")){if(!jQuery.trim(b.html())){$.ajax({url:this.urls.tags.get,error:function(g,e,f){a.log("Tagging failed",g,e,f);a.trigger("error",_l("Tagging failed"),g,e,f)},success:function(e){b.html(e);b.find(".tooltip").tooltip();d.slideDown("fast")}})}else{d.slideDown("fast")}}else{d.slideUp("fast")}return false},loadAndDisplayAnnotation:function(b){this.log(this+".loadAndDisplayAnnotation",b);var d=this.$el.find(".annotation-area"),c=d.find(".annotation-elt"),a=this.urls.annotation.set;if(d.is(":hidden")){if(!jQuery.trim(c.html())){$.ajax({url:this.urls.annotation.get,error:function(){alert(_l("Annotations failed"))},success:function(e){if(e===""){e="<em>"+_l("Describe or add notes to dataset")+"</em>"}c.html(e);d.find(".tooltip").tooltip();async_save_text(c.attr("id"),c.attr("id"),a,"new_annotation",18,true,4);d.slideDown("fast")}})}else{d.slideDown("fast")}}else{d.slideUp("fast")}return false},toString:function(){var a=(this.model)?(this.model+""):("(no model)");return"HDAView("+a+")"}});HDAEditView.templates={tagArea:Handlebars.templates["template-hda-tagArea"],annotationArea:Handlebars.templates["template-hda-annotationArea"]};function create_scatterplot_action_fn(a,b){action=function(){var d=$(window.parent.document).find("iframe#galaxy_main"),c=a+"/scatterplot?"+$.param(b);d.attr("src",c);$("div.popmenu-wrapper").remove();return false};return action}function create_trackster_action_fn(a,c,b){return function(){var d={};if(b){d["f-dbkey"]=b}$.ajax({url:a+"/list_tracks?"+$.param(d),dataType:"html",error:function(){alert(_l("Could not add this dataset to browser")+".")},success:function(e){var f=window.parent;f.show_modal(_l("View Data in a New or Saved Visualization"),"",{Cancel:function(){f.hide_modal()},"View in saved visualization":function(){f.show_modal(_l("Add Data to Saved Visualization"),e,{Cancel:function(){f.hide_modal()},"Add to visualization":function(){$(f.document).find("input[name=id]:checked").each(function(){var g=$(this).val();c.id=g;f.location=a+"/trackster?"+$.param(c)})}})},"View in new visualization":function(){f.location=a+"/trackster?"+$.param(c)}})}});return false}}; \ No newline at end of file diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed 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 @@ -var HistoryDatasetAssociation=BaseModel.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"new",data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:"",deleted:false,purged:false,visible:true,accessible:true},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("history_id")+"/contents/"+this.get("id")},initialize:function(){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",HistoryDatasetAssociation.STATES.NOT_VIEWABLE)}this.on("change:state",function(b,a){this.log(this+" has changed state:",b,a);if(this.inReadyState()){this.trigger("state:ready",b,a,this.previous("state"))}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(b,c){var a=true;if((!b)&&(this.get("deleted")||this.get("purged"))){a=false}if((!c)&&(!this.get("visible"))){a=false}return a},inReadyState:function(){var a=this.get("state");return(this.isDeletedOrPurged()||(a===HistoryDatasetAssociation.STATES.OK)||(a===HistoryDatasetAssociation.STATES.EMPTY)||(a===HistoryDatasetAssociation.STATES.FAILED_METADATA)||(a===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(a===HistoryDatasetAssociation.STATES.DISCARDED)||(a===HistoryDatasetAssociation.STATES.ERROR))},hasData:function(){return(this.get("file_size")>0)},toString:function(){var a=this.get("id")||"";if(this.get("name")){a=this.get("hid")+' :"'+this.get("name")+'",'+a}return"HDA("+a+")"}});HistoryDatasetAssociation.STATES={UPLOAD:"upload",QUEUED:"queued",PAUSED:"paused",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};var HDACollection=Backbone.Collection.extend(LoggableMixin).extend({model:HistoryDatasetAssociation,initialize:function(){},ids:function(){return this.map(function(a){return a.id})},getByHid:function(a){return _.first(this.filter(function(b){return b.get("hid")===a}))},hidToCollectionIndex:function(a){if(!a){return this.models.length}var d=this.models.length-1;for(var b=d;b>=0;b--){var c=this.at(b).get("hid");if(c==a){return b}if(c<a){return b+1}}return null},getVisible:function(a,b){return this.filter(function(c){return c.isVisible(a,b)})},getStateLists:function(){var a={};_.each(_.values(HistoryDatasetAssociation.STATES),function(b){a[b]=[]});this.each(function(b){a[b.get("state")].push(b.get("id"))});return a},running:function(){var a=[];this.each(function(b){if(!b.inReadyState()){a.push(b.get("id"))}});return a},set:function(a){var b=this;if(!a||!_.isArray(a)){return}a.forEach(function(c){var d=b.get(c.id);if(d){d.set(c)}})},update:function(a){this.log(this+"update:",a);if(!(a&&a.length)){return[]}var c=this,b=null;_.each(a,function(f,d){var e=c.get(f);if(e){e.fetch();b.push(e)}});return b},toString:function(){return("HDACollection()")}}); \ No newline at end of file +var HistoryDatasetAssociation=BaseModel.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"new",data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:"",deleted:false,purged:false,visible:true,accessible:true},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("history_id")+"/contents/"+this.get("id")},initialize:function(){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",HistoryDatasetAssociation.STATES.NOT_VIEWABLE)}this.on("change:state",function(b,a){this.log(this+" has changed state:",b,a);if(this.inReadyState()){this.trigger("state:ready",b,a,this.previous("state"))}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(b,c){var a=true;if((!b)&&(this.get("deleted")||this.get("purged"))){a=false}if((!c)&&(!this.get("visible"))){a=false}return a},inReadyState:function(){var a=this.get("state");return(this.isDeletedOrPurged()||(a===HistoryDatasetAssociation.STATES.OK)||(a===HistoryDatasetAssociation.STATES.EMPTY)||(a===HistoryDatasetAssociation.STATES.FAILED_METADATA)||(a===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(a===HistoryDatasetAssociation.STATES.DISCARDED)||(a===HistoryDatasetAssociation.STATES.ERROR))},hasData:function(){return(this.get("file_size")>0)},toString:function(){var a=this.get("id")||"";if(this.get("name")){a=this.get("hid")+' :"'+this.get("name")+'",'+a}return"HDA("+a+")"}});HistoryDatasetAssociation.STATES={UPLOAD:"upload",QUEUED:"queued",PAUSED:"paused",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};var HDACollection=Backbone.Collection.extend(LoggableMixin).extend({model:HistoryDatasetAssociation,initialize:function(){},ids:function(){return this.map(function(a){return a.id})},getByHid:function(a){return _.first(this.filter(function(b){return b.get("hid")===a}))},hidToCollectionIndex:function(a){if(!a){return this.models.length}var d=this.models.length-1;for(var b=d;b>=0;b--){var c=this.at(b).get("hid");if(c==a){return b}if(c<a){return b+1}}return null},getVisible:function(a,b){return this.filter(function(c){return c.isVisible(a,b)})},getStateLists:function(){var a={};_.each(_.values(HistoryDatasetAssociation.STATES),function(b){a[b]=[]});this.each(function(b){a[b.get("state")].push(b.get("id"))});return a},running:function(){var a=[];this.each(function(b){if(!b.inReadyState()){a.push(b.get("id"))}});return a},set:function(a){var b=this;if(!a||!_.isArray(a)){return}a.forEach(function(c){var d=b.get(c.id);if(d){d.set(c)}})},update:function(a){this.log(this+"update:",a);if(!(a&&a.length)){return[]}var c=this,b=null;_.each(a,function(f,d){var e=c.get(f);if(e){e.fetch();b.push(e)}});return b},toString:function(){return("HDACollection()")}}); \ No newline at end of file diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed 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 @@ -var History=BaseModel.extend(LoggableMixin).extend({defaults:{id:"",name:"",state:"",diskSize:0,deleted:false,annotation:null,message:null},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("id")},initialize:function(a,b){this.log(this+".initialize:",a,b);this.hdas=new HDACollection();if(b){if(_.isArray(b)){this.hdas.reset(b);this.checkForUpdates();if(this.hdas.length>0){this.updateDisplayApplications()}}else{if(_.isString(b)){this.log("error in initialHdas: ",b);Galaxy.show_modal(_l("Error loading datasets for history"),b,{Ok:function(){Galaxy.hide_modal()}})}}}this.hdas.bind("state:ready",function(d,f,c){if(d.get("force_history_refresh")){var e=this;setTimeout(function(){e.stateUpdater()},History.UPDATE_DELAY)}},this)},loadFromApi:function(a,c){var b=this;b.attributes.id=a;jQuery.when(jQuery.ajax("api/users/current"),b.fetch()).then(function(e,d){b.attributes.user=e[0];b.trigger("loaded:user",e[0]);b.trigger("loaded",d[0])}).then(function(){jQuery.ajax(b.url()+"/contents?"+jQuery.param({ids:b.hdaIdsFromStateIds().join(",")})).success(function(d){b.hdas.reset(d);b.checkForUpdates();b.trigger("loaded:hdas",d);if(c){callback(b)}})})},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(a){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(f,d,e){if(!((f.readyState===0)&&(f.status===0))){alert(_l("Error getting history updates from the server:")+"\n"+e);c.log("stateUpdater error:",e,"responseText:",f.responseText)}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{var g=_l("ERROR updating hdas from api history contents")+": ";a.log(g,b,h,c,d,f);alert(g+b.join(","))}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},updateDisplayApplications:function(a){this.log(this+"updateDisplayApplications:",a);var c=this,b=(a&&_.isArray(a))?({hda_ids:a.join(",")}):({});c.log(this+": fetching display application data");jQuery.ajax("history/get_display_application_links",{data:b,success:function(e,d,f){c.hdas.set(e)},error:function(g,d,e){if(!((g.readyState===0)&&(g.status===0))){var f="Error fetching display applications, "+a+":"+(g.responseText||e);Galaxy.show_modal("History panel error",f,{Ok:function(){Galaxy.hide_modal()}});this.log(f)}}})},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"}); \ No newline at end of file +var History=BaseModel.extend(LoggableMixin).extend({defaults:{id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("id")},initialize:function(b,c,a){a=a||null;this.log(this+".initialize:",b,c);this.hdas=new HDACollection();if(c&&_.isArray(c)){this.hdas.reset(c);this.checkForUpdates();if(this.hdas.length>0){this.updateDisplayApplications()}}this.hdas.bind("state:ready",function(e,g,d){if(e.get("force_history_refresh")){var f=this;setTimeout(function(){f.stateUpdater()},History.UPDATE_DELAY)}},this);if(this.logger){this.bind("all",function(d){this.log(this+"",arguments)},this)}},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(g,d,e){if(g.status===502){setTimeout(function(){c.log("Bad Gateway error. Retrying...");c.stateUpdater()},History.UPDATE_DELAY)}else{if(!((g.readyState===0)&&(g.status===0))){c.log("stateUpdater error:",e,"responseText:",g.responseText);var f=_l("An error occurred while getting updates from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{a.log("Error updating hdas from api history contents",b,h,c,d,f);var g=_l("An error occurred while getting dataset details from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");a.trigger("error",g,h,c,d)}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},updateDisplayApplications:function(a){this.log(this+"updateDisplayApplications:",a);var c=this,b=(a&&_.isArray(a))?({hda_ids:a.join(",")}):({});c.log(this+": fetching display application data");jQuery.ajax("history/get_display_application_links",{data:b,success:function(e,d,f){c.hdas.set(e)},error:function(g,d,e){if(!((g.readyState===0)&&(g.status===0))){var f="Error fetching display applications, "+a+":"+(g.responseText||e);Galaxy.show_modal("History panel error",f,{Ok:function(){Galaxy.hide_modal()}});this.log(f)}}})},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"}); \ No newline at end of file diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed 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 @@ -var HistoryPanel=BaseView.extend(LoggableMixin).extend({el:"body.historyPage",HDAView:HDAEditView,events:{"click #history-tag":"loadAndDisplayTags"},initialize:function(a){if(a.logger){this.logger=this.model.logger=a.logger}this.log(this+".initialize:",a);if(!a.urlTemplates){throw (this+" needs urlTemplates on initialize")}if(!a.urlTemplates.history){throw (this+" needs urlTemplates.history on initialize")}if(!a.urlTemplates.hda){throw (this+" needs urlTemplates.hda on initialize")}this.urlTemplates=a.urlTemplates.history;this.hdaUrlTemplates=a.urlTemplates.hda;this._setUpWebStorage(a.initiallyExpanded,a.show_deleted,a.show_hidden);this.model.bind("change:nice_size",this.updateHistoryDiskSize,this);this.model.hdas.bind("add",this.add,this);this.model.hdas.bind("reset",this.addAll,this);this.model.hdas.bind("change:deleted",this.handleHdaDeletionChange,this);this.model.hdas.bind("state:ready",function(c,d,b){if((!c.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(c.get("id"))}},this);this.hdaViews={};this.urls={}},_setUpWebStorage:function(b,a,c){this.storage=new PersistantStorage("HistoryView."+this.model.get("id"),{expandedHdas:{},show_deleted:false,show_hidden:false});this.log(this+" (prev) storage:",JSON.stringify(this.storage.get(),null,2));if(b){this.storage.set("exandedHdas",b)}if((a===true)||(a===false)){this.storage.set("show_deleted",a)}if((c===true)||(c===false)){this.storage.set("show_hidden",c)}this.show_deleted=this.storage.get("show_deleted");this.show_hidden=this.storage.get("show_hidden");this.log(this+" (init'd) storage:",this.storage.get())},add:function(a){this.render()},addAll:function(){this.render()},handleHdaDeletionChange:function(a){if(a.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(a.get("id"))}},removeHdaView:function(c,b){var a=this.hdaViews[c];if(!a){return}a.remove(b);delete this.hdaViews[c];if(_.isEmpty(this.hdaViews)){this.render()}},render:function(){var b=this,d=b.toString()+".set-up",c=$("<div/>"),a=this.model.toJSON(),e=(this.$el.children().size()===0);a.urls=this._renderUrls(a);c.append(HistoryPanel.templates.historyPanel(a));c.find(".tooltip").tooltip({placement:"bottom"});if(!this.model.hdas.length||!this.renderItems(c.find("#"+this.model.get("id")+"-datasets"))){c.find("#emptyHistoryMessage").show()}$(b).queue(d,function(f){b.$el.fadeOut("fast",function(){f()})});$(b).queue(d,function(f){b.$el.html("");b.$el.append(c.children());b.$el.fadeIn("fast",function(){f()})});$(b).queue(d,function(f){this.log(b+" rendered:",b.$el);b._setUpBehaviours();if(e){b.trigger("rendered:initial")}else{b.trigger("rendered")}f()});$(b).dequeue(d);return this},_renderUrls:function(a){var b=this;b.urls={};_.each(this.urlTemplates,function(d,c){b.urls[c]=_.template(d,a)});return b.urls},renderItems:function(b){this.hdaViews={};var a=this,c=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"));_.each(c,function(f){var e=f.get("id"),d=a.storage.get("expandedHdas").get(e);a.hdaViews[e]=new a.HDAView({model:f,expanded:d,urlTemplates:a.hdaUrlTemplates,logger:a.logger});a._setUpHdaListeners(a.hdaViews[e]);b.prepend(a.hdaViews[e].render().$el)});return c.length},_setUpHdaListeners:function(b){var a=this;b.bind("body-expanded",function(c){a.storage.get("expandedHdas").set(c,true)});b.bind("body-collapsed",function(c){a.storage.get("expandedHdas").deleteKey(c)})},_setUpBehaviours:function(){if(!(this.model.get("user")&&this.model.get("user").email)){return}var a=this.$("#history-annotation-area");this.$("#history-annotate").click(function(){if(a.is(":hidden")){a.slideDown("fast")}else{a.slideUp("fast")}return false});async_save_text("history-name-container","history-name",this.urls.rename,"new_name",18);async_save_text("history-annotation-container","history-annotation",this.urls.annotate,"new_annotation",18,true,4)},updateHistoryDiskSize:function(){this.$el.find("#history-size").text(this.model.get("nice_size"))},showQuotaMessage:function(){var a=this.$el.find("#quota-message-container");if(a.is(":hidden")){a.slideDown("fast")}},hideQuotaMessage:function(){var a=this.$el.find("#quota-message-container");if(!a.is(":hidden")){a.slideUp("fast")}},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")},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(a){a.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},loadAndDisplayTags:function(c){this.log(this+".loadAndDisplayTags",c);var d=this.$el.find("#history-tag-area"),b=d.find(".tag-elt");this.log("\t tagArea",d," tagElt",b);if(d.is(":hidden")){if(!jQuery.trim(b.html())){var a=this;$.ajax({url:a.urls.tag,error:function(){alert(_l("Tagging failed"))},success:function(e){b.html(e);b.find(".tooltip").tooltip();d.slideDown("fast")}})}else{d.slideDown("fast")}}else{d.slideUp("fast")}return false},toString:function(){var a=this.model.get("name")||"";return"HistoryPanel("+a+")"}});HistoryPanel.templates={historyPanel:Handlebars.templates["template-history-historyPanel"]}; \ No newline at end of file +var HistoryPanel=BaseView.extend(LoggableMixin).extend({el:"body.historyPage",HDAView:HDAEditView,events:{"click #history-tag":"loadAndDisplayTags","click #message-container":"removeMessage"},initialize:function(a){if(a.logger){this.logger=this.model.logger=a.logger}this.log(this+".initialize:",a);if(!a.urlTemplates){throw (this+" needs urlTemplates on initialize")}if(!a.urlTemplates.history){throw (this+" needs urlTemplates.history on initialize")}if(!a.urlTemplates.hda){throw (this+" needs urlTemplates.hda on initialize")}this.urlTemplates=a.urlTemplates.history;this.hdaUrlTemplates=a.urlTemplates.hda;this._setUpWebStorage(a.initiallyExpanded,a.show_deleted,a.show_hidden);this._setUpEventHandlers();this.hdaViews={};this.urls={}},_setUpEventHandlers:function(){this.model.bind("change:nice_size",this.updateHistoryDiskSize,this);this.model.bind("error",function(d,c,b,a){this.displayMessage("error",d);this.model.attributes.error=undefined},this);this.model.hdas.bind("add",this.add,this);this.model.hdas.bind("reset",this.addAll,this);this.model.hdas.bind("change:deleted",this.handleHdaDeletionChange,this);this.model.hdas.bind("state:ready",function(b,c,a){if((!b.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(b.get("id"))}},this);this.bind("error",function(d,c,b,a){this.displayMessage("error",d)});if(this.logger){this.bind("all",function(a){this.log(this+"",arguments)},this)}},_setUpWebStorage:function(b,a,c){this.storage=new PersistantStorage("HistoryView."+this.model.get("id"),{expandedHdas:{},show_deleted:false,show_hidden:false});this.log(this+" (prev) storage:",JSON.stringify(this.storage.get(),null,2));if(b){this.storage.set("exandedHdas",b)}if((a===true)||(a===false)){this.storage.set("show_deleted",a)}if((c===true)||(c===false)){this.storage.set("show_hidden",c)}this.show_deleted=this.storage.get("show_deleted");this.show_hidden=this.storage.get("show_hidden");this.log(this+" (init'd) storage:",this.storage.get())},add:function(a){this.render()},addAll:function(){this.render()},handleHdaDeletionChange:function(a){if(a.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(a.get("id"))}},removeHdaView:function(c,b){var a=this.hdaViews[c];if(!a){return}a.remove(b);delete this.hdaViews[c];if(_.isEmpty(this.hdaViews)){this.render()}},render:function(){var b=this,d=b.toString()+".set-up",c=$("<div/>"),a=this.model.toJSON(),e=(this.$el.children().size()===0);a.urls=this._renderUrls(a);c.append(HistoryPanel.templates.historyPanel(a));c.find(".tooltip").tooltip({placement:"bottom"});if(!this.model.hdas.length||!this.renderItems(c.find("#"+this.model.get("id")+"-datasets"))){c.find("#emptyHistoryMessage").show()}$(b).queue(d,function(f){b.$el.fadeOut("fast",function(){f()})});$(b).queue(d,function(f){b.$el.html("");b.$el.append(c.children());b.$el.fadeIn("fast",function(){f()})});$(b).queue(d,function(f){this.log(b+" rendered:",b.$el);b._setUpBehaviours();if(e){b.trigger("rendered:initial")}else{b.trigger("rendered")}f()});$(b).dequeue(d);return this},_renderUrls:function(a){var b=this;b.urls={};_.each(this.urlTemplates,function(d,c){b.urls[c]=_.template(d,a)});return b.urls},renderItems:function(b){this.hdaViews={};var a=this,c=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"));_.each(c,function(f){var e=f.get("id"),d=a.storage.get("expandedHdas").get(e);a.hdaViews[e]=new a.HDAView({model:f,expanded:d,urlTemplates:a.hdaUrlTemplates,logger:a.logger});a._setUpHdaListeners(a.hdaViews[e]);b.prepend(a.hdaViews[e].render().$el)});return c.length},_setUpHdaListeners:function(b){var a=this;b.bind("body-expanded",function(c){a.storage.get("expandedHdas").set(c,true)});b.bind("body-collapsed",function(c){a.storage.get("expandedHdas").deleteKey(c)});b.bind("error",function(f,e,c,d){a.displayMessage("error",f)})},_setUpBehaviours:function(){if(!(this.model.get("user")&&this.model.get("user").email)){return}var a=this.$("#history-annotation-area");this.$("#history-annotate").click(function(){if(a.is(":hidden")){a.slideDown("fast")}else{a.slideUp("fast")}return false});async_save_text("history-name-container","history-name",this.urls.rename,"new_name",18);async_save_text("history-annotation-container","history-annotation",this.urls.annotate,"new_annotation",18,true,4)},updateHistoryDiskSize:function(){this.$el.find("#history-size").text(this.model.get("nice_size"))},showQuotaMessage:function(){var a=this.$el.find("#quota-message-container");if(a.is(":hidden")){a.slideDown("fast")}},hideQuotaMessage:function(){var a=this.$el.find("#quota-message-container");if(!a.is(":hidden")){a.slideUp("fast")}},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")},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(a){a.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},loadAndDisplayTags:function(d){this.log(this+".loadAndDisplayTags",d);var b=this,e=this.$el.find("#history-tag-area"),c=e.find(".tag-elt");this.log("\t tagArea",e," tagElt",c);if(e.is(":hidden")){if(!jQuery.trim(c.html())){var a=this;$.ajax({url:a.urls.tag,error:function(h,g,f){b.log("Error loading tag area html",h,g,f);b.trigger("error",_l("Tagging failed"),h,g,f)},success:function(f){c.html(f);c.find(".tooltip").tooltip();e.slideDown("fast")}})}else{e.slideDown("fast")}}else{e.slideUp("fast")}return false},displayMessage:function(c,d){var b=this.$el.find("#message-container"),a=$("<div/>").addClass(c+"message").text(d);b.html(a)},removeMessage:function(){var a=this.$el.find("#message-container");a.html(null)},toString:function(){var a=this.model.get("name")||"";return"HistoryPanel("+a+")"}});HistoryPanel.templates={historyPanel:Handlebars.templates["template-history-historyPanel"]}; \ No newline at end of file diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed static/scripts/packed/templates/compiled/template-history-historyPanel.js --- a/static/scripts/packed/templates/compiled/template-history-historyPanel.js +++ b/static/scripts/packed/templates/compiled/template-history-historyPanel.js @@ -1,1 +1,1 @@ -(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel"]=b(function(m,B,z,s,I){this.compilerInfo=[2,">= 1.0.0-rc.3"];z=z||m.helpers;I=I||{};var A="",p,l,h,w=this,e="function",c=z.blockHelperMissing,d=this.escapeExpression;function v(N,M){var J="",L,K;J+='\n <div id="history-name" class="tooltip editable-text"\n title="';K={hash:{},inverse:w.noop,fn:w.program(2,u,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='">';if(L=z.name){L=L.call(N,{hash:{},data:M})}else{L=N.name;L=typeof L===e?L.apply(N):L}J+=d(L)+"</div>\n ";return J}function u(K,J){return"Click to rename history"}function t(N,M){var J="",L,K;J+='\n <div id="history-name" class="tooltip"\n title="';K={hash:{},inverse:w.noop,fn:w.program(5,r,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='">';if(L=z.name){L=L.call(N,{hash:{},data:M})}else{L=N.name;L=typeof L===e?L.apply(N):L}J+=d(L)+"</div>\n ";return J}function r(K,J){return"You must be logged in to edit your history name"}function q(N,M){var J="",L,K;J+='\n <a id="history-tag" title="';K={hash:{},inverse:w.noop,fn:w.program(8,o,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='"\n class="icon-button tags tooltip" target="galaxy_main" href="javascript:void(0)"></a>\n <a id="history-annotate" title="';K={hash:{},inverse:w.noop,fn:w.program(10,H,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='"\n class="icon-button annotate tooltip" target="galaxy_main" href="javascript:void(0)"></a>\n ';return J}function o(K,J){return"Edit history tags"}function H(K,J){return"Edit history annotation"}function G(N,M){var J="",L,K;J+='\n <div id="history-tag-annotation">\n\n <div id="history-tag-area" style="display: none">\n <strong>';K={hash:{},inverse:w.noop,fn:w.program(13,F,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+=':</strong>\n <div class="tag-elt"></div>\n </div>\n\n <div id="history-annotation-area" style="display: none">\n <strong>';K={hash:{},inverse:w.noop,fn:w.program(15,E,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+=':</strong>\n <div id="history-annotation-container">\n <div id="history-annotation" class="tooltip editable-text"\n title="';K={hash:{},inverse:w.noop,fn:w.program(17,D,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='">\n ';L=z["if"].call(N,N.annotation,{hash:{},inverse:w.program(21,n,M),fn:w.program(19,C,M),data:M});if(L||L===0){J+=L}J+="\n </div>\n </div>\n </div>\n </div>\n ";return J}function F(K,J){return"Tags"}function E(K,J){return"Annotation"}function D(K,J){return"Click to edit annotation"}function C(M,L){var J="",K;J+="\n ";if(K=z.annotation){K=K.call(M,{hash:{},data:L})}else{K=M.annotation;K=typeof K===e?K.apply(M):K}J+=d(K)+"\n ";return J}function n(N,M){var J="",L,K;J+="\n <em>";K={hash:{},inverse:w.noop,fn:w.program(22,k,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+="</em>\n ";return J}function k(K,J){return"Describe or add notes to history"}function j(N,M){var J="",L,K;J+="\n ";K={hash:{},inverse:w.noop,fn:w.program(25,i,M),data:M};if(L=z.warningmessagesmall){L=L.call(N,K)}else{L=N.warningmessagesmall;L=typeof L===e?L.apply(N):L}if(!z.warningmessagesmall){L=c.call(N,L,K)}if(L||L===0){J+=L}J+="\n ";return J}function i(M,L){var K,J;J={hash:{},inverse:w.noop,fn:w.program(26,g,L),data:L};if(K=z.local){K=K.call(M,J)}else{K=M.local;K=typeof K===e?K.apply(M):K}if(!z.local){K=c.call(M,K,J)}if(K||K===0){return K}else{return""}}function g(K,J){return"You are currently viewing a deleted history!"}function f(M,L){var J="",K;J+='\n <div id="message-container">\n <div class="';if(K=z.status){K=K.call(M,{hash:{},data:L})}else{K=M.status;K=typeof K===e?K.apply(M):K}J+=d(K)+'message">';if(K=z.message){K=K.call(M,{hash:{},data:L})}else{K=M.message;K=typeof K===e?K.apply(M):K}J+=d(K)+"</div>\n </div>\n ";return J}function y(K,J){return"You are over your disk quota.\n Tool execution is on hold until your disk usage drops below your allocated quota."}function x(K,J){return"Your history is empty. Click 'Get Data' on the left pane to start"}A+='<div id="history-controls">\n\n <div id="history-title-area" class="historyLinks">\n \n <div id="history-name-container">\n \n ';l=z["if"].call(B,((p=B.user),p==null||p===false?p:p.email),{hash:{},inverse:w.program(4,t,I),fn:w.program(1,v,I),data:I});if(l||l===0){A+=l}A+='\n </div>\n </div>\n\n <div id="history-subtitle-area">\n <div id="history-size" style="float:left;">';if(l=z.nice_size){l=l.call(B,{hash:{},data:I})}else{l=B.nice_size;l=typeof l===e?l.apply(B):l}A+=d(l)+'</div>\n\n <div id="history-secondary-links" style="float: right;">\n ';l=z["if"].call(B,((p=B.user),p==null||p===false?p:p.email),{hash:{},inverse:w.noop,fn:w.program(7,q,I),data:I});if(l||l===0){A+=l}A+='\n </div>\n <div style="clear: both;"></div>\n </div>\n\n \n \n ';l=z["if"].call(B,((p=B.user),p==null||p===false?p:p.email),{hash:{},inverse:w.noop,fn:w.program(12,G,I),data:I});if(l||l===0){A+=l}A+="\n\n ";l=z["if"].call(B,B.deleted,{hash:{},inverse:w.noop,fn:w.program(24,j,I),data:I});if(l||l===0){A+=l}A+="\n\n ";l=z["if"].call(B,B.message,{hash:{},inverse:w.noop,fn:w.program(28,f,I),data:I});if(l||l===0){A+=l}A+='\n\n <div id="quota-message-container" style="display: none">\n <div id="quota-message" class="errormessage">\n ';h={hash:{},inverse:w.noop,fn:w.program(30,y,I),data:I};if(l=z.local){l=l.call(B,h)}else{l=B.local;l=typeof l===e?l.apply(B):l}if(!z.local){l=c.call(B,l,h)}if(l||l===0){A+=l}A+='\n </div>\n </div>\n</div>\n\n<div id="';if(l=z.id){l=l.call(B,{hash:{},data:I})}else{l=B.id;l=typeof l===e?l.apply(B):l}A+=d(l)+'-datasets" class="history-datasets-list"></div>\n\n<div class="infomessagesmall" id="emptyHistoryMessage" style="display: none;">\n ';h={hash:{},inverse:w.noop,fn:w.program(32,x,I),data:I};if(l=z.local){l=l.call(B,h)}else{l=B.local;l=typeof l===e?l.apply(B):l}if(!z.local){l=c.call(B,l,h)}if(l||l===0){A+=l}A+="\n</div>";return A})})(); \ No newline at end of file +(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel"]=b(function(m,B,z,s,I){this.compilerInfo=[2,">= 1.0.0-rc.3"];z=z||m.helpers;I=I||{};var A="",p,l,h,w=this,e="function",c=z.blockHelperMissing,d=this.escapeExpression;function v(N,M){var J="",L,K;J+='\n <div id="history-name" class="tooltip editable-text"\n title="';K={hash:{},inverse:w.noop,fn:w.program(2,u,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='">';if(L=z.name){L=L.call(N,{hash:{},data:M})}else{L=N.name;L=typeof L===e?L.apply(N):L}J+=d(L)+"</div>\n ";return J}function u(K,J){return"Click to rename history"}function t(N,M){var J="",L,K;J+='\n <div id="history-name" class="tooltip"\n title="';K={hash:{},inverse:w.noop,fn:w.program(5,r,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='">';if(L=z.name){L=L.call(N,{hash:{},data:M})}else{L=N.name;L=typeof L===e?L.apply(N):L}J+=d(L)+"</div>\n ";return J}function r(K,J){return"You must be logged in to edit your history name"}function q(N,M){var J="",L,K;J+='\n <a id="history-tag" title="';K={hash:{},inverse:w.noop,fn:w.program(8,o,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='"\n class="icon-button tags tooltip" target="galaxy_main" href="javascript:void(0)"></a>\n <a id="history-annotate" title="';K={hash:{},inverse:w.noop,fn:w.program(10,H,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='"\n class="icon-button annotate tooltip" target="galaxy_main" href="javascript:void(0)"></a>\n ';return J}function o(K,J){return"Edit history tags"}function H(K,J){return"Edit history annotation"}function G(N,M){var J="",L,K;J+='\n <div id="history-tag-annotation">\n\n <div id="history-tag-area" style="display: none">\n <strong>';K={hash:{},inverse:w.noop,fn:w.program(13,F,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+=':</strong>\n <div class="tag-elt"></div>\n </div>\n\n <div id="history-annotation-area" style="display: none">\n <strong>';K={hash:{},inverse:w.noop,fn:w.program(15,E,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+=':</strong>\n <div id="history-annotation-container">\n <div id="history-annotation" class="tooltip editable-text"\n title="';K={hash:{},inverse:w.noop,fn:w.program(17,D,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+='">\n ';L=z["if"].call(N,N.annotation,{hash:{},inverse:w.program(21,n,M),fn:w.program(19,C,M),data:M});if(L||L===0){J+=L}J+="\n </div>\n </div>\n </div>\n </div>\n ";return J}function F(K,J){return"Tags"}function E(K,J){return"Annotation"}function D(K,J){return"Click to edit annotation"}function C(M,L){var J="",K;J+="\n ";if(K=z.annotation){K=K.call(M,{hash:{},data:L})}else{K=M.annotation;K=typeof K===e?K.apply(M):K}J+=d(K)+"\n ";return J}function n(N,M){var J="",L,K;J+="\n <em>";K={hash:{},inverse:w.noop,fn:w.program(22,k,M),data:M};if(L=z.local){L=L.call(N,K)}else{L=N.local;L=typeof L===e?L.apply(N):L}if(!z.local){L=c.call(N,L,K)}if(L||L===0){J+=L}J+="</em>\n ";return J}function k(K,J){return"Describe or add notes to history"}function j(N,M){var J="",L,K;J+="\n ";K={hash:{},inverse:w.noop,fn:w.program(25,i,M),data:M};if(L=z.warningmessagesmall){L=L.call(N,K)}else{L=N.warningmessagesmall;L=typeof L===e?L.apply(N):L}if(!z.warningmessagesmall){L=c.call(N,L,K)}if(L||L===0){J+=L}J+="\n ";return J}function i(M,L){var K,J;J={hash:{},inverse:w.noop,fn:w.program(26,g,L),data:L};if(K=z.local){K=K.call(M,J)}else{K=M.local;K=typeof K===e?K.apply(M):K}if(!z.local){K=c.call(M,K,J)}if(K||K===0){return K}else{return""}}function g(K,J){return"You are currently viewing a deleted history!"}function f(M,L){var J="",K;J+='\n <div class="';if(K=z.status){K=K.call(M,{hash:{},data:L})}else{K=M.status;K=typeof K===e?K.apply(M):K}J+=d(K)+'message">';if(K=z.message){K=K.call(M,{hash:{},data:L})}else{K=M.message;K=typeof K===e?K.apply(M):K}J+=d(K)+"</div>\n ";return J}function y(K,J){return"You are over your disk quota.\n Tool execution is on hold until your disk usage drops below your allocated quota."}function x(K,J){return"Your history is empty. Click 'Get Data' on the left pane to start"}A+='<div id="history-controls">\n\n <div id="history-title-area" class="historyLinks">\n \n <div id="history-name-container">\n \n ';l=z["if"].call(B,((p=B.user),p==null||p===false?p:p.email),{hash:{},inverse:w.program(4,t,I),fn:w.program(1,v,I),data:I});if(l||l===0){A+=l}A+='\n </div>\n </div>\n\n <div id="history-subtitle-area">\n <div id="history-size" style="float:left;">';if(l=z.nice_size){l=l.call(B,{hash:{},data:I})}else{l=B.nice_size;l=typeof l===e?l.apply(B):l}A+=d(l)+'</div>\n\n <div id="history-secondary-links" style="float: right;">\n ';l=z["if"].call(B,((p=B.user),p==null||p===false?p:p.email),{hash:{},inverse:w.noop,fn:w.program(7,q,I),data:I});if(l||l===0){A+=l}A+='\n </div>\n <div style="clear: both;"></div>\n </div>\n\n \n \n ';l=z["if"].call(B,((p=B.user),p==null||p===false?p:p.email),{hash:{},inverse:w.noop,fn:w.program(12,G,I),data:I});if(l||l===0){A+=l}A+="\n\n ";l=z["if"].call(B,B.deleted,{hash:{},inverse:w.noop,fn:w.program(24,j,I),data:I});if(l||l===0){A+=l}A+='\n\n <div id="message-container">\n ';l=z["if"].call(B,B.message,{hash:{},inverse:w.noop,fn:w.program(28,f,I),data:I});if(l||l===0){A+=l}A+='\n </div>\n\n <div id="quota-message-container" style="display: none">\n <div id="quota-message" class="errormessage">\n ';h={hash:{},inverse:w.noop,fn:w.program(30,y,I),data:I};if(l=z.local){l=l.call(B,h)}else{l=B.local;l=typeof l===e?l.apply(B):l}if(!z.local){l=c.call(B,l,h)}if(l||l===0){A+=l}A+='\n </div>\n </div>\n</div>\n\n<div id="';if(l=z.id){l=l.call(B,{hash:{},data:I})}else{l=B.id;l=typeof l===e?l.apply(B):l}A+=d(l)+'-datasets" class="history-datasets-list"></div>\n\n<div class="infomessagesmall" id="emptyHistoryMessage" style="display: none;">\n ';h={hash:{},inverse:w.noop,fn:w.program(32,x,I),data:I};if(l=z.local){l=l.call(B,h)}else{l=B.local;l=typeof l===e?l.apply(B):l}if(!z.local){l=c.call(B,l,h)}if(l||l===0){A+=l}A+="\n</div>";return A})})(); \ No newline at end of file diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed static/scripts/templates/compiled/template-history-historyPanel.js --- a/static/scripts/templates/compiled/template-history-historyPanel.js +++ b/static/scripts/templates/compiled/template-history-historyPanel.js @@ -184,7 +184,7 @@ function program28(depth0,data) { var buffer = "", stack1; - buffer += "\n <div id=\"message-container\">\n <div class=\""; + buffer += "\n <div class=\""; if (stack1 = helpers.status) { stack1 = stack1.call(depth0, {hash:{},data:data}); } else { stack1 = depth0.status; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } buffer += escapeExpression(stack1) @@ -192,7 +192,7 @@ if (stack1 = helpers.message) { stack1 = stack1.call(depth0, {hash:{},data:data}); } else { stack1 = depth0.message; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } buffer += escapeExpression(stack1) - + "</div>\n </div>\n "; + + "</div>\n "; return buffer; } @@ -228,10 +228,10 @@ buffer += "\n\n "; stack2 = helpers['if'].call(depth0, depth0.deleted, {hash:{},inverse:self.noop,fn:self.program(24, program24, data),data:data}); if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n\n "; + buffer += "\n\n <div id=\"message-container\">\n "; stack2 = helpers['if'].call(depth0, depth0.message, {hash:{},inverse:self.noop,fn:self.program(28, program28, data),data:data}); if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n\n <div id=\"quota-message-container\" style=\"display: none\">\n <div id=\"quota-message\" class=\"errormessage\">\n "; + buffer += "\n </div>\n\n <div id=\"quota-message-container\" style=\"display: none\">\n <div id=\"quota-message\" class=\"errormessage\">\n "; options = {hash:{},inverse:self.noop,fn:self.program(30, program30, data),data:data}; if (stack2 = helpers.local) { stack2 = stack2.call(depth0, options); } else { stack2 = depth0.local; stack2 = typeof stack2 === functionType ? stack2.apply(depth0) : stack2; } diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed static/scripts/templates/history-templates.html --- a/static/scripts/templates/history-templates.html +++ b/static/scripts/templates/history-templates.html @@ -62,11 +62,11 @@ {{#warningmessagesmall}}{{#local}}You are currently viewing a deleted history!{{/local}}{{/warningmessagesmall}} {{/if}} - {{#if message}} <div id="message-container"> + {{#if message}} <div class="{{status}}message">{{message}}</div> + {{/if}} </div> - {{/if}} <div id="quota-message-container" style="display: none"><div id="quota-message" class="errormessage"> diff -r 005ee724a360d56e6b243852ce70c27c3804ef6b -r cf2313ae788daca198be009c8c16ec4b27b551ed templates/webapps/galaxy/root/history.mako --- a/templates/webapps/galaxy/root/history.mako +++ b/templates/webapps/galaxy/root/history.mako @@ -221,28 +221,25 @@ )} <script type="text/javascript"> -function modalAsAlert( title, body, buttons ){ - alert( title + ':\n' + body ); -} - function galaxyPageSetUp(){ // moving global functions, objects into Galaxy namespace top.Galaxy = top.Galaxy || {}; - // bad idea from memleak standpoint? - top.Galaxy.mainWindow = top.Galaxy.mainWindow || top.frames.galaxy_main; - top.Galaxy.toolWindow = top.Galaxy.toolWindow || top.frames.galaxy_tools; - top.Galaxy.historyWindow = top.Galaxy.historyWindow || top.frames.galaxy_history; + if( top != window ){ + top.Galaxy.mainWindow = top.Galaxy.mainWindow || top.frames.galaxy_main; + top.Galaxy.toolWindow = top.Galaxy.toolWindow || top.frames.galaxy_tools; + top.Galaxy.historyWindow = top.Galaxy.historyWindow || top.frames.galaxy_history; + + top.Galaxy.$masthead = top.Galaxy.$masthead || $( top.document ).find( 'div#masthead' ); + top.Galaxy.$messagebox = top.Galaxy.$messagebox || $( top.document ).find( 'div#messagebox' ); + top.Galaxy.$leftPanel = top.Galaxy.$leftPanel || $( top.document ).find( 'div#left' ); + top.Galaxy.$centerPanel = top.Galaxy.$centerPanel || $( top.document ).find( 'div#center' ); + top.Galaxy.$rightPanel = top.Galaxy.$rightPanel || $( top.document ).find( 'div#right' ); - top.Galaxy.$masthead = top.Galaxy.$masthead || $( top.document ).find( 'div#masthead' ); - top.Galaxy.$messagebox = top.Galaxy.$messagebox || $( top.document ).find( 'div#messagebox' ); - top.Galaxy.$leftPanel = top.Galaxy.$leftPanel || $( top.document ).find( 'div#left' ); - top.Galaxy.$centerPanel = top.Galaxy.$centerPanel || $( top.document ).find( 'div#center' ); - top.Galaxy.$rightPanel = top.Galaxy.$rightPanel || $( top.document ).find( 'div#right' ); - - //modals - top.Galaxy.show_modal = top.show_modal || modalAsAlert; - top.Galaxy.hide_modal = top.hide_modal || function(){}; + //modals + top.Galaxy.show_modal = top.show_modal; + top.Galaxy.hide_modal = top.hide_modal; + } // other base functions @@ -297,7 +294,7 @@ historyJson.user = userJson; // create the history panel - var history = new History( historyJson, hdaJson ); + var history = new History( historyJson, hdaJson, ( debugging )?( console ):( null ) ); var historyPanel = new HistoryPanel({ model : history, urlTemplates : galaxy_paths.attributes, @@ -445,11 +442,10 @@ .warningmessagesmall { margin: 8px 0 0 0; } - #message-container { - margin: 8px 0 0 0; + #message-container div { } #message-container [class$="message"] { - margin: 0px; + margin: 8px 0 0 0; } /*---- history level */ 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.