1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/e40fdd5f6e89/ changeset: e40fdd5f6e89 user: carlfeberhard date: 2012-12-04 20:43:49 summary: base/_panels.mako: IE console protection; history panel: move hda updater into history-model (from HDACollection), handle new hdas more gracefully, handle hidden hdas that move into the ready states. affected #: 8 files diff -r b175274d13e0be88c4504d51aa0f49d0802cc42b -r e40fdd5f6e8936f936f7118b0b9521f7379972ee static/scripts/mvc/dataset/hda-base.js --- a/static/scripts/mvc/dataset/hda-base.js +++ b/static/scripts/mvc/dataset/hda-base.js @@ -72,7 +72,13 @@ if( urlKey === 'meta_download' ){ urls[ urlKey ] = hdaView._renderMetaDownloadUrls( urlTemplateOrObj, modelJson ); } else { - urls[ urlKey ] = _.template( urlTemplateOrObj, modelJson ); + try { + urls[ urlKey ] = _.template( urlTemplateOrObj, modelJson ); + } catch( Error ){ + throw( hdaView + '._renderUrls error: ' + Error + + '\n rendering:' + urlTemplateOrObj + + '\n with ' + JSON.stringify( modelJson ) ); + } } } }); @@ -109,7 +115,6 @@ itemWrapper = $( '<div/>' ).attr( 'id', 'historyItem-' + id ), initialRender = ( this.$el.children().size() === 0 ); - //console.debug( this + '.render, initial?:', initialRender ); this.$el.attr( 'id', 'historyItemContainer-' + id ); itemWrapper @@ -362,7 +367,7 @@ break; default: //??: no body? - body.append( $( '<div>Error: unknown dataset state "' + state + '".</div>' ) ); + body.append( $( '<div>Error: unknown dataset state "' + this.model.get( 'state' ) + '".</div>' ) ); } body.append( '<div style="clear: both"></div>' ); @@ -520,6 +525,11 @@ } }, + + remove : function(){ + + }, + // ......................................................................... MISC toString : function(){ var modelString = ( this.model )?( this.model + '' ):( '(no model)' ); diff -r b175274d13e0be88c4504d51aa0f49d0802cc42b -r e40fdd5f6e8936f936f7118b0b9521f7379972ee static/scripts/mvc/dataset/hda-edit.js --- a/static/scripts/mvc/dataset/hda-edit.js +++ b/static/scripts/mvc/dataset/hda-edit.js @@ -193,7 +193,6 @@ if( !( this.model.hasData() ) || !( visualizations && visualizations.length ) || !( visualization_url ) ){ - //console.warn( 'NOT rendering visualization icon' ) this.visualizationsButton = null; return null; } diff -r b175274d13e0be88c4504d51aa0f49d0802cc42b -r e40fdd5f6e8936f936f7118b0b9521f7379972ee static/scripts/mvc/dataset/hda-model.js --- a/static/scripts/mvc/dataset/hda-model.js +++ b/static/scripts/mvc/dataset/hda-model.js @@ -32,13 +32,14 @@ // ---whereas these are Dataset related/inherited id : null, - name : '', + name : '(unnamed dataset)', // one of HistoryDatasetAssociation.STATES - state : '', + state : 'ok', // sniffed datatype (sam, tabular, bed, etc.) data_type : null, // size in bytes file_size : 0, + file_ext : '', // array of associated file types (eg. [ 'bam_index', ... ]) meta_files : [], @@ -48,10 +49,10 @@ deleted : false, purged : false, - // aka. !hidden + // aka. !hidden (start hidden) visible : false, // based on trans.user (is_admin or security_agent.can_access_dataset( <user_roles>, hda.dataset )) - accessible : false + accessible : true }, /** fetch location of this history in the api */ @@ -59,6 +60,7 @@ url : function(){ //TODO: get this via url router return 'api/histories/' + this.get( 'history_id' ) + '/contents/' + this.get( 'id' ); + //TODO: this breaks on save() }, /** Set up the model, determine if accessible, bind listeners @@ -222,6 +224,34 @@ return this.map( function( item ){ return item.id; }); }, + /** If the given hid is in the collection, return it's index. If not, return the insertion point it would need. + * NOTE: assumes hids are unique and valid + * @param {Int} hid the hid to find or create. If hid is 0, null, undefined: return the last hid + 1 + * @returns the collection index of the existing hda or an insertion point if it doesn't exist + */ + hidToCollectionIndex : function( hid ){ + // if the hid is 0, null, undefined: assume a request for a new hid (return the last index) + if( !hid ){ + return this.models.length; + } + + var endingIndex = this.models.length - 1; + //TODO: prob. more efficient to cycle backwards through these (assuming ordered by hid) + for( var i=endingIndex; i>=0; i-- ){ + var hdaHid = this.at( i ).get( 'hid' ); + //this.log( i, 'hdaHid:', hdaHid ); + if( hdaHid == hid ){ + //this.log( '\t match:', hdaHid, hid, ' returning:', i ); + return i; + } + if( hdaHid < hid ){ + //this.log( '\t past it, returning:', ( i + 1 ) ); + return i + 1; + } + } + return null; + }, + /** Get every 'shown' hda in this collection based on show_deleted/hidden * @param {Boolean} show_deleted are we showing deleted hdas? * @param {Boolean} show_hidden are we showing hidden hdas? @@ -263,24 +293,31 @@ }, /** Update (fetch) the data of the hdas with the given ids. + * @param {String} historyId the id of the history containing this collection * @param {String[]} ids an array of hda ids to update + * @returns {HistoryDatasetAssociation[]} hda models that were updated * @see HistoryDatasetAssociation#fetch */ update : function( ids ){ this.log( this + 'update:', ids ); - if( !( ids && ids.length ) ){ return; } + if( !( ids && ids.length ) ){ return []; } - var collection = this; + var collection = this, + updatedHdas = null; _.each( ids, function( id, index ){ - var historyItem = collection.get( id ); - historyItem.fetch(); + var hda = collection.get( id ); + if( hda ){ + hda.fetch(); + updatedHdas.push( hda ); + } }); + return updatedHdas; }, /** String representation. */ toString : function(){ - return ( 'HDACollection(' + this.ids().join(',') + ')' ); + return ( 'HDACollection()' ); } }); diff -r b175274d13e0be88c4504d51aa0f49d0802cc42b -r e40fdd5f6e8936f936f7118b0b9521f7379972ee static/scripts/mvc/history/history-model.js --- a/static/scripts/mvc/history/history-model.js +++ b/static/scripts/mvc/history/history-model.js @@ -88,8 +88,6 @@ history.fetch() ).then( function( userResponse, historyResponse ){ - //console.warn( 'fetched user: ', userResponse[0] ); - //console.warn( 'fetched history: ', historyResponse[0] ); history.attributes.user = userResponse[0]; //? meh. history.trigger( 'loaded:user', userResponse[0] ); @@ -102,7 +100,6 @@ // reset the collection to the hdas returned })).success( function( hdas ){ - //console.warn( 'fetched hdas', hdas ); history.hdas.reset( hdas ); history.checkForUpdates(); @@ -167,7 +164,7 @@ // send the changed ids (if any) to dataset collection to have them fetch their own model changes if( changedIds.length ){ - history.hdas.update( changedIds ); + history.updateHdas( changedIds ); } // set up to keep pulling if this history in run/queue state @@ -176,7 +173,7 @@ || ( history.get( 'state' ) === HistoryDatasetAssociation.STATES.QUEUED ) ){ setTimeout( function(){ history.stateUpdater(); - }, 4000 ); + }, History.UPDATE_DELAY ); // otherwise, we're now in a 'ready' state (no hdas running) } else { @@ -187,14 +184,70 @@ // if not interruption by iframe reload //TODO: remove when iframes are removed if( !( ( xhr.readyState === 0 ) && ( xhr.status === 0 ) ) ){ - //if( console && console.warn ){ - // console.warn( 'Error getting history updates from the server:', xhr, status, error ); - //} alert( _l( 'Error getting history updates from the server.' ) + '\n' + error ); } }); }, + /** Update the models in the hdas collection that match the ids given by getting their data + * via the api/AJAX. If a model exists in the collection, set will be used with the new data. + * If it's not in the collection, addHdas will be used to create it. + * @param {String[]} hdaIds an array of the encoded ids of the hdas to get from the server. + */ + updateHdas : function( hdaIds ){ + //TODO:?? move to collection? still need proper url + var history = this; + jQuery.ajax({ + url : this.url() + '/contents?' + jQuery.param({ ids : hdaIds.join(',') }), + + error : function( xhr, status, error ){ + var msg = 'ERROR updating hdas from api history contents:'; + history.log( msg, hdaIds, xhr, status, error ); + alert( msg + hdaIds.join(',') ); + }, + + /** when the proper models for the requested ids are returned, + * either update existing or create new entries in the hdas collection + * @inner + */ + success : function( hdaDataList, status, xhr ){ + history.log( history + '.updateHdas, success:', hdaDataList, status, xhr ); + //TODO: compile new models to be added in one go + var hdasToAdd = []; + + _.each( hdaDataList, function( hdaData, index ){ + var existingModel = history.hdas.get( hdaData.id ); + // if this model exists already, update it + if( existingModel ){ + history.log( 'found existing model in list for id ' + hdaData.id + ', updating...:' ); + existingModel.set( hdaData ); + + // if this model is new and isn't in the hda collection, cache it to be created + } else { + history.log( 'NO existing model for id ' + hdaData.id + ', creating...:' ); + modelsToAdd.push( hdaData ); + } + }); + if( hdasToAdd.length ){ + history.addHdas( hdasToAdd ); + } + } + }); + }, + + /** Add multiple hda models to the hdas collection from an array of hda data. + */ + addHdas : function( hdaDataList ){ + //TODO: this is all probably easier if hdas is a relation + var history = this; + //TODO:?? what about hidden? deleted? + _.each( hdaDataList, function( hdaData, index ){ + var indexFromHid = history.hdas.hidToCollectionIndex( hdaData.hid ); + hdaData.history_id = history.get( 'id' ); + history.hdas.add( new HistoryDatasetAssociation( hdaData ), { at: indexFromHid }); + }); + }, + toString : function(){ var nameString = ( this.get( 'name' ) )? ( ',' + this.get( 'name' ) ) : ( '' ); @@ -202,6 +255,13 @@ } }); +//------------------------------------------------------------------------------ CLASS VARS +/** When the history has running hdas, + * this is the amount of time between update checks from the server + */ +History.UPDATE_DELAY = 4000; + + //============================================================================== /** @class A collection of histories (per user). * (stub) currently unused. diff -r b175274d13e0be88c4504d51aa0f49d0802cc42b -r e40fdd5f6e8936f936f7118b0b9521f7379972ee static/scripts/mvc/history/history-panel.js --- a/static/scripts/mvc/history/history-panel.js +++ b/static/scripts/mvc/history/history-panel.js @@ -160,6 +160,20 @@ 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 ); + + // if an a hidden hda is created (gen. by a workflow), moves thru the updater to the ready state, + // then: remove it from the collection if the panel is set to NOT show hidden datasets + this.model.hdas.bind( 'change:state', + function( hda, newState, changedList ){ + //TODO: magic string here - somehow use HDA.states + if( ( hda.inReadyState() ) + && ( !hda.get( 'visible' ) ) + && ( !this.storage.get( 'show_hidden' ) ) ){ + this.removeHda( hda ); + } + }, + this ); + //this.bind( 'all', function(){ // this.log( arguments ); //}, this ); @@ -178,6 +192,8 @@ * @see PersistantStorage */ _setUpWebStorage : function( initiallyExpanded, show_deleted, show_hidden ){ + //this.log( '_setUpWebStorage, initiallyExpanded:', initiallyExpanded, + // 'show_deleted:', show_deleted, 'show_hidden', show_hidden ); // data that needs to be persistant over page refreshes // (note the key function which uses the history id as well) @@ -197,7 +213,6 @@ // get the show_deleted/hidden settings giving priority to values passed in, // using web storage otherwise - //this.log( 'show_deleted:', show_deleted, 'show_hidden', show_hidden ); // if the page has specifically requested show_deleted/hidden, these will be either true or false // (as opposed to undefined, null) - and we give priority to that setting if( ( show_deleted === true ) || ( show_deleted === false ) ){ @@ -218,18 +233,31 @@ * @param {HistoryDatasetAssociation} hda hda to add to the collection */ add : function( hda ){ - //console.debug( 'add.' + this, hda ); - //TODO + //this.log( 'add.' + this, hda ); + //KISS: just re-render the entire thing when adding + this.render(); }, /** Event hander to respond when hdas are reset */ addAll : function(){ - //console.debug( 'addAll.' + this ); + //this.log( 'addAll.' + this ); // re render when all hdas are reset this.render(); }, + /** Remove a view from the panel and the assoc. model from the collection + * @param {HistoryDataAssociation} the hda to remove + */ + removeHda : function( hdaModel, callback ){ + var hdaView = this.hdaViews[ hdaModel.get( 'id' ) ]; + hdaView.$el.fadeOut( 'fast', function(){ + hdaView.$el.remove(); + if( callback ){ callback(); } + }); + this.model.hdas.remove( hdaModel ); + }, + // ......................................................................... RENDERING /** Render urls, historyPanel body, and hdas (if any are shown) * @see Backbone.View#render @@ -243,8 +271,6 @@ modelJson = this.model.toJSON(), initialRender = ( this.$el.children().size() === 0 ); - //console.debug( this + '.render, initialRender:', initialRender ); - // render the urls and add them to the model json modelJson.urls = this._renderUrls( modelJson ); @@ -466,7 +492,7 @@ } return false; }, - + // ......................................................................... MISC /** Return a string rep of the history */ diff -r b175274d13e0be88c4504d51aa0f49d0802cc42b -r e40fdd5f6e8936f936f7118b0b9521f7379972ee templates/base.mako --- a/templates/base.mako +++ b/templates/base.mako @@ -23,29 +23,39 @@ ## Default javascripts <%def name="javascripts()"> - ## <!--[if lt IE 7]> - ## <script type='text/javascript' src="/static/scripts/libs/IE/IE7.js"></script> - ## <![endif]--> - - ${h.js( - "libs/jquery/jquery", - "libs/json2", - "libs/bootstrap", - "galaxy.base", - "libs/underscore", - "libs/backbone/backbone", - "libs/backbone/backbone-relational", - "libs/handlebars.runtime", - "mvc/ui" - )} - - <script type="text/javascript"> - // Set up needed paths. - var galaxy_paths = new GalaxyPaths({ - root_path: '${h.url_for( "/" )}', - image_path: '${h.url_for( "/static/images" )}' - }); - </script> + ## <!--[if lt IE 7]> + ## <script type='text/javascript' src="/static/scripts/libs/IE/IE7.js"></script> + ## <![endif]--> + + ${h.js( + "libs/jquery/jquery", + "libs/json2", + "libs/bootstrap", + "galaxy.base", + "libs/underscore", + "libs/backbone/backbone", + "libs/backbone/backbone-relational", + "libs/handlebars.runtime", + "mvc/ui" + )} + + <script type="text/javascript"> + // console protection + window.console = window.console || { + log : function(){}, + debug : function(){}, + info : function(){}, + warn : function(){}, + error : function(){}, + assert : function(){}, + }; + + // Set up needed paths. + var galaxy_paths = new GalaxyPaths({ + root_path: '${h.url_for( "/" )}', + image_path: '${h.url_for( "/static/images" )}' + }); + </script></%def> ## Additional metas can be defined by templates inheriting from this one. diff -r b175274d13e0be88c4504d51aa0f49d0802cc42b -r e40fdd5f6e8936f936f7118b0b9521f7379972ee templates/base/base_panels.mako --- a/templates/base/base_panels.mako +++ b/templates/base/base_panels.mako @@ -60,6 +60,16 @@ 'galaxy.base' )} <script type="text/javascript"> + // console protection + window.console = window.console || { + log : function(){}, + debug : function(){}, + info : function(){}, + warn : function(){}, + error : function(){}, + assert : function(){}, + }; + // Set up needed paths. var galaxy_paths = new GalaxyPaths({ root_path: '${h.url_for( "/" )}', diff -r b175274d13e0be88c4504d51aa0f49d0802cc42b -r e40fdd5f6e8936f936f7118b0b9521f7379972ee templates/root/alternate_history.mako --- a/templates/root/alternate_history.mako +++ b/templates/root/alternate_history.mako @@ -297,14 +297,13 @@ // add needed controller urls to GalaxyPaths galaxy_paths.set( 'hda', ${get_hda_url_templates()} ); galaxy_paths.set( 'history', ${get_history_url_templates()} ); -//console.debug( 'galaxy_paths:', galaxy_paths ); $(function(){ galaxyPageSetUp(); Galaxy.historyFrame = window; // ostensibly, this is the App - //if( console && console.debug ){ + //if( window.console && console.debug ){ // //if( console.clear ){ console.clear(); } // console.pretty = function( o ){ $( '<pre/>' ).text( JSON.stringify( o, null, ' ' ) ).appendTo( 'body' ); } // top.storage = jQuery.jStorage @@ -315,9 +314,6 @@ var user = ${ get_current_user() }, history = ${ get_history( history.id ) }, hdas = ${ get_hdas( history.id, datasets ) }; - //console.debug( 'user:', user ); - //console.debug( 'history:', history ); - //console.debug( 'hdas:', hdas ); var currUser = new User( user ); if( !Galaxy.currUser ){ Galaxy.currUser = currUser; } 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.