1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/5c58466a1bac/ Changeset: 5c58466a1bac User: carlfeberhard Date: 2014-07-31 18:05:26 Summary: Collections view drill-down: (still a work in progress) allow overlay of collection panel view over *current* history panel (not implemented for other history panels), refactoring of history/hda/collections; remove unused init_history_items; pack scripts Affected #: 35 files diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/galaxy.base.js --- a/static/scripts/galaxy.base.js +++ b/static/scripts/galaxy.base.js @@ -463,88 +463,6 @@ }); } -function init_history_items(historywrapper, noinit, nochanges) { - //NOTE: still needed for non-panel history views - - var action = function() { - // Load saved state and show as necessary - try { - var stored = $.jStorage.get("history_expand_state"); - if (stored) { - for (var id in stored) { - $("#" + id + " div.historyItemBody" ).show(); - } - } - } catch(err) { - // Something was wrong with values in storage, so clear storage - $.jStorage.deleteKey("history_expand_state"); - } - - // If Mozilla, hide scrollbars in hidden items since they cause animation bugs - if ( $.browser.mozilla ) { - $( "div.historyItemBody" ).each( function() { - if ( !$(this).is(":visible") ) { $(this).find( "pre.peek" ).css( "overflow", "hidden" ); } - }); - } - - historywrapper.each( function() { - var id = this.id, - body = $(this).children( "div.historyItemBody" ), - peek = body.find( "pre.peek" ); - $(this).find( ".historyItemTitleBar > .historyItemTitle" ).wrap( "<a href='javascript:void(0);'></a>" ) - .click( function() { - var prefs; - if ( body.is(":visible") ) { - // Hiding stuff here - if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ); } - body.slideUp( "fast" ); - - if (!nochanges) { // Ignore embedded item actions - // Save setting - prefs = $.jStorage.get("history_expand_state"); - if (prefs) { - delete prefs[id]; - $.jStorage.set("history_expand_state", prefs); - } - } - } else { - // Showing stuff here - body.slideDown( "fast", function() { - if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); } - }); - - if (!nochanges) { - // Save setting - prefs = $.jStorage.get("history_expand_state"); - if (!prefs) { prefs = {}; } - prefs[id] = true; - $.jStorage.set("history_expand_state", prefs); - } - } - return false; - }); - }); - - // Generate 'collapse all' link - $("#top-links > a.toggle").click( function() { - var prefs = $.jStorage.get("history_expand_state"); - if (!prefs) { prefs = {}; } - $( "div.historyItemBody:visible" ).each( function() { - if ( $.browser.mozilla ) { - $(this).find( "pre.peek" ).css( "overflow", "hidden" ); - } - $(this).slideUp( "fast" ); - if (prefs) { - delete prefs[$(this).parent().attr("id")]; - } - }); - $.jStorage.set("history_expand_state", prefs); - }).show(); - }; - - action(); -} - function commatize( number ) { number += ''; // Convert to string var rgx = /(\d+)(\d{3})/; diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/mvc/base-mvc.js --- a/static/scripts/mvc/base-mvc.js +++ b/static/scripts/mvc/base-mvc.js @@ -221,10 +221,146 @@ //============================================================================== +var ExpandableView = Backbone.View.extend( LoggableMixin ).extend({ +//TODO: Although the reasoning behind them is different, this shares a lot with HiddenUntilActivated above: combine them + //PRECONDITION: model must have method hasDetails + + initialize : function( attributes ){ + /** are the details of this view expanded/shown or not? */ + this.expanded = attributes.expanded || false; + this.log( '\t expanded:', this.expanded ); + }, + + // ........................................................................ render main +//TODO: for lack of a better place, add rendering logic here + fxSpeed : 'fast', + + /** Render this content, set up ui. + * @param {Integer} speed the speed of the render + * @fires rendered when rendered + * @fires rendered:ready when first rendered and NO running HDAs + * @returns {Object} this HDABaseView + */ + render : function( speed ){ + var $newRender = this._buildNewRender(); + this._queueNewRender( $newRender, speed ); + return this; + }, + + _buildNewRender : function(){ + // create a new render using a skeleton template, render title buttons, render body, and set up events, etc. + var $newRender = $( this.templates.skeleton( this.model.toJSON() ) ); + if( this.expanded ){ + $newRender.children( '.details' ).replaceWith( this._renderDetails() ); + } + this._setUpBehaviors( $newRender ); + return $newRender; + }, + + /** Fade out the old el, replace with new dom, then fade in. + * @param {Boolean} fade whether or not to fade out/in when re-rendering + * @fires rendered when rendered + * @fires rendered:ready when first rendered and NO running HDAs + */ + _queueNewRender : function( $newRender, speed ) { + speed = ( speed === undefined )?( this.fxSpeed ):( speed ); + var view = this; + + $( view ).queue( 'fx', [ + function( next ){ this.$el.fadeOut( speed, next ); }, + function( next ){ + view._swapNewRender( $newRender ); + next(); + }, + function( next ){ this.$el.fadeIn( speed, next ); }, + function( next ){ + this.trigger( 'rendered', view ); + next(); + } + ]); + }, + + _swapNewRender : function( $newRender ){ + return this.$el.empty().attr( 'class', this.className ).append( $newRender.children() ); + }, + + /** set up js behaviors, event handlers for elements within the given container + * @param {jQuery} $container jq object that contains the elements to process (defaults to this.$el) + */ + _setUpBehaviors : function( $container ){ + $container = $container || this.$el; + // set up canned behavior on children (bootstrap, popupmenus, editable_text, etc.) + make_popup_menus( $container ); + $container.find( '[title]' ).tooltip({ placement : 'bottom' }); + }, + + // ......................................................................... details + _renderDetails : function(){ + // override this + return null; + }, + + // ......................................................................... expansion/details + /** Show or hide the body/details of history content. + * @param {Boolean} expand if true, expand; if false, collapse + */ + toggleExpanded : function( expand ){ + expand = ( expand === undefined )?( !this.expanded ):( expand ); + if( expand ){ + this.expand(); + } else { + this.collapse(); + } + return this; + }, + + /** Render and show the full, detailed body of this view including extra data and controls. + * note: if the model does not have detailed data, fetch that data before showing the body + * @fires expanded when a body has been expanded + */ + expand : function(){ + var view = this; + + function _renderDetailsAndExpand(){ + view.$( '.details' ).replaceWith( view._renderDetails() ); + // needs to be set after the above or the slide will not show + view.expanded = true; + view.$( '.details' ).slideDown( view.fxSpeed, function(){ + view.trigger( 'expanded', view ); + }); + } +//TODO:?? remove + // fetch first if no details in the model + if( !view.model.hasDetails() ){ + // we need the change event on HDCA's for the elements to be processed - so silent == false + view.model.fetch().always( function( model ){ + _renderDetailsAndExpand(); + }); +//TODO: no error handling + } else { + _renderDetailsAndExpand(); + } + }, + + /** Hide the body/details of an HDA. + * @fires collapsed when a body has been collapsed + */ + collapse : function(){ + var view = this; + view.expanded = false; + this.$( '.details' ).slideUp( view.fxSpeed, function(){ + view.trigger( 'collapsed', view ); + }); + } + +}); + +//============================================================================== return { LoggableMixin : LoggableMixin, SessionStorageModel : SessionStorageModel, HiddenUntilActivatedViewMixin : HiddenUntilActivatedViewMixin, - mixin : mixin + mixin : mixin, + ExpandableView : ExpandableView }; }); diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/mvc/collection/collection-model.js --- a/static/scripts/mvc/collection/collection-model.js +++ b/static/scripts/mvc/collection/collection-model.js @@ -16,6 +16,7 @@ */ var DatasetCollectionElement = Backbone.Model.extend( BASE_MVC.LoggableMixin ).extend( /** @lends DatasetCollectionElement.prototype */{ + //TODO:?? this model may be unneccessary - it reflects the api structure, but... // if we munge the element with the element.object at parse, we can flatten the entire hierarchy @@ -24,7 +25,6 @@ //logger : console, defaults : { - id : null, model_class : 'DatasetCollectionElement', element_identifier : null, element_index : null, @@ -41,33 +41,48 @@ this.object = this._createObjectModel(); this.on( 'change:object', function(){ - //console.log( 'change:object' ); + //this.log( 'change:object' ); //TODO: prob. better to update the sub-model instead of re-creating it this.object = this._createObjectModel(); }); }, _createObjectModel : function(){ - //console.log( '_createObjectModel', this.get( 'object' ), this.object ); + //this.log( '_createObjectModel', this.get( 'object' ), this.object ); //TODO: same patterns as HDCA _createElementsModel - refactor to BASE_MVC.hasSubModel? if( _.isUndefined( this.object ) ){ this.object = null; } if( !this.get( 'object' ) ){ return this.object; } - var object = this.get( 'object' ); + var object = this.get( 'object' ), + ObjectClass = this._getObjectClass(); this.unset( 'object', { silent: true }); + this.object = new ObjectClass( object ); + return this.object; + }, + + _getObjectClass : function(){ this.debug( 'DCE, element_type:', this.get( 'element_type' ) ); switch( this.get( 'element_type' ) ){ case 'dataset_collection': - this.object = new DatasetCollection( object ); - break; + return DatasetCollection; case 'hda': - this.object = new HDA_MODEL.HistoryDatasetAssociation( object ); - break; - default: - throw new TypeError( 'Unknown element_type: ' + this.get( 'element_type' ) ); + return HDA_MODEL.HistoryDatasetAssociation; } - return this.object; + throw new TypeError( 'Unknown element_type: ' + this.get( 'element_type' ) ); + }, + + toJSON : function(){ + var json = Backbone.Model.prototype.toJSON.call( this ); + if( this.object ){ + json.object = this.object.toJSON(); + } + return json; + }, + + hasDetails : function(){ + return ( this.object !== null + && this.object.hasDetails() ); }, /** String representation. */ @@ -79,6 +94,52 @@ //============================================================================== +/** @class Backbone model for + * @borrows LoggableMixin#logger as #logger + * @borrows LoggableMixin#log as #log + * @constructs + */ +var HDADCE = DatasetCollectionElement.extend( +/** @lends DatasetCollectionElement.prototype */{ + + _getObjectClass : function(){ + return HDA_MODEL.HistoryDatasetAssociation; + }, + + /** String representation. */ + toString : function(){ + var objStr = ( this.object )?( '' + this.object ):( this.get( 'element_identifier' ) ); + return ([ 'HDADCE(', objStr, ')' ].join( '' )); + } +}); + + +//============================================================================== +/** @class Backbone model for + * @borrows LoggableMixin#logger as #logger + * @borrows LoggableMixin#log as #log + * @constructs + */ +var DCDCE = DatasetCollectionElement.extend( +/** @lends DatasetCollectionElement.prototype */{ + + _getObjectClass : function(){ + return DatasetCollection; + }, + + getVisibleContents : function(){ + return this.object? this.object.getVisibleContents(): []; + }, + + /** String representation. */ + toString : function(){ + var objStr = ( this.object )?( '' + this.object ):( this.get( 'element_identifier' ) ); + return ([ 'DCDCE(', objStr, ')' ].join( '' )); + } +}); + + +//============================================================================== /** @class Backbone collection for DCEs. * NOTE: used *only* in second level of list:paired collections (a * collection that contains collections) @@ -87,7 +148,7 @@ * @borrows LoggableMixin#log as #log * @constructs */ -var DatasetCollectionElementCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).extend( +var DCECollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).extend( /** @lends DatasetCollectionElementCollection.prototype */{ model: DatasetCollectionElement, @@ -112,6 +173,40 @@ //============================================================================== +/** @class Backbone collection for + * @borrows LoggableMixin#logger as #logger + * @borrows LoggableMixin#log as #log + * @constructs + */ +var HDADCECollection = DCECollection.extend( +/** @lends DatasetCollectionElementCollection.prototype */{ + model: HDADCE, + + /** String representation. */ + toString : function(){ + return ([ 'HDADCECollection(', this.length, ')' ].join( '' )); + } +}); + + +//============================================================================== +/** @class Backbone collection for + * @borrows LoggableMixin#logger as #logger + * @borrows LoggableMixin#log as #log + * @constructs + */ +var DCDCECollection = DCECollection.extend( +/** @lends DatasetCollectionElementCollection.prototype */{ + model: DCDCE, + + /** String representation. */ + toString : function(){ + return ([ 'DCDCECollection(', this.length, ')' ].join( '' )); + } +}); + + +//============================================================================== /** @class Backbone model for Dataset Collections. * DCs contain a bbone collection named 'elements' using the class found in * this.collectionClass (gen. DatasetCollectionElementCollection). DCs move @@ -133,7 +228,7 @@ collection_type : 'list' }, - collectionClass : DatasetCollectionElementCollection, + collectionClass : DCECollection, /** */ initialize : function( model, options ){ @@ -159,11 +254,25 @@ return this.elements; }, + toJSON : function(){ + var json = Backbone.Model.prototype.toJSON.call( this ); + if( this.elements ){ + json.elements = this.elements.toJSON(); + } + return json; + }, + hasDetails : function(){ //TODO: this is incorrect for (accidentally) empty collections + this.debug( 'hasDetails:', this.elements.length ); return this.elements.length !== 0; }, + getVisibleContents : function( filters ){ + //TODO: filters unused for now + return this.elements; + }, + // ........................................................................ misc /** String representation */ toString : function(){ @@ -174,37 +283,11 @@ //============================================================================== -/** @class Backbone collection for a collection of collection collections collecting correctly. */ -var DatasetCollectionCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).extend({ - - model: DatasetCollection, - - ///** logger used to record this.log messages, commonly set to console */ - //// comment this out to suppress log output - //logger : console, - - /** Set up. - * @see Backbone.Collection#initialize - */ - initialize : function( models, options ){ - options = options || {}; - this.info( 'DatasetCollectionCollection.initialize:', models, options ); - //this._setUpListeners(); - }, - - /** String representation. */ - toString : function(){ - return ([ 'DatasetCollectionCollection(', this.get( 'name' ), ')' ].join( '' )); - } -}); - - -//NOTE: the following prototypes may not be necessary - but I wanted to specifiy -// them (for now) and allow for the possibility of unique functionality -//============================================================================== var ListDatasetCollection = DatasetCollection.extend( /** @lends ListDatasetCollection.prototype */{ + collectionClass : HDADCECollection, + /** String representation. */ toString : function(){ return ([ 'ListDatasetCollection(', this.get( 'name' ), ')' ].join( '' )); @@ -213,7 +296,7 @@ //============================================================================== -var PairDatasetCollection = DatasetCollection.extend( +var PairDatasetCollection = ListDatasetCollection.extend( /** @lends ListDatasetCollection.prototype */{ /** String representation. */ @@ -227,6 +310,8 @@ var ListPairedDatasetCollection = DatasetCollection.extend( /** @lends ListDatasetCollection.prototype */{ + collectionClass : DCDCECollection, + // list:paired is the only collection that itself contains collections //collectionClass : DatasetCollectionCollection, @@ -239,10 +324,7 @@ //============================================================================== return { - DatasetCollectionElement : DatasetCollectionElement, - DatasetCollectionElementCollection : DatasetCollectionElementCollection, - DatasetCollection : DatasetCollection, - DatasetCollectionCollection : DatasetCollectionCollection, + //DatasetCollection : DatasetCollection, ListDatasetCollection : ListDatasetCollection, PairDatasetCollection : PairDatasetCollection, ListPairedDatasetCollection : ListPairedDatasetCollection diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/mvc/collection/collection-panel.js --- a/static/scripts/mvc/collection/collection-panel.js +++ b/static/scripts/mvc/collection/collection-panel.js @@ -1,13 +1,13 @@ define([ "mvc/collection/dataset-collection-base", - "mvc/dataset/hda-base", "mvc/base-mvc", "utils/localization" -], function( DC_BASE, HDA_BASE, BASE_MVC, _l ){ +], function( DC_BASE, BASE_MVC, _l ){ /* ============================================================================= TODO: ============================================================================= */ +// ============================================================================= /** @class non-editable, read-only View/Controller for a dataset collection. * @name CollectionPanel * @@ -18,17 +18,20 @@ */ var CollectionPanel = Backbone.View.extend( BASE_MVC.LoggableMixin ).extend( /** @lends CollectionPanel.prototype */{ + //MODEL is either a DatasetCollection (or subclass) or a DatasetCollectionElement (list of pairs) /** logger used to record this.log messages, commonly set to console */ // comment this out to suppress log output //logger : console, tagName : 'div', - className : 'history-panel', + className : 'dataset-collection-panel', /** (in ms) that jquery effects will use */ fxSpeed : 'fast', + DCEViewClass : DC_BASE.DCEBaseView, + // ......................................................................... SET UP /** Set up the view, set up storage, bind listeners to HistoryContents events * @param {Object} attributes optional settings for the panel @@ -42,7 +45,10 @@ this.log( this + '.initialize:', attributes ); this.hasUser = attributes.hasUser; - this.HDAViewClass = attributes.HDAViewClass || HDA_BASE.HDABaseView; + this.panelStack = []; + this.parentName = attributes.parentName; + + window.collectionPanel = this; }, /** create any event listeners for the panel @@ -74,7 +80,7 @@ this.log( 'render:', speed, callback ); // send a speed of 0 to have no fade in/out performed speed = ( speed === undefined )?( this.fxSpeed ):( speed ); - //console.debug( this + '.render, fxSpeed:', speed ); + //this.debug( this + '.render, fxSpeed:', speed ); var panel = this, $newRender; @@ -123,7 +129,13 @@ */ renderModel : function( ){ // tmp div for final swap in render - var $newRender = $( '<div/>' ).append( CollectionPanel.templates.panel( this.model.toJSON() ) ); +//TODO: ugh - reuse issue - refactor out + var type = this.model.get( 'collection_type' ) || this.model.object.get( 'collection_type' ), + json = _.extend( this.model.toJSON(), { + parentName : this.parentName, + type : type + }), + $newRender = $( '<div/>' ).append( this.templates.panel( json ) ); this._setUpBehaviours( $newRender ); this.renderContents( $newRender ); return $newRender; @@ -154,13 +166,15 @@ * @returns the number of visible hda views */ renderContents : function( $whereTo ){ - //console.debug( 'renderContents, elements:', this.model.elements ); + //this.debug( 'renderContents, elements:', this.model.elements ); $whereTo = $whereTo || this.$el; + this.warn( this + '.renderContents:, model:', this.model ); var panel = this, contentViews = {}, - visibleContents = this.model.elements || []; - //this.log( 'renderContents, visibleContents:', visibleContents, $whereTo ); + //NOTE: no filtering here + visibleContents = this.model.getVisibleContents(); + this.log( 'renderContents, visibleContents:', visibleContents, $whereTo ); this.$datasetsList( $whereTo ).empty(); if( visibleContents && visibleContents.length ){ @@ -168,66 +182,92 @@ var contentId = content.id, contentView = panel._createContentView( content ); contentViews[ contentId ] = contentView; - panel.attachContentView( contentView.render(), $whereTo ); + panel._attachContentView( contentView.render(), $whereTo ); }); } this.contentViews = contentViews; return this.contentViews; }, - /** - * @param {HistoryDatasetAssociation} content - */ + /** */ _createContentView : function( content ){ - //console.debug( 'content json:', JSON.stringify( content, null, ' ' ) ); + //this.debug( 'content json:', JSON.stringify( content, null, ' ' ) ); var contentView = null, ContentClass = this._getContentClass( content ); - //console.debug( 'content.object json:', JSON.stringify( content.object, null, ' ' ) ); - //console.debug( 'ContentClass:', ContentClass ); - //console.debug( 'content:', content ); - //console.debug( 'content.object:', content.object ); + //this.debug( 'content.object json:', JSON.stringify( content.object, null, ' ' ) ); + this.debug( 'ContentClass:', ContentClass ); + //this.debug( 'content:', content ); + this.debug( 'content.object:', content.object ); contentView = new ContentClass({ - model : content.object, + model : content, linkTarget : this.linkTarget, //draggable : true, hasUser : this.hasUser, logger : this.logger }); - //this._setUpHdaListeners( contentView ); + this.debug( 'contentView:', contentView ); + this._setUpContentListeners( contentView ); return contentView; }, + /** */ _getContentClass : function( content ){ + this.debug( this + '._getContentClass:', content ); switch( content.get( 'element_type' ) ){ case 'hda': - return this.HDAViewClass; + return this.DCEViewClass; case 'dataset_collection': - return DC_BASE.NestedDCEBaseView; + return this.DCEViewClass; } throw new TypeError( 'Unknown element type:', content.get( 'element_type' ) ); }, -// /** Set up HistoryPanel listeners for HDAView events. Currently binds: -// * HDAView#body-visible, HDAView#body-hidden to store expanded states -// * @param {HDAView} hdaView HDAView (base or edit) to listen to -// */ -// _setUpHdaListeners : function( hdaView ){ -// var panel = this; -// hdaView.on( 'error', function( model, xhr, options, msg ){ -// panel.errorHandler( model, xhr, options, msg ); -// }); -// // maintain a list of hdas whose bodies are expanded -// hdaView.on( 'body-expanded', function( model ){ -// panel.storage.addExpandedHda( model ); -// }); -// hdaView.on( 'body-collapsed', function( id ){ -// panel.storage.removeExpandedHda( id ); -// }); -// return this; -// }, + /** Set up listeners for content view events. In this override, handle collection expansion. */ + _setUpContentListeners : function( contentView ){ + var panel = this; + if( contentView.model.get( 'element_type' ) === 'dataset_collection' ){ + contentView.on( 'expanded', function( collectionView ){ + panel.info( 'expanded', collectionView ); + panel._addCollectionPanel( collectionView ); + }); + } + }, + + /** */ + _addCollectionPanel : function( collectionView ){ + var currPanel = this, + collectionModel = collectionView.model; + + this.debug( 'collection panel (stack), collectionView:', collectionView ); + this.debug( 'collection panel (stack), collectionModel:', collectionModel ); + var panel = new PairCollectionPanel({ + model : collectionModel, + parentName : this.model.get( 'name' ) + }); + currPanel.panelStack.push( panel ); + + currPanel.$( '.controls' ).add( '.datasets-list' ).hide(); + currPanel.$el.append( panel.$el ); + panel.on( 'close', function(){ + currPanel.render(); + collectionView.collapse(); + currPanel.panelStack.pop(); + }); + + //TODO: to hdca-model, hasDetails + if( !panel.model.hasDetails() ){ + var xhr = panel.model.fetch(); + xhr.done( function(){ + //TODO: (re-)render collection contents + panel.render(); + }); + } else { + panel.render(); + } + }, /** attach an contentView to the panel */ - attachContentView : function( contentView, $whereTo ){ + _attachContentView : function( contentView, $whereTo ){ $whereTo = $whereTo || this.$el; var $datasetsList = this.$datasetsList( $whereTo ); $datasetsList.append( contentView.$el ); @@ -237,90 +277,102 @@ // ------------------------------------------------------------------------ panel events /** event map */ events : { - 'click .panel-navigation-back' : 'close' + 'click .navigation .back' : 'close' }, /** */ close : function( event ){ this.$el.remove(); - this.trigger( 'collection-close' ); + this.trigger( 'close' ); }, // ........................................................................ misc - /** Return a string rep of the history */ + /** string rep */ toString : function(){ return 'CollectionPanel(' + (( this.model )?( this.model.get( 'name' )):( '' )) + ')'; } }); +//----------------------------------------------------------------------------- TEMPLATES +/** underscore templates */ +CollectionPanel.templates = CollectionPanel.prototype.templates = (function(){ +// use closure to run underscore template fn only once at module load + var _panelTemplate = _.template([ + '<div class="controls">', + '<div class="navigation">', + '<a class="back" href="javascript:void(0)">', + '<span class="fa fa-icon fa-angle-left"></span>', + _l( 'Back to ' ), '<%- collection.parentName %>', + '</a>', + '</div>', -//------------------------------------------------------------------------------ TEMPLATES -var _panelTemplate = [ - '<div class="history-controls">', - '<div class="panel-navigation">', - '<a class="panel-navigation-back" href="javascript:void(0)">', _l( 'Back' ), '</a>', + '<div class="title">', + '<div class="name"><%- collection.name || collection.element_identifier %></div>', + '<div class="subtitle">', +//TODO: remove logic from template + '<% if( collection.type === "list" ){ %>', + _l( 'a list of datasets' ), + '<% } else if( collection.type === "paired" ){ %>', + _l( 'a pair of datasets' ), + '<% } else if( collection.type === "list:paired" ){ %>', + _l( 'a list of paired datasets' ), + '<% } %>', + '</div>', + '</div>', '</div>', + // where the datasets/hdas are added + '<div class="datasets-list"></div>' + ].join( '' )); - '<div class="history-title">', - '<% if( collection.name ){ %>', - '<div class="history-name"><%= collection.hid %> : <%= collection.name %></div>', - '<% } %>', - '</div>', + // we override here in order to pass the localizer (_L) into the template scope - since we use it as a fn within + return { + panel : function( json ){ + return _panelTemplate({ _l: _l, collection: json }); + } + }; +}()); - //'<div class="history-subtitle clear">', - // '<% if( history.nice_size ){ %>', - // '<div class="history-size"><%= history.nice_size %></div>', - // '<% } %>', - // '<div class="history-secondary-actions"></div>', - //'</div>', - // - //'<% if( history.deleted ){ %>', - // '<div class="warningmessagesmall"><strong>', - // _l( 'You are currently viewing a deleted history!' ), - // '</strong></div>', - //'<% } %>', - // - //'<div class="message-container">', - // '<% if( history.message ){ %>', - // // should already be localized - // '<div class="<%= history.status %>message"><%= history.message %></div>', - // '<% } %>', - //'</div>', - // - //'<div class="quota-message errormessage">', - // _l( 'You are over your disk quota' ), '. ', - // _l( 'Tool execution is on hold until your disk usage drops below your allocated quota' ), '.', - //'</div>', - // - //'<div class="tags-display"></div>', - //'<div class="annotation-display"></div>', - //'<div class="history-dataset-actions">', - // '<div class="btn-group">', - // '<button class="history-select-all-datasets-btn btn btn-default"', - // 'data-mode="select">', _l( 'All' ), '</button>', - // '<button class="history-deselect-all-datasets-btn btn btn-default"', - // 'data-mode="select">', _l( 'None' ), '</button>', - // '</div>', - // '<button class="history-dataset-action-popup-btn btn btn-default">', - // _l( 'For all selected' ), '...</button>', - //'</div>', - '</div>', - // end history controls - // where the datasets/hdas are added - '<div class="datasets-list"></div>' +// ============================================================================= +/** @class non-editable, read-only View/Controller for a dataset collection. */ +var ListCollectionPanel = CollectionPanel.extend({ + DCEViewClass : DC_BASE.HDADCEBaseView, + // ........................................................................ misc + /** string rep */ + toString : function(){ + return 'ListCollectionPanel(' + (( this.model )?( this.model.get( 'name' )):( '' )) + ')'; + } +}); -].join( '' ); -CollectionPanel.templates = { - panel : function( JSON ){ - return _.template( _panelTemplate, JSON, { variable: 'collection' }); +// ============================================================================= +/** @class non-editable, read-only View/Controller for a dataset collection. */ +var PairCollectionPanel = ListCollectionPanel.extend({ + // ........................................................................ misc + /** string rep */ + toString : function(){ + return 'PairCollectionPanel(' + (( this.model )?( this.model.get( 'name' )):( '' )) + ')'; } -}; +}); + + +// ============================================================================= +/** @class non-editable, read-only View/Controller for a dataset collection. */ +var ListOfPairsCollectionPanel = CollectionPanel.extend({ + DCEViewClass : DC_BASE.DCDCEBaseView, + // ........................................................................ misc + /** string rep */ + toString : function(){ + return 'ListOfPairsCollectionPanel(' + (( this.model )?( this.model.get( 'name' )):( '' )) + ')'; + } +}); //============================================================================== return { - CollectionPanel: CollectionPanel + CollectionPanel : CollectionPanel, + ListCollectionPanel : ListCollectionPanel, + PairCollectionPanel : PairCollectionPanel, + ListOfPairsCollectionPanel : ListOfPairsCollectionPanel }; }); diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/mvc/collection/dataset-collection-base.js --- a/static/scripts/mvc/collection/dataset-collection-base.js +++ b/static/scripts/mvc/collection/dataset-collection-base.js @@ -29,7 +29,82 @@ this.log( 'DCBaseView.initialize:', attributes ); }, -//TODO: render has been removed from the inheritance chain here, so this won't work when called as is + // ........................................................................ render main + /** Render this content, set up ui. + * @param {Boolean} fade whether or not to fade out/in when re-rendering + * @fires rendered when rendered + * @fires rendered:ready when first rendered and NO running HDAs + * @returns {Object} this HDABaseView + */ + render : function( fade ){ + var $newRender = this._buildNewRender(); + this._queueNewRender( $newRender, fade ); + return this; + }, + + _buildNewRender : function(){ + // create a new render using a skeleton template, render title buttons, render body, and set up events, etc. + var $newRender = $( this.templates.skeleton( this.model.toJSON() ) ); + $newRender.find( '.primary-actions' ).append( this._render_primaryActions() ); + this._setUpBehaviors( $newRender ); + //this._renderSelectable( $newRender ); + return $newRender; + }, + + /** Fade out the old el, replace with new dom, then fade in. + * @param {Boolean} fade whether or not to fade out/in when re-rendering + * @fires rendered when rendered + * @fires rendered:ready when first rendered and NO running HDAs + */ + _queueNewRender : function( $newRender, fade ) { + fade = ( fade === undefined )?( true ):( fade ); + var view = this; + + // fade the old render out (if desired) + if( fade ){ + $( view ).queue( function( next ){ this.$el.fadeOut( view.fxSpeed, next ); }); + } + // empty the old render, swap in the new render contents + $( view ).queue( function( next ){ +//TODO:?? change to replaceWith pattern? + this.$el.empty().attr( 'class', view.className ).append( $newRender.children() ); + next(); + }); + // fade the new in + if( fade ){ + $( view ).queue( function( next ){ this.$el.fadeIn( view.fxSpeed, next ); }); + } + // trigger an event to know we're ready + $( view ).queue( function( next ){ + this.trigger( 'rendered', view ); + next(); + }); + }, + + /** set up js behaviors, event handlers for elements within the given container + * @param {jQuery} $container jq object that contains the elements to process (defaults to this.$el) + */ + _setUpBehaviors : function( $container ){ + $container = $container || this.$el; + make_popup_menus( $container ); + $container.find( '[title]' ).tooltip({ placement : 'bottom' }); + }, + + // ........................................................................ titlebar buttons + /** Render icon-button group for the common, most easily accessed actions. + * @returns {jQuery} rendered DOM or null + */ + _render_primaryActions : function(){ + // override + return []; + }, + + // ......................................................................... misc + events : { + 'click .title-bar' : function( event ){ + this.trigger( 'expanded', this ); + } + }, // ......................................................................... misc /** String representation */ @@ -40,37 +115,23 @@ }); /** templates for DCBaseViews (skeleton and body) */ -DCBaseView.templates = (function(){ +DCBaseView.templates = DCBaseView.prototype.templates = (function(){ // use closure to run underscore template fn only once at module load var skeletonTemplate = _.template([ - '<div class="dataset hda">', - '<div class="dataset-warnings">', - '<% if ( collection.deleted ) { %>', - '<div class="dataset-deleted-msg warningmessagesmall"><strong>', - _l( 'This collection has been deleted.' ), - '</div>', - '<% } %>', - '<% if ( !collection.visible ) { %>', - '<div class="dataset-hidden-msg warningmessagesmall"><strong>', - _l( 'This collection has been hidden.' ), - '</div>', - '<% } %>', - '</div>', - '<div class="dataset-primary-actions"></div>', - '<div class="dataset-title-bar clear" tabindex="0">', - '<span class="dataset-state-icon state-icon"></span>', - '<div class="dataset-title">', - '<span class="dataset-name"><%- collection.name %></span>', + '<div class="dataset-collection">', + '<div class="primary-actions"></div>', + '<div class="title-bar clear" tabindex="0">', + '<div class="title">', + '<span class="name"><%- collection.element_identifier %></span>', '</div>', '</div>', - '<div class="dataset-body"></div>', + '<div class="details"></div>', '</div>' ].join( '' )); var bodyTemplate = _.template([ - '<div class="dataset-body">', - '<div class="dataset-summary">', - _l( 'A dataset collection.' ), + '<div class="details">', + '<div class="summary">', _l( 'A dataset collection.' ), '</div>', '</div>' ].join( '' )); @@ -86,66 +147,312 @@ }()); -//TODO: unused -////============================================================================== -///** @class Read only view for DatasetCollectionElement. -// * @name DCEBaseView -// * -// * @augments Backbone.View -// * @borrows LoggableMixin#logger as #logger -// * @borrows LoggableMixin#log as #log -// * @constructs -// */ -//var NestedDCBaseView = DCBaseView.extend({ -// -// logger : console, -// -// /** */ -// initialize : function( attributes ){ -// if( attributes.logger ){ this.logger = this.model.logger = attributes.logger; } -// this.warn( this + '.initialize:', attributes ); -// DCBaseView.prototype.initialize.call( this, attributes ); -// }, -// -// _template : function(){ -// this.debug( this.model ); -// this.debug( this.model.toJSON() ); -// return NestedDCBaseView.templates.skeleton( this.model.toJSON() ); -// }, -// -// // ......................................................................... misc -// /** String representation */ -// toString : function(){ -// var modelString = ( this.model )?( this.model + '' ):( '(no model)' ); -// return 'NestedDCBaseView(' + modelString + ')'; -// } -//}); -// -////------------------------------------------------------------------------------ TEMPLATES -////TODO: possibly break these out into a sep. module -//NestedDCBaseView.templates = (function(){ -// var skeleton = _.template([ -// '<div class="dataset hda history-panel-hda state-ok">', -// '<div class="dataset-primary-actions"></div>', -// '<div class="dataset-title-bar clear" tabindex="0">', -// '<div class="dataset-title">', -// '<span class="dataset-name"><%= collection.name %></span>', -// '</div>', -// '</div>', -// '</div>' -// ].join( '' )); -// // we override here in order to pass the localizer (_L) into the template scope - since we use it as a fn within -// return { -// skeleton : function( json ){ -// return skeleton({ _l: _l, collection: json }); -// } -// }; -//}()); +//============================================================================== +/** @class Read only view for DatasetCollectionElement. + * @name DCBaseView + * + * @augments Backbone.View + * @borrows LoggableMixin#logger as #logger + * @borrows LoggableMixin#log as #log + * @constructs + */ +var DCEBaseView = BASE_MVC.ExpandableView.extend({ + + /** logger used to record this.log messages, commonly set to console */ + // comment this out to suppress log output + //logger : console, + + /** */ + className : "dataset-collection-element collection-dataset dataset", + /** */ + fxSpeed : 'fast', + + /** */ + initialize : function( attributes ){ + if( attributes.logger ){ this.logger = this.model.logger = attributes.logger; } + this.log( 'DCEBaseView.initialize:', attributes ); + BASE_MVC.ExpandableView.prototype.initialize.call( this, attributes ); + }, + + // ......................................................................... renderers + /** Render the enclosing div of the hda body and, if expanded, the html in the body + * @returns {jQuery} rendered DOM + */ + _renderDetails : function(){ + var $details = $( this.templates.details( this.model.toJSON() ) ); + this._setUpBehaviors( $details ); + // only render the body html if it's being shown + if( this.expanded ){ + $details.show(); + } + return $details; + }, + + // ......................................................................... events + events : { + // expand the body when the title is clicked or when in focus and space or enter is pressed + 'click .title-bar' : '_clickTitleBar', + 'keydown .title-bar' : '_keyDownTitleBar' + }, + + _clickTitleBar : function( event ){ + event.stopPropagation(); + this.toggleExpanded(); + }, + + _keyDownTitleBar : function( event ){ + // bail (with propagation) if keydown and not space or enter + var KEYCODE_SPACE = 32, KEYCODE_RETURN = 13; + if( event && ( event.type === 'keydown' ) + &&( event.keyCode === KEYCODE_SPACE || event.keyCode === KEYCODE_RETURN ) ){ + this.toggleExpanded(); + event.stopPropagation(); + return false; + } + return true; + }, + + // ......................................................................... misc + /** String representation */ + toString : function(){ + var modelString = ( this.model )?( this.model + '' ):( '(no model)' ); + return 'DCEBaseView(' + modelString + ')'; + } +}); + +/** templates for DCBaseViews (skeleton and body) */ +DCEBaseView.templates = DCEBaseView.prototype.templates = (function(){ +// use closure to run underscore template fn only once at module load + var skeletonTemplate = _.template([ + '<div class="dataset-collection-element collection-dataset dataset">', + '<div class="primary-actions"></div>', + '<div class="title-bar clear" tabindex="0">', + '<span class="state-icon"></span>', + '<div class="title">', + '<span class="name"><%- collection.element_identifier %></span>', + '</div>', + '</div>', + '<div class="details"></div>', + '</div>' + ].join( '' )); + + var bodyTemplate = _.template([ + '<div class="details">', + '<div class="summary">', + _l( 'A dataset collection element.' ), + '</div>', + '</div>' + ].join( '' )); + + // we override here in order to pass the localizer (_L) into the template scope - since we use it as a fn within + return { + skeleton : function( collectionJSON ){ + return skeletonTemplate({ _l: _l, collection: collectionJSON }); + }, + body : function( collectionJSON ){ + return bodyTemplate({ _l: _l, collection: collectionJSON }); + } + }; +}()); + + +//============================================================================== +/** @class Read only view for DatasetCollectionElement. + * @name DCBaseView + * + * @augments Backbone.View + * @borrows LoggableMixin#logger as #logger + * @borrows LoggableMixin#log as #log + * @constructs + */ +var HDADCEBaseView = DCEBaseView.extend({ + + /** logger used to record this.log messages, commonly set to console */ + // comment this out to suppress log output + //logger : console, + + // ......................................................................... misc + /** String representation */ + toString : function(){ + var modelString = ( this.model )?( this.model + '' ):( '(no model)' ); + return 'HDADCEBaseView(' + modelString + ')'; + } +}); + +/** templates for DCBaseViews (skeleton and body) */ +HDADCEBaseView.templates = HDADCEBaseView.prototype.templates = (function(){ +// use closure to run underscore template fn only once at module load + var skeletonTemplate = _.template([ + '<div class="dataset-collection-element dataset">', + '<div class="primary-actions"></div>', + '<div class="title-bar clear" tabindex="0">', + '<span class="state-icon"></span>', + '<div class="title">', +//TODO:?? re-check this: in pairs the name and identifier are different - but not otherwise + '<span class="name"><%- element.element_identifier %></span>', + '</div>', +// '<% if( element.element_identifier !== hda.name ){ %>', +// '<div class="subtitle"><%- element.element_identifier %></div>', +// '<% } %>', + '</div>', + '<div class="details"></div>', + '</div>' + ].join( '' )); + + var detailsTemplate = _.template([ + '<div class="details">', + '<div class="summary">', + '<% if( hda.misc_blurb ){ %>', + '<div class="blurb">', + '<span class="value"><%- hda.misc_blurb %></span>', + '</div>', + '<% } %>', + + '<% if( hda.data_type ){ %>', + '<div class="datatype">', + '<label class="prompt">', _l( 'format' ), '</label>', + '<span class="value"><%- hda.data_type %></span>', + '</div>', + '<% } %>', + + '<% if( hda.metadata_dbkey ){ %>', + '<div class="dbkey">', + '<label class="prompt">', _l( 'database' ), '</label>', + '<span class="value">', + '<%- hda.metadata_dbkey %>', + '</span>', + '</div>', + '<% } %>', + + '<% if( hda.misc_info ){ %>', + '<div class="info">', + '<span class="value"><%- hda.misc_info %></span>', + '</div>', + '<% } %>', + '</div>', + // end dataset-summary + + '<div class="actions clear">', + '<div class="left"></div>', + '<div class="right"></div>', + '</div>', + + '<% if( !hda.deleted ){ %>', + '<div class="tags-display"></div>', + '<div class="annotation-display"></div>', + + '<div class="display-applications">', + //TODO: the following two should be compacted + '<% _.each( hda.display_apps, function( app ){ %>', + '<div class="display-application">', + '<span class="display-application-location"><%- app.label %></span> ', + '<span class="display-application-links">', + '<% _.each( app.links, function( link ){ %>', + '<a target="<%= link.target %>" href="<%= link.href %>">', + '<% print( _l( link.text ) ); %>', + '</a> ', + '<% }); %>', + '</span>', + '</div>', + '<% }); %>', + + '<% _.each( hda.display_types, function( app ){ %>', + '<div class="display-application">', + '<span class="display-application-location"><%- app.label %></span> ', + '<span class="display-application-links">', + '<% _.each( app.links, function( link ){ %>', + '<a target="<%= link.target %>" href="<%= link.href %>">', + '<% print( _l( link.text ) ); %>', + '</a> ', + '<% }); %>', + '</span>', + '</div>', + '<% }); %>', + '</div>', + + '<% if( hda.peek ){ %>', + '<pre class="dataset-peek"><%= hda.peek %></pre>', + '<% } %>', + + '<% } %>', + // end if !deleted + + '</div>' + ].join( '' )); + + // we override here in order to pass the localizer (_L) into the template scope - since we use it as a fn within + return { + skeleton : function( json ){ + return skeletonTemplate({ _l: _l, element: json, hda: json.object }); + }, + details : function( json ){ + return detailsTemplate({ _l: _l, element: json, hda: json.object }); + } + }; +}()); + + +//============================================================================== +/** @class Read only view for DatasetCollectionElement. + * @name DCBaseView + * + * @augments Backbone.View + * @borrows LoggableMixin#logger as #logger + * @borrows LoggableMixin#log as #log + * @constructs + */ +var DCDCEBaseView = DCEBaseView.extend({ + + /** logger used to record this.log messages, commonly set to console */ + // comment this out to suppress log output + //logger : console, + + // ......................................................................... misc + /** String representation */ + expand : function(){ + this.trigger( 'expanded', this ); + }, + + // ......................................................................... misc + /** String representation */ + toString : function(){ + var modelString = ( this.model )?( this.model + '' ):( '(no model)' ); + return 'DCDCEBaseView(' + modelString + ')'; + } +}); + +/** templates for DCBaseViews (skeleton and body) */ +DCDCEBaseView.templates = DCDCEBaseView.prototype.templates = (function(){ +// use closure to run underscore template fn only once at module load + var skeletonTemplate = _.template([ + '<div class="dataset-collection-element dataset-collection">', + '<div class="primary-actions"></div>', + '<div class="title-bar clear" tabindex="0">', + '<span class="state-icon"></span>', + '<div class="title">', + '<span class="name"><%- element.element_identifier %></span>', + '</div>', +//TODO: currently correct, but needs logic if more nested types are added + '<div class="subtitle">', _l( 'paired datasets' ), '</div>', + '</div>', + '<div class="details"></div>', + '</div>' + ].join( '' )); + + // we override here in order to pass the localizer (_L) into the template scope - since we use it as a fn within + return { + skeleton : function( json ){ + return skeletonTemplate({ _l: _l, element: json, collection: json.object }); + } + }; +}()); //============================================================================== return { DCBaseView : DCBaseView, - //NestedDCBaseView : NestedDCBaseView, + DCEBaseView : DCEBaseView, + HDADCEBaseView : HDADCEBaseView, + DCDCEBaseView : DCDCEBaseView }; }); diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/mvc/collection/hdca-base.js --- a/static/scripts/mvc/collection/hdca-base.js +++ b/static/scripts/mvc/collection/hdca-base.js @@ -22,8 +22,9 @@ // comment this out to suppress log output //logger : console, +//TODO: not a dataset /** */ - className : "dataset hda history-panel-hda", + className : "dataset hdca history-panel-hda", /** */ initialize : function( attributes ){ @@ -52,6 +53,26 @@ return $body; }, + /** In this override, do not slide down or render any body/details - allow the container to handle it + * @fires expanded when a body has been expanded + */ + expand : function(){ + this.warn( this + '.expand' ); + var contentView = this; + + // fetch first if no details in the model + if( this.model.inReadyState() && !this.model.hasDetails() ){ + // we need the change event on HDCA's for the elements to be processed - so silent == false + this.model.fetch().always( function( model ){ + contentView.expanded = true; + contentView.trigger( 'expanded', contentView ); + }); + } else { + contentView.expanded = true; + contentView.trigger( 'expanded', contentView ); + } + }, + // ......................................................................... misc /** String representation */ toString : function(){ @@ -64,7 +85,8 @@ HDCABaseView.templates = HDCABaseView.prototype.templates = (function(){ // use closure to run underscore template fn only once at module load var skeletonTemplate = _.template([ - '<div class="dataset hda">', +//TODO: not a dataset + '<div class="dataset hdca">', '<div class="dataset-warnings">', '<% if ( collection.deleted ) { %>', '<div class="dataset-deleted-msg warningmessagesmall"><strong>', @@ -77,22 +99,32 @@ '</div>', '<% } %>', '</div>', - '<div class="dataset-selector"><span class="fa fa-2x fa-square-o"></span></div>', - '<div class="dataset-primary-actions"></div>', - '<div class="dataset-title-bar clear" tabindex="0">', - '<span class="dataset-state-icon state-icon"></span>', - '<div class="dataset-title">', - '<span class="hda-hid"><%- collection.hid %></span> ', - '<span class="dataset-name"><%- collection.name %></span>', + '<div class="selector"><span class="fa fa-2x fa-square-o"></span></div>', + '<div class="primary-actions"></div>', + '<div class="title-bar clear" tabindex="0">', + '<span class="state-icon"></span>', + '<div class="title">', + '<span class="hid"><%- collection.hid %></span> ', + '<span class="name"><%- collection.name %></span>', + '</div>', + '<div class="subtitle">', +//TODO: remove from template logic + '<% if( collection.collection_type === "list" ){ %>', + _l( 'a list of datasets' ), + '<% } else if( collection.collection_type === "paired" ){ %>', + _l( 'a pair of datasets' ), + '<% } else if( collection.collection_type === "list:paired" ){ %>', + _l( 'a list of paired datasets' ), + '<% } %>', '</div>', '</div>', - '<div class="dataset-body"></div>', + '<div class="details"></div>', '</div>' ].join( '' )); var bodyTemplate = _.template([ - '<div class="dataset-body">', - '<div class="dataset-summary">', + '<div class="details">', + '<div class="summary">', _l( 'A dataset collection.' ), '</div>' ].join( '' )); diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/mvc/collection/hdca-edit.js --- a/static/scripts/mvc/collection/hdca-edit.js +++ b/static/scripts/mvc/collection/hdca-edit.js @@ -23,13 +23,13 @@ // ......................................................................... edit attr, delete /** Render icon-button group for the common, most easily accessed actions. - * Overrides _render_titleButtons to include editing related buttons. + * Overrides _render_primaryActions to include editing related buttons. * @returns {jQuery} rendered DOM */ - _render_titleButtons : function(){ - this.log( this + '._render_titleButtons' ); + _render_primaryActions : function(){ + this.log( this + '._render_primaryActions' ); // render the display, edit attr and delete icon-buttons - return _super.prototype._render_titleButtons.call( this ) + return _super.prototype._render_primaryActions.call( this ) .concat([ this._render_deleteButton() ]); diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/mvc/collection/hdca-model.js --- a/static/scripts/mvc/collection/hdca-model.js +++ b/static/scripts/mvc/collection/hdca-model.js @@ -5,20 +5,15 @@ ], function( HISTORY_CONTENT, DC_MODEL, _l ){ //============================================================================== var hcontentMixin = HISTORY_CONTENT.HistoryContentMixin, -/** @class Backbone model for (generic) Dataset Collection within a History. - * @constructs - */ - HistoryDatasetCollection = DC_MODEL.DatasetCollection.extend( hcontentMixin ); + ListDC = DC_MODEL.ListDatasetCollection, + PairDC = DC_MODEL.PairDatasetCollection, + ListPairedDC = DC_MODEL.ListPairedDatasetCollection; - -//NOTE: the following prototypes may not be necessary - but I wanted to specifiy -// them (for now) and allow for the possibility of unique functionality //============================================================================== -var ListDC = DC_MODEL.ListDatasetCollection, /** @class Backbone model for List Dataset Collection within a History. * @constructs */ - HistoryListDatasetCollection = ListDC.extend( hcontentMixin ).extend( +var HistoryListDatasetCollection = ListDC.extend( hcontentMixin ).extend( /** @lends HistoryListDatasetCollection.prototype */{ initialize : function( model, options ){ @@ -36,11 +31,10 @@ //============================================================================== -var PairDC = DC_MODEL.PairDatasetCollection, /** @class Backbone model for Pair Dataset Collection within a History. * @constructs */ - HistoryPairDatasetCollection = PairDC.extend( hcontentMixin ).extend( +var HistoryPairDatasetCollection = PairDC.extend( hcontentMixin ).extend( /** @lends HistoryPairDatasetCollection.prototype */{ initialize : function( model, options ){ @@ -58,11 +52,10 @@ //============================================================================== -var ListPairedDC = DC_MODEL.ListPairedDatasetCollection, /** @class Backbone model for List of Pairs Dataset Collection within a History. * @constructs */ - HistoryListPairedDatasetCollection = ListPairedDC.extend( hcontentMixin ).extend( +var HistoryListPairedDatasetCollection = ListPairedDC.extend( hcontentMixin ).extend( /** @lends HistoryListPairedDatasetCollection.prototype */{ initialize : function( model, options ){ @@ -81,7 +74,6 @@ //============================================================================== return { - HistoryDatasetCollection : HistoryDatasetCollection, HistoryListDatasetCollection : HistoryListDatasetCollection, HistoryPairDatasetCollection : HistoryPairDatasetCollection, HistoryListPairedDatasetCollection : HistoryListPairedDatasetCollection diff -r 51e6a073c4b93a5df784e876abd17edffd3b0bbe -r 5c58466a1bacfe265f8dd92b1533f7b9aa9687b9 static/scripts/mvc/dataset/hda-base.js --- a/static/scripts/mvc/dataset/hda-base.js +++ b/static/scripts/mvc/dataset/hda-base.js @@ -23,7 +23,7 @@ //logger : console, tagName : "div", - className : "dataset hda history-panel-hda", + className : "dataset hda history-content", id : function(){ return 'hda-' + this.model.get( 'id' ); }, fxSpeed : 'fast', @@ -96,7 +96,7 @@ /** In this override, render the dataset display button * @returns {jQuery} rendered DOM */ - _render_titleButtons : function(){ + _render_primaryActions : function(){ // render just the display for read-only return [ this._render_displayButton() ]; }, @@ -115,7 +115,7 @@ var displayBtnData = { target : this.linkTarget, - classes : 'dataset-display' + classes : 'display-btn' }; // show a disabled display if the data's been purged @@ -181,7 +181,7 @@ if( _.isEmpty( meta_files ) ){ return $([ '<a href="' + urls.download + '" title="' + _l( 'Download' ) + '" ', - 'class="icon-btn dataset-download-btn">', + 'class="icon-btn download-btn">', '<span class="fa fa-floppy-o"></span>', '</a>' ].join( '' ) ); @@ -206,7 +206,7 @@ '<div class="icon-btn-group">', '<a href="' + urls.download + '" title="' + _l( 'Download' ) + '" ', - 'class="icon-btn dataset-download-btn">', + 'class="icon-btn download-btn">', '<span class="fa fa-floppy-o"></span>', // join these w/o whitespace or there'll be a gap when rendered '</a><a class="icon-btn popup" id="' + menuId + '">', @@ -256,7 +256,7 @@ primaryButtonArray = primaryButtonArray || []; var view = this, $body = $( HDABaseView.templates.body( _.extend( this.model.toJSON(), { body: body }))); - $body.find( '.dataset-actions .left' ).append( + $body.find( '.actions .left' ).append( _.map( primaryButtonArray, function( renderingFn ){ return renderingFn.call( view ); }) @@ -358,7 +358,7 @@ $body = $( HDABaseView.templates.body( this.model.toJSON() ) ), // prepend the download btn to the defaults and render btnRenderers = [ this._render_downloadButton ].concat( this.defaultPrimaryActionButtonRenderers ); - $body.find( '.dataset-actions .left' ).append( + $body.find( '.actions .left' ).append( _.map( btnRenderers, function( renderingFn ){ return renderingFn.call( view ); })); @@ -385,11 +385,11 @@ var hdaView = this; function _renderBodyAndExpand(){ - hdaView.$el.children( '.dataset-body' ).replaceWith( hdaView._renderBody() ); + hdaView.$el.children( '.details' ).replaceWith( hdaView._renderBody() ); //NOTE: needs to be set after the above or the slide will not show hdaView.expanded = true; - hdaView.$el.children( '.dataset-body' ).slideDown( hdaView.fxSpeed, function(){ - hdaView.trigger( 'expanded', hdaView.model ); + hdaView.$el.children( '.details' ).slideDown( hdaView.fxSpeed, function(){ + hdaView.trigger( 'expanded', hdaView ); }); } // fetch first if no details in the model @@ -429,24 +429,24 @@ //TODO: possibly break these out into a sep. module var skeletonTemplate = _.template([ '<div class="dataset hda">', - '<div class="dataset-warnings">', + '<div class="warnings">', // error during index fetch - show error on dataset '<% if( hda.error ){ %>', '<div class="errormessagesmall">', - _l( 'There was an error getting the data for this dataset' ), ':<%- hda.error %>', + _l( 'There was an error getting the data for this dataset' ), ': <%- hda.error %>', '</div>', '<% } %>', '<% if( hda.deleted ){ %>', // purged and deleted '<% if( hda.purged ){ %>', - '<div class="dataset-purged-msg warningmessagesmall"><strong>', + '<div class="purged-msg warningmessagesmall"><strong>', _l( 'This dataset has been deleted and removed from disk' ) + '.', '</strong></div>', // deleted not purged '<% } else { %>', - '<div class="dataset-deleted-msg warningmessagesmall"><strong>', + '<div class="deleted-msg warningmessagesmall"><strong>', _l( 'This dataset has been deleted' ) + '.', '</strong></div>', '<% } %>', @@ -454,61 +454,61 @@ // hidden '<% if( !hda.visible ){ %>', - '<div class="dataset-hidden-msg warningmessagesmall"><strong>', + '<div class="hidden-msg warningmessagesmall"><strong>', _l( 'This dataset has been hidden' ) + '.', '</strong></div>', '<% } %>', '</div>', // multi-select checkbox - '<div class="dataset-selector">', + '<div class="selector">', '<span class="fa fa-2x fa-square-o"></span>', '</div>', // space for title bar buttons - '<div class="dataset-primary-actions"></div>', + '<div class="primary-actions"></div>', // adding a tabindex here allows focusing the title bar and the use of keydown to expand the dataset display - '<div class="dataset-title-bar clear" tabindex="0">', - '<span class="dataset-state-icon state-icon"></span>', - '<div class="dataset-title">', + '<div class="title-bar clear" tabindex="0">', + '<span class="state-icon"></span>', + '<div class="title">', //TODO: remove whitespace and use margin-right - '<span class="hda-hid"><%- hda.hid %></span> ', - '<span class="dataset-name"><%- hda.name %></span>', + '<span class="hid"><%- hda.hid %></span> ', + '<span class="name"><%- hda.name %></span>', '</div>', '</div>', - '<div class="dataset-body"></div>', + '<div class="details"></div>', '</div>' ].join( '' )); var bodyTemplate = _.template([ -'<div class="dataset-body">', +'<div class="details">', '<% if( hda.body ){ %>', - '<div class="dataset-summary">', + '<div class="summary">', '<%= hda.body %>', '</div>', - '<div class="dataset-actions clear">', + '<div class="actions clear">', '<div class="left"></div>', '<div class="right"></div>', '</div>', '<% } else { %>', - '<div class="dataset-summary">', + '<div class="summary">', '<% if( hda.misc_blurb ){ %>', - '<div class="dataset-blurb">', + '<div class="blurb">', '<span class="value"><%- hda.misc_blurb %></span>', '</div>', '<% } %>', '<% if( hda.data_type ){ %>', - '<div class="dataset-datatype">', + '<div class="datatype">', '<label class="prompt">', _l( 'format' ), '</label>', '<span class="value"><%- hda.data_type %></span>', '</div>', '<% } %>', '<% if( hda.metadata_dbkey ){ %>', - '<div class="dataset-dbkey">', + '<div class="dbkey">', '<label class="prompt">', _l( 'database' ), '</label>', '<span class="value">', '<%- hda.metadata_dbkey %>', @@ -517,14 +517,14 @@ '<% } %>', '<% if( hda.misc_info ){ %>', - '<div class="dataset-info">', + '<div class="info">', '<span class="value"><%- hda.misc_info %></span>', '</div>', '<% } %>', '</div>', // end dataset-summary - '<div class="dataset-actions clear">', + '<div class="actions clear">', '<div class="left"></div>', '<div class="right"></div>', '</div>', @@ -533,7 +533,7 @@ '<div class="tags-display"></div>', '<div class="annotation-display"></div>', - '<div class="dataset-display-applications">', + '<div class="display-applications">', //TODO: the following two should be compacted '<% _.each( hda.display_apps, function( app ){ %>', '<div class="display-application">', This diff is so big that we needed to truncate the remainder. Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.