mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Histories: move order parsing into managers; View multi: allow and pass ordering into bootstrapped histories, limit to 10; View multi, client: allow better collection setting and addition
This commit is contained in:
@@ -387,12 +387,16 @@ var HistoryCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).ext
|
||||
//logger : console,
|
||||
|
||||
urlRoot : ( window.galaxy_config? galaxy_config.root : '/' ) + 'api/histories',
|
||||
//url : function(){ return this.urlRoot; },
|
||||
url : function(){ return this.urlRoot; },
|
||||
|
||||
initialize : function( models, options ){
|
||||
options = options || {};
|
||||
this.log( 'HistoryCollection.initialize', arguments );
|
||||
|
||||
this.includeDeleted = options.includeDeleted || false;
|
||||
this.offset = options.offset;
|
||||
this.limit = options.limit;
|
||||
this.order = options.order;
|
||||
|
||||
//this.on( 'all', function(){
|
||||
// console.info( 'event:', arguments );
|
||||
@@ -401,6 +405,17 @@ var HistoryCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).ext
|
||||
this.setUpListeners();
|
||||
},
|
||||
|
||||
fetch : function( options ){
|
||||
options = options || {};
|
||||
if( !this.includeDeleted ){
|
||||
var data = options.data || {};
|
||||
data.q = 'deleted';
|
||||
data.qv = 'False';
|
||||
options.data = data;
|
||||
}
|
||||
Backbone.Collection.prototype.fetch.call( this, options );
|
||||
},
|
||||
|
||||
setUpListeners : function setUpListeners(){
|
||||
var collection = this;
|
||||
|
||||
@@ -414,7 +429,9 @@ var HistoryCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).ext
|
||||
|
||||
// listen for a history copy, adding it to the beginning of the collection
|
||||
this.on( 'copied', function( original, newData ){
|
||||
this.unshift( new History( newData, [] ) );
|
||||
var history = new History( newData, [] );
|
||||
this.unshift( history );
|
||||
this.trigger( 'new-current', history, this );
|
||||
});
|
||||
},
|
||||
|
||||
@@ -426,7 +443,7 @@ var HistoryCollection = Backbone.Collection.extend( BASE_MVC.LoggableMixin ).ext
|
||||
// new histories go in the front
|
||||
//TODO: (implicit ordering by update time...)
|
||||
collection.unshift( history );
|
||||
collection.trigger( 'new-current' );
|
||||
collection.trigger( 'new-current', history, this );
|
||||
});
|
||||
//TODO: move back to using history.save (via Deferred.then w/ set_as_current)
|
||||
},
|
||||
|
||||
@@ -411,12 +411,12 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
// --- set up models, sub-views, and listeners
|
||||
/** the original unfiltered and unordered collection of histories */
|
||||
this.collection = null;
|
||||
this.setCollection( options.histories || [] );
|
||||
|
||||
/** model id to column map */
|
||||
this.columnMap = {};
|
||||
//TODO: why create here?
|
||||
this.createColumns( options.columnOptions );
|
||||
/** model id to column map */
|
||||
this.columnOptions = options.columnOptions || {};
|
||||
|
||||
this.setCollection( options.histories );
|
||||
this.setUpListeners();
|
||||
},
|
||||
|
||||
@@ -471,14 +471,31 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
/** Set up a (new) history collection, sorting and adding listeners
|
||||
* @fires 'new-collection' when set with this view as the arg
|
||||
*/
|
||||
setCollection : function setCollection( models ){
|
||||
setCollection : function setCollection( collection ){
|
||||
this.stopListening( this.collection );
|
||||
|
||||
this.collection = collection || new HISTORY_MODEL.HistoryCollection();
|
||||
this.setUpCollectionListeners();
|
||||
|
||||
this.sortCollection( this.order, { silent: true });
|
||||
this.createColumns();
|
||||
// multipanel.addModels( collection, { silent: true });
|
||||
this.trigger( 'new-collection', this );
|
||||
return this;
|
||||
},
|
||||
|
||||
/** Set up a (new) history collection, sorting and adding listeners
|
||||
* @fires 'new-collection' when set with this view as the arg
|
||||
*/
|
||||
addModels : function setCollection( models, collection, options ){
|
||||
// options = options || {};
|
||||
var multipanel = this;
|
||||
multipanel.stopListening( multipanel.collection );
|
||||
multipanel.collection = models;
|
||||
multipanel.sortCollection( multipanel.order, { silent: true });
|
||||
multipanel.setUpCollectionListeners();
|
||||
multipanel.trigger( 'new-collection', multipanel );
|
||||
return multipanel;
|
||||
models = _.isArray( models )? models : [ models ];
|
||||
models.forEach( function( model ){
|
||||
multipanel.addColumn( model, false );
|
||||
});
|
||||
// render?
|
||||
return this;
|
||||
},
|
||||
|
||||
/** Set up listeners for the collection - handling: added histories, change of current, deletion, and sorting */
|
||||
@@ -486,13 +503,13 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
var multipanel = this,
|
||||
collection = multipanel.collection;
|
||||
multipanel.listenTo( collection, {
|
||||
// handle addition of histories, triggered by column copy and create new
|
||||
'add': multipanel.addAsCurrentColumn,
|
||||
'add': multipanel.addModels,
|
||||
// handle setting a history as current, triggered by history.setAsCurrent
|
||||
'set-as-current': multipanel.setCurrentHistory,
|
||||
// handle deleting a history (depends on whether panels is including deleted or not)
|
||||
'change:deleted change:purged': multipanel.handleDeletedHistory,
|
||||
|
||||
// handle addition of histories, triggered by column copy and create new
|
||||
'new-current': multipanel.addAsCurrentColumn,
|
||||
'sort' : function(){ multipanel.renderColumns( 0 ); }
|
||||
});
|
||||
},
|
||||
@@ -563,6 +580,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
this.collection.sort( options );
|
||||
return this.collection;
|
||||
},
|
||||
//TODO: to setOrder
|
||||
|
||||
/** create a new history and set it to current */
|
||||
create : function( ev ){
|
||||
@@ -571,11 +589,12 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
// ------------------------------------------------------------------------ columns
|
||||
/** create columns from collection */
|
||||
createColumns : function createColumns( columnOptions ){
|
||||
columnOptions = columnOptions || {};
|
||||
createColumns : function createColumns( models, columnOptions ){
|
||||
columnOptions = columnOptions || this.options.columnOptions;
|
||||
var multipanel = this;
|
||||
// clear column map
|
||||
this.columnMap = {};
|
||||
// TODO: make cummulative
|
||||
multipanel.columnMap = {};
|
||||
multipanel.collection.each( function( model, i ){
|
||||
var column = multipanel.createColumn( model, columnOptions );
|
||||
multipanel.columnMap[ model.id ] = column;
|
||||
@@ -595,36 +614,10 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return column;
|
||||
},
|
||||
|
||||
/** return array of Columns filtered by filters and sorted to match the collection
|
||||
* @param: filters Function[] array of filter fns
|
||||
*/
|
||||
sortedFilteredColumns : function( filters ){
|
||||
filters = filters || this.filters;
|
||||
if( !filters || !filters.length ){
|
||||
return this.sortedColumns();
|
||||
}
|
||||
var multipanel = this;
|
||||
return multipanel.sortedColumns().filter( function( column, index ){
|
||||
var filtered = column.currentHistory || _.every( filters.map( function( filter ){
|
||||
return filter.call( column );
|
||||
}));
|
||||
return filtered;
|
||||
});
|
||||
},
|
||||
|
||||
/** return array of Columns sorted to match the collection */
|
||||
sortedColumns : function(){
|
||||
var multipanel = this;
|
||||
var sorted = this.collection.map( function( history, index ){
|
||||
return multipanel.columnMap[ history.id ];
|
||||
});
|
||||
return sorted;
|
||||
},
|
||||
|
||||
/** add a new column for history and render all columns if render is true */
|
||||
addColumn : function add( history, render ){
|
||||
//this.debug( 'adding column for:', history );
|
||||
render = render !== undefined? render: true;
|
||||
render = render !== undefined? render : true;
|
||||
var newColumn = this.createColumn( history );
|
||||
this.columnMap[ history.id ] = newColumn;
|
||||
if( render ){
|
||||
@@ -634,7 +627,8 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
},
|
||||
|
||||
/** add a new column for history and make it the current history/column */
|
||||
addAsCurrentColumn : function add( history ){
|
||||
addAsCurrentColumn : function add( history, collection, options ){
|
||||
// console.debug( 'addAsCurrentColumn:', history, collection, options );
|
||||
//this.log( 'adding current column for:', history );
|
||||
var multipanel = this,
|
||||
newColumn = this.addColumn( history, false );
|
||||
@@ -674,7 +668,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
multipanel.listenTo( column, {
|
||||
//'all': function(){ console.info( 'column ' + column + ':', arguments ) },
|
||||
'in-view': multipanel.queueHdaFetch
|
||||
});
|
||||
});
|
||||
|
||||
multipanel.listenTo( column.panel, {
|
||||
//'all': function(){ console.info( 'panel ' + column.panel + ':', arguments ) },
|
||||
@@ -716,6 +710,32 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return Object.keys( this.columnMap ).length;
|
||||
},
|
||||
|
||||
/** return array of Columns filtered by filters and sorted to match the collection
|
||||
* @param: filters Function[] array of filter fns
|
||||
*/
|
||||
sortedFilteredColumns : function( filters ){
|
||||
filters = filters || this.filters;
|
||||
if( !filters || !filters.length ){
|
||||
return this.sortedColumns();
|
||||
}
|
||||
var multipanel = this;
|
||||
return multipanel.sortedColumns().filter( function( column, index ){
|
||||
var filtered = column.currentHistory || _.every( filters.map( function( filter ){
|
||||
return filter.call( column );
|
||||
}));
|
||||
return filtered;
|
||||
});
|
||||
},
|
||||
|
||||
/** return array of Columns sorted to match the collection */
|
||||
sortedColumns : function(){
|
||||
var multipanel = this;
|
||||
var sorted = this.collection.map( function( history, index ){
|
||||
return multipanel.columnMap[ history.id ];
|
||||
});
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------ render
|
||||
/** Render this view, columns, and set up view plugins */
|
||||
render : function render( speed ){
|
||||
@@ -969,7 +989,9 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
// when scrolling - check for histories now in view: they will fire 'in-view' and queueHdaLoading if necc.
|
||||
//TODO:?? might be able to simplify and not use pub-sub
|
||||
var debouncedInView = _.debounce( function _debouncedInner(){
|
||||
multipanel.checkColumnsInView();
|
||||
var viewport = multipanel._viewport();
|
||||
multipanel.checkColumnsInView( viewport );
|
||||
multipanel.checkForEndOfScroll( viewport );
|
||||
}, 100 );
|
||||
this.$( '.middle' ).parent().scroll( debouncedInView );
|
||||
},
|
||||
@@ -994,15 +1016,20 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
/** Get the left and right pixel coords of the middle element */
|
||||
_viewport : function(){
|
||||
var viewLeft = this.$( '.middle' ).parent().offset().left;
|
||||
return { left: viewLeft, right: viewLeft + this.$( '.middle' ).parent().width() };
|
||||
var $outerMiddle = this.$( '.middle' ).parent(),
|
||||
viewLeft = $outerMiddle.offset().left,
|
||||
width = $outerMiddle.width();
|
||||
return {
|
||||
left : viewLeft,
|
||||
right : viewLeft + width
|
||||
};
|
||||
},
|
||||
|
||||
/** returns the columns currently in the viewport */
|
||||
columnsInView : function(){
|
||||
columnsInView : function( viewport ){
|
||||
//TODO: uses offset which is render intensive
|
||||
//TODO: 2N - could use arg filter (sortedFilteredColumns( filter )) instead
|
||||
var vp = this._viewport();
|
||||
var vp = viewport || this._viewport();
|
||||
return this.sortedFilteredColumns().filter( function( column ){
|
||||
return column.currentHistory || column.inView( vp.left, vp.right );
|
||||
});
|
||||
@@ -1017,6 +1044,17 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
});
|
||||
},
|
||||
|
||||
/** */
|
||||
checkForEndOfScroll : function( viewport ){
|
||||
viewport = viewport || this._viewport();
|
||||
var END_PADDING = 16,
|
||||
$middle = this.$( '.middle' ),
|
||||
scrollRight = $middle.parent().scrollLeft() + viewport.right;
|
||||
if( scrollRight >= ( $middle.width() - END_PADDING ) ){
|
||||
this.trigger( 'end-of-scroll' );
|
||||
}
|
||||
},
|
||||
|
||||
/** Show and enable the current columns drop target */
|
||||
currentColumnDropTargetOn : function(){
|
||||
var currentColumn = this.columnMap[ this.currentHistoryId ];
|
||||
|
||||
@@ -8,7 +8,7 @@ import pkg_resources
|
||||
pkg_resources.require( "Paste" )
|
||||
|
||||
pkg_resources.require( "SQLAlchemy >= 0.4" )
|
||||
from sqlalchemy import true, false, desc, asc
|
||||
from sqlalchemy import true, false
|
||||
|
||||
from galaxy import exceptions
|
||||
from galaxy.web import _future_expose_api as expose_api
|
||||
@@ -166,6 +166,13 @@ class HistoriesController( BaseAPIController, ExportsHistoryMixin, ImportsHistor
|
||||
# otherwise, do the default filter of removing the deleted histories
|
||||
return [ self.app.model.History.deleted == false() ]
|
||||
|
||||
def _parse_order_by( self, order_by_string ):
|
||||
ORDER_BY_SEP_CHAR = ','
|
||||
manager = self.history_manager
|
||||
if ORDER_BY_SEP_CHAR in order_by_string:
|
||||
return [ manager.parse_order_by( o ) for o in order_by_string.split( ORDER_BY_SEP_CHAR ) ]
|
||||
return manager.parse_order_by( order_by_string )
|
||||
|
||||
@expose_api_anonymous
|
||||
def show( self, trans, id, deleted='False', **kwd ):
|
||||
"""
|
||||
@@ -418,10 +425,3 @@ class HistoriesController( BaseAPIController, ExportsHistoryMixin, ImportsHistor
|
||||
raise exceptions.MessageException( "Export not available or not yet ready." )
|
||||
|
||||
return self.serve_ready_history_export( trans, jeha )
|
||||
|
||||
def _parse_order_by( self, order_by_string ):
|
||||
ORDER_BY_SEP_CHAR = ','
|
||||
manager = self.history_manager
|
||||
if ORDER_BY_SEP_CHAR in order_by_string:
|
||||
return [ manager.parse_order_by( o ) for o in order_by_string.split( ORDER_BY_SEP_CHAR ) ]
|
||||
return manager.parse_order_by( order_by_string )
|
||||
|
||||
@@ -628,7 +628,7 @@ class HistoryController( BaseUIController, SharableMixin, UsesAnnotations, UsesI
|
||||
show_deleted=show_deleted, show_hidden=show_hidden, use_panels=use_panels )
|
||||
|
||||
@web.expose
|
||||
def view_multiple( self, trans, include_deleted_histories=False, order='update' ):
|
||||
def view_multiple( self, trans, include_deleted_histories=False, limit=10, order='update' ):
|
||||
"""
|
||||
"""
|
||||
if not trans.user:
|
||||
@@ -641,7 +641,9 @@ class HistoryController( BaseUIController, SharableMixin, UsesAnnotations, UsesI
|
||||
|
||||
# TODO: allow specifying user_id for admin?
|
||||
include_deleted_histories = galaxy.util.string_as_bool( include_deleted_histories )
|
||||
order = order if order in ( 'update', 'name', 'size' ) else 'update'
|
||||
limit = limit if limit != 'None' else None
|
||||
order = order if order in ( 'update_time', 'name', 'size' ) else 'update_time'
|
||||
order_by = self.history_manager.parse_order_by( order )
|
||||
|
||||
deleted_filter = None
|
||||
if not include_deleted_histories:
|
||||
@@ -651,14 +653,15 @@ class HistoryController( BaseUIController, SharableMixin, UsesAnnotations, UsesI
|
||||
current_history_id = trans.security.encode_id( current_history.id ) if current_history else None
|
||||
|
||||
history_dictionaries = []
|
||||
for history in self.history_manager.by_user( trans.user, filters=deleted_filter ):
|
||||
histories = self.history_manager.by_user( trans.user, filters=deleted_filter, limit=limit, order_by=order_by )
|
||||
for history in histories:
|
||||
history_dictionary = self.history_serializer.serialize_to_view( history,
|
||||
view='detailed', user=trans.user, trans=trans )
|
||||
view='detailed', user=trans.user, trans=trans )
|
||||
history_dictionaries.append( history_dictionary )
|
||||
|
||||
return trans.fill_template_mako( "history/view_multiple.mako",
|
||||
current_history_id=current_history_id, histories=history_dictionaries,
|
||||
include_deleted_histories=include_deleted_histories, order=order )
|
||||
current_history_id=current_history_id, histories=history_dictionaries,
|
||||
include_deleted_histories=include_deleted_histories, order=order, limit=limit )
|
||||
|
||||
@web.expose
|
||||
def display_by_username_and_slug( self, trans, username, slug ):
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -29,17 +29,13 @@ define( 'app', function(){
|
||||
'mvc/history/multi-panel'
|
||||
], function( HISTORY_MODEL, MULTI_PANEL ){
|
||||
$(function(){
|
||||
window.historyJSONArray = bootstrapped.historyJSONArray;
|
||||
bootstrapped.histories.forEach( function( h ){
|
||||
console.debug( h.name, h.update_time, h.size );
|
||||
})
|
||||
histories = new HISTORY_MODEL.HistoryCollection( bootstrapped.histories, {
|
||||
includeDeleted : bootstrapped.includingDeleted
|
||||
});
|
||||
|
||||
var historyModels = [];
|
||||
historyJSONArray.forEach( function( historyJSON ){
|
||||
if( !historyJSON.purged ){
|
||||
historyModels.push( new HISTORY_MODEL.History( historyJSON ) );
|
||||
}
|
||||
});
|
||||
histories = new HISTORY_MODEL.HistoryCollection( historyModels, {
|
||||
includeDeleted : bootstrapped.includingDeleted
|
||||
});
|
||||
multipanel = new MULTI_PANEL.MultiPanelColumns({
|
||||
el : $( '#center' ).get(0),
|
||||
histories : histories,
|
||||
@@ -50,6 +46,6 @@ define( 'app', function(){
|
||||
});
|
||||
});
|
||||
</script>
|
||||
${ galaxy_client.load( app='app', historyJSONArray=histories,
|
||||
includingDeleted=include_deleted_histories, order=order ) }
|
||||
${ galaxy_client.load( app='app', histories=histories,
|
||||
includingDeleted=include_deleted_histories, order=order, limit=limit ) }
|
||||
</%def>
|
||||
|
||||
Reference in New Issue
Block a user