mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
UI, history multi-view: simplify header UI, label current history, some clean up
This commit is contained in:
@@ -6,7 +6,6 @@ define([
|
||||
"ui/mode-button",
|
||||
"ui/search-input"
|
||||
], function( HISTORY_MODEL, HPANEL_EDIT, baseMVC, ajaxQueue ){
|
||||
window.HISTORY_MODEL = HISTORY_MODEL;
|
||||
//==============================================================================
|
||||
/** */
|
||||
function historyCopyDialog( history, options ){
|
||||
@@ -265,7 +264,7 @@ var HistoryPanelColumn = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return ( this.currentHistory )?
|
||||
[
|
||||
'<div class="pull-left">',
|
||||
'<button class="create-new btn btn-default">', _l( 'Create new' ), '</button> ',
|
||||
'<strong class="current-label">', _l( 'Current History' ), '</strong>',
|
||||
'</div>'
|
||||
].join( '' )
|
||||
:[
|
||||
@@ -328,6 +327,7 @@ var HistoryPanelColumn = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
//logger : console,
|
||||
className : 'multi-history-columns',
|
||||
|
||||
// ------------------------------------------------------------------------ set up
|
||||
/** Set up internals, history collection, and columns to display the history */
|
||||
@@ -366,9 +366,8 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
/** model id to column map */
|
||||
this.columnMap = {};
|
||||
//TODO: why create here?
|
||||
//TODO: why create here?
|
||||
this.createColumns( options.columnOptions );
|
||||
|
||||
this.setUpListeners();
|
||||
},
|
||||
|
||||
@@ -386,10 +385,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
var multipanel = this;
|
||||
multipanel.stopListening( multipanel.collection );
|
||||
multipanel.collection = models;
|
||||
//TODO: slow... esp. on start up
|
||||
//if( multipanel.order !== 'update' ){
|
||||
multipanel.sortCollection( multipanel.order, { silent: true });
|
||||
//}
|
||||
multipanel.sortCollection( multipanel.order, { silent: true });
|
||||
multipanel.setUpCollectionListeners();
|
||||
multipanel.trigger( 'new-collection', multipanel );
|
||||
return multipanel;
|
||||
@@ -408,11 +404,6 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
'change:deleted': multipanel.handleDeletedHistory,
|
||||
|
||||
'sort' : function(){ multipanel.renderColumns( 0 ); }
|
||||
|
||||
// debugging
|
||||
//'all' : function(){
|
||||
// console.info( 'collection:', arguments );
|
||||
//}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -430,11 +421,6 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
this.sortCollection();
|
||||
|
||||
////TODO: this actually means these render twice (1st from setCollection) - good enough for now
|
||||
//if( oldCurrentColumn ){ oldCurrentColumn.render().delegateEvents(); }
|
||||
//TODO:?? this occasionally causes race with hdaQueue
|
||||
//newCurrentColumn.panel.render( 'fast' ).delegateEvents();
|
||||
|
||||
multipanel._recalcFirstColumnHeight();
|
||||
return newCurrentColumn;
|
||||
},
|
||||
@@ -451,14 +437,14 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
// if it's the current column, create a new, empty history as the new current
|
||||
if( column.model.id === this.currentHistoryId ){
|
||||
//TODO: figuring out the order of async here is tricky - for now let the user handle the two step process
|
||||
//TODO: figuring out the order of async here is tricky
|
||||
// - for now let the user handle the two step process
|
||||
//multipanel.collection.create().done( function(){
|
||||
// if( !multipanel.collection.includeDeleted ){ multipanel.removeColumn( column, false ); }
|
||||
//});
|
||||
} else if( !multipanel.collection.includeDeleted ){
|
||||
multipanel.removeColumn( column );
|
||||
}
|
||||
//TODO: prob. be done better
|
||||
}
|
||||
},
|
||||
|
||||
@@ -475,13 +461,12 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
//TODO: we can use a 2 arg version and return 1/0/-1
|
||||
//this.collection.comparator = function( h1, h2 ){
|
||||
this.collection.comparator = function( h ){
|
||||
//TODO: this won't do reverse order well
|
||||
//TODO: this won't do reverse order well
|
||||
return [ h.id !== currentHistoryId, h.get( 'name' ).toLowerCase() ];
|
||||
};
|
||||
break;
|
||||
case 'size':
|
||||
this.collection.comparator = function( h ){
|
||||
//console.debug( 'name sort', arguments )
|
||||
return [ h.id !== currentHistoryId, h.get( 'size' ) ];
|
||||
};
|
||||
break;
|
||||
@@ -501,6 +486,8 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
order = 'update';
|
||||
}
|
||||
this.order = order;
|
||||
this.trigger( 'order:change', order, this );
|
||||
this.$( '.current-order' ).text( order );
|
||||
this.sortCollection();
|
||||
return this;
|
||||
},
|
||||
@@ -533,6 +520,9 @@ 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 ){
|
||||
@@ -547,6 +537,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
});
|
||||
},
|
||||
|
||||
/** return array of Columns sorted to match the collection */
|
||||
sortedColumns : function(){
|
||||
var multipanel = this;
|
||||
var sorted = this.collection.map( function( history, index ){
|
||||
@@ -555,9 +546,9 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
/** */
|
||||
/** add a new column for history and render all columns if render is true */
|
||||
addColumn : function add( history, render ){
|
||||
//console.debug( 'adding column for:', history );
|
||||
//this.debug( 'adding column for:', history );
|
||||
render = render !== undefined? render: true;
|
||||
var newColumn = this.createColumn( history );
|
||||
this.columnMap[ history.id ] = newColumn;
|
||||
@@ -567,9 +558,9 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return newColumn;
|
||||
},
|
||||
|
||||
/** */
|
||||
/** add a new column for history and make it the current history/column */
|
||||
addAsCurrentColumn : function add( history ){
|
||||
//console.log( 'adding current column for:', history );
|
||||
//this.log( 'adding current column for:', history );
|
||||
var multipanel = this,
|
||||
newColumn = this.addColumn( history, false );
|
||||
this.setCurrentHistory( history );
|
||||
@@ -579,7 +570,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return newColumn;
|
||||
},
|
||||
|
||||
/** */
|
||||
/** remove the given column, it's listeners, and optionally render */
|
||||
removeColumn : function remove( column, render ){
|
||||
render = render !== undefined? render : true;
|
||||
this.log( 'removeColumn', column );
|
||||
@@ -657,79 +648,17 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
var multipanel = this;
|
||||
|
||||
multipanel.log( multipanel + '.render' );
|
||||
multipanel.$el.html( multipanel.template( multipanel.options ) );
|
||||
//console.debug( multipanel.$( '.loading-overlay' ).fadeIn( 0 ) );
|
||||
multipanel.$el.html( multipanel.mainTemplate( multipanel ) );
|
||||
multipanel.renderColumns( speed );
|
||||
//console.debug( multipanel.$( '.loading-overlay' ).fadeOut( 'fast' ) );
|
||||
|
||||
// set the columns to full height allowed and set up behaviors for thie multipanel
|
||||
multipanel.setUpBehaviors();
|
||||
//TODO: wrong - has to wait for columns to render
|
||||
//TODO: wrong - has to wait for columns to render
|
||||
// - create a column listener that fires this when all columns are rendered
|
||||
multipanel.trigger( 'rendered', multipanel );
|
||||
return multipanel;
|
||||
},
|
||||
|
||||
/** Template - overall structure relies on flex-boxes and is 3 components: header, middle, footer */
|
||||
template : function template( options ){
|
||||
options = options || {};
|
||||
var html = [];
|
||||
if( this.options.headerHeight ){
|
||||
html = html.concat([
|
||||
// a loading overlay
|
||||
'<div class="loading-overlay flex-row"><div class="loading-overlay-message">loading...</div></div>',
|
||||
'<div class="header flex-column-container">',
|
||||
// page & history controls
|
||||
'<div class="header-control header-control-left flex-column">',
|
||||
'<button class="done btn btn-default">', _l( 'Done' ), '</button>',
|
||||
'<button class="include-deleted btn btn-default"></button>',
|
||||
'<div class="order btn-group">',
|
||||
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',
|
||||
_l( 'Order histories by' ) + '... <span class="caret"></span>',
|
||||
'</button>',
|
||||
'<ul class="dropdown-menu" role="menu">',
|
||||
'<li><a href="javascript:void(0);" class="order-update">',
|
||||
_l( 'Time of last update' ),
|
||||
'</a></li>',
|
||||
'<li><a href="javascript:void(0);" class="order-name">',
|
||||
_l( 'Name' ),
|
||||
'</a></li>',
|
||||
'<li><a href="javascript:void(0);" class="order-size">',
|
||||
_l( 'Size' ),
|
||||
'</a></li>',
|
||||
'</ul>',
|
||||
'</div>',
|
||||
'<div id="search-histories" class="header-search"></div>',
|
||||
'</div>',
|
||||
// feedback
|
||||
'<div class="header-control header-control-center flex-column">',
|
||||
'<div class="header-info">',
|
||||
'</div>',
|
||||
'</div>',
|
||||
// dataset controls
|
||||
'<div class="header-control header-control-right flex-column">',
|
||||
'<div id="search-datasets" class="header-search"></div>',
|
||||
'<button id="toggle-deleted" class="btn btn-default">',
|
||||
_l( 'Include deleted datasets' ),
|
||||
'</button>',
|
||||
'<button id="toggle-hidden" class="btn btn-default">',
|
||||
_l( 'Include hidden datasets' ),
|
||||
'</button>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
]);
|
||||
}
|
||||
|
||||
html = html.concat([
|
||||
// middle - where the columns go
|
||||
'<div class="outer-middle flex-row flex-row-container">',
|
||||
'<div class="middle flex-column-container flex-row"></div>',
|
||||
'</div>',
|
||||
// footer
|
||||
'<div class="footer flex-column-container">','</div>'
|
||||
]);
|
||||
return $( html.join( '' ) );
|
||||
},
|
||||
|
||||
/** Render the columns and panels */
|
||||
renderColumns : function renderColumns( speed ){
|
||||
speed = speed !== undefined? speed: this.fxSpeed;
|
||||
@@ -737,61 +666,21 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
// render columns and track the total number rendered, firing an event when all are rendered
|
||||
var multipanel = this,
|
||||
sortedAndFiltered = multipanel.sortedFilteredColumns();
|
||||
//console.log( '\t columnMapLength:', this.columnMapLength(), this.columnMap );
|
||||
//this.log( '\t sortedAndFiltered:', sortedAndFiltered );
|
||||
|
||||
// set up width based on collection size
|
||||
//console.debug( '(render) width before:', multipanel.$( '.middle' ).width() )
|
||||
multipanel.$( '.middle' ).width( sortedAndFiltered.length
|
||||
//TODO: magic number 16 === the amount that safely prevents stacking of columns when adding a new one
|
||||
* ( this.options.columnWidth + this.options.columnGap ) + this.options.columnGap + 16 );
|
||||
//console.debug( '(render) width now:', multipanel.$( '.middle' ).width() )
|
||||
|
||||
//console.debug( 'sortedAndFiltered:', sortedAndFiltered )
|
||||
//multipanel.$( '.middle' ).empty();
|
||||
|
||||
// this.$( '.middle' ).html( sortedAndFiltered.map( function( column, i ){
|
||||
// return column.$el.hide();
|
||||
// }));
|
||||
// sortedAndFiltered.forEach( function( column, i ){
|
||||
////console.debug( 'rendering:', column, i )
|
||||
// //multipanel.$( '.middle' ).append( column.$el.hide() );
|
||||
// column.delegateEvents();
|
||||
////TODO: current column in-view is never fired
|
||||
// multipanel.renderColumn( column, speed ).$el.show();
|
||||
// });
|
||||
|
||||
// var $els = sortedAndFiltered.map( function( column, i ){
|
||||
////console.debug( 'rendering:', column, i )
|
||||
// multipanel.renderColumn( column, speed );
|
||||
// return column.$el;
|
||||
// });
|
||||
//// this breaks the event map
|
||||
// //this.$( '.middle' ).html( $els );
|
||||
//// this doesn't
|
||||
// this.$( '.middle' ).append( $els );
|
||||
|
||||
var $middle = multipanel.$( '.middle' );
|
||||
$middle.empty();
|
||||
sortedAndFiltered.forEach( function( column, i ){
|
||||
//console.debug( 'rendering:', column, i, column.panel )
|
||||
|
||||
column.$el.appendTo( $middle );
|
||||
column.delegateEvents();
|
||||
multipanel.renderColumn( column, speed );
|
||||
|
||||
//column.$el.hide().appendTo( $middle );
|
||||
//multipanel.renderColumn( column, speed );
|
||||
// //.panel.on( 'all', function(){
|
||||
// // console.debug( 'column rendered:', arguments );
|
||||
// //});
|
||||
//// this won't work until we checkColumnsInView after the render
|
||||
////column.$el.fadeIn( speed );
|
||||
//column.$el.show();
|
||||
});
|
||||
//this.log( 'column rendering done' );
|
||||
|
||||
//TODO: event columns-rendered
|
||||
//TODO: event columns-rendered
|
||||
|
||||
if( this.searchFor && sortedAndFiltered.length <= 1 ){
|
||||
} else {
|
||||
@@ -808,15 +697,11 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
renderColumn : function( column, speed ){
|
||||
speed = speed !== undefined? speed: this.fxSpeed;
|
||||
return column.render( speed );
|
||||
//TODO: causes weirdness
|
||||
//return _.delay( function(){
|
||||
// return column.render( speed );
|
||||
//}, 0 );
|
||||
},
|
||||
|
||||
//TODO: combine the following two more sensibly
|
||||
//TODO: could have HistoryContents.haveDetails return false
|
||||
// if column.model.contents.length === 0 && !column.model.get( 'empty' ) then just check that
|
||||
//TODO: combine the following two more sensibly
|
||||
//TODO: could have HistoryContents.haveDetails return false
|
||||
// if column.model.contents.length === 0 && !column.model.get( 'empty' ) then just check that
|
||||
/** Get the *summary* contents of a column's history (and details on any expanded contents),
|
||||
* queueing the ajax call and using a named queue to prevent the call being sent twice
|
||||
*/
|
||||
@@ -874,14 +759,17 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
events : {
|
||||
// will move to the server root (gen. Analyze data)
|
||||
'click .done.btn' : 'close',
|
||||
//TODO:?? could just go back - but that's not always correct/desired behav.
|
||||
//'click .done.btn' : function(){ window.history.back(); },
|
||||
// creates a new empty history and makes it current
|
||||
'click .create-new.btn' : 'create',
|
||||
|
||||
'click #include-deleted' : '_clickToggleDeletedHistories',
|
||||
// these change the collection and column sort order
|
||||
'click .order .order-update' : function( e ){ this.setOrder( 'update' ); },
|
||||
'click .order .order-name' : function( e ){ this.setOrder( 'name' ); },
|
||||
'click .order .order-size' : function( e ){ this.setOrder( 'size' ); }
|
||||
'click .order .order-size' : function( e ){ this.setOrder( 'size' ); },
|
||||
|
||||
'click #toggle-deleted' : '_clickToggleDeletedDatasets',
|
||||
'click #toggle-hidden' : '_clickToggleHiddenDatasets'
|
||||
|
||||
//'dragstart .list-item .title-bar' : function( e ){ console.debug( 'ok' ); }
|
||||
},
|
||||
@@ -897,37 +785,48 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
window.location = destination;
|
||||
},
|
||||
|
||||
_clickToggleDeletedHistories : function( ev ){
|
||||
return this.toggleDeletedHistories( $( ev.currentTarget ).is( ':checked' ) );
|
||||
},
|
||||
/** Include deleted histories in the collection */
|
||||
includeDeletedHistories : function(){
|
||||
//TODO: better through API/limit+offset
|
||||
window.location += ( /\?/.test( window.location.toString() ) )?( '&' ):( '?' )
|
||||
+ 'include_deleted_histories=True';
|
||||
toggleDeletedHistories : function( show ){
|
||||
if( show ){
|
||||
window.location = Galaxy.options.root + 'history/view_multiple?include_deleted_histories=True';
|
||||
} else {
|
||||
window.location = Galaxy.options.root + 'history/view_multiple';
|
||||
}
|
||||
},
|
||||
|
||||
/** Show only non-deleted histories */
|
||||
excludeDeletedHistories : function(){
|
||||
//TODO: better through API/limit+offset
|
||||
window.location = window.location.toString().replace( /[&\?]include_deleted_histories=True/g, '' );
|
||||
_clickToggleDeletedDatasets : function( ev ){
|
||||
return this.toggleDeletedDatasets( $( ev.currentTarget ).is( ':checked' ) );
|
||||
},
|
||||
toggleDeletedDatasets : function( show ){
|
||||
show = show !== undefined? show : false;
|
||||
var multipanel = this;
|
||||
multipanel.sortedFilteredColumns().forEach( function( column, i ){
|
||||
_.delay( function(){
|
||||
column.panel.toggleShowDeleted( show, false );
|
||||
}, i * 200 );
|
||||
});
|
||||
},
|
||||
|
||||
_clickToggleHiddenDatasets : function( ev ){
|
||||
return this.toggleHiddenDatasets( $( ev.currentTarget ).is( ':checked' ) );
|
||||
},
|
||||
toggleHiddenDatasets : function( show ){
|
||||
show = show !== undefined? show : false;
|
||||
var multipanel = this;
|
||||
multipanel.sortedFilteredColumns().forEach( function( column, i ){
|
||||
_.delay( function(){
|
||||
column.panel.toggleShowHidden( show, false );
|
||||
}, i * 200 );
|
||||
});
|
||||
},
|
||||
|
||||
/** Set up any view plugins */
|
||||
setUpBehaviors : function(){
|
||||
var multipanel = this;
|
||||
|
||||
//TODO: currently doesn't need to be a mode button
|
||||
// toggle button for include deleted
|
||||
multipanel.$( '.include-deleted' ).modeButton({
|
||||
initialMode : this.collection.includeDeleted? 'exclude' : 'include',
|
||||
switchModesOnClick : false,
|
||||
modes: [
|
||||
{ mode: 'include', html: _l( 'Include deleted histories' ),
|
||||
onclick: _.bind( multipanel.includeDeletedHistories, multipanel )
|
||||
},
|
||||
{ mode: 'exclude', html: _l( 'Exclude deleted histories' ),
|
||||
onclick: _.bind( multipanel.excludeDeletedHistories, multipanel )
|
||||
}
|
||||
]
|
||||
});
|
||||
multipanel._moreOptionsPopover();
|
||||
|
||||
// input to search histories
|
||||
multipanel.$( '#search-histories' ).searchInput({
|
||||
@@ -942,7 +841,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
},
|
||||
onclear : function( searchFor ){
|
||||
multipanel.searchFor = null;
|
||||
//TODO: remove specifically not just reset
|
||||
//TODO: remove specifically not just reset
|
||||
multipanel.filters = [];
|
||||
multipanel.renderColumns( 0 );
|
||||
}
|
||||
@@ -986,53 +885,25 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
}
|
||||
});
|
||||
|
||||
//TODO: each panel stores the hidden/deleted state - and that isn't reflected in the buttons
|
||||
// toggle button for showing deleted history contents
|
||||
multipanel.$( '#toggle-deleted' ).modeButton({
|
||||
initialMode : 'include',
|
||||
modes: [
|
||||
{ mode: 'exclude', html: _l( 'Exclude deleted datasets' ) },
|
||||
{ mode: 'include', html: _l( 'Include deleted datasets' ) }
|
||||
]
|
||||
}).click( function(){
|
||||
var show = $( this ).modeButton( 'getMode' ).mode === 'exclude';
|
||||
multipanel.sortedFilteredColumns().forEach( function( column, i ){
|
||||
_.delay( function(){
|
||||
column.panel.toggleShowDeleted( show, false );
|
||||
}, i * 200 );
|
||||
});
|
||||
});
|
||||
|
||||
// toggle button for showing hidden history contents
|
||||
multipanel.$( '#toggle-hidden' ).modeButton({
|
||||
initialMode : 'include',
|
||||
modes: [
|
||||
{ mode: 'exclude', html: _l( 'Exclude hidden datasets' ) },
|
||||
{ mode: 'include', html: _l( 'Include hidden datasets' ) }
|
||||
]
|
||||
}).click( function(){
|
||||
var show = $( this ).modeButton( 'getMode' ).mode === 'exclude';
|
||||
multipanel.sortedFilteredColumns().forEach( function( column, i ){
|
||||
_.delay( function(){
|
||||
column.panel.toggleShowHidden( show, false );
|
||||
}, i * 200 );
|
||||
});
|
||||
});
|
||||
|
||||
// resize first (fixed position) column on page resize
|
||||
$( window ).resize( function(){
|
||||
multipanel._recalcFirstColumnHeight();
|
||||
});
|
||||
|
||||
// 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
|
||||
//TODO:?? might be able to simplify and not use pub-sub
|
||||
var debouncedInView = _.debounce( _.bind( this.checkColumnsInView, this ), 100 );
|
||||
this.$( '.middle' ).parent().scroll( debouncedInView );
|
||||
},
|
||||
|
||||
///** Put the in-view columns then the other columns in a queue, rendering each one at a time */
|
||||
//panelRenderQueue : function( columns, fn, args, renderEventName ){
|
||||
//},
|
||||
_moreOptionsPopover : function(){
|
||||
return this.$( '.open-more-options.btn' ).popover({
|
||||
container : '.header',
|
||||
placement : 'bottom',
|
||||
html : true,
|
||||
content : $( this.optionsPopoverTemplate( this ) )
|
||||
});
|
||||
},
|
||||
|
||||
/** Adjust the height of the first, current column since flex-boxes won't work with fixed postiion elements */
|
||||
_recalcFirstColumnHeight : function(){
|
||||
@@ -1052,18 +923,17 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
/** returns the columns currently in the viewport */
|
||||
columnsInView : function(){
|
||||
//TODO: uses offset which is render intensive
|
||||
//TODO: 2N - could use arg filter (sortedFilteredColumns( filter )) instead
|
||||
//TODO: 2N - could use arg filter (sortedFilteredColumns( filter )) instead
|
||||
var vp = this._viewport();
|
||||
return this.sortedFilteredColumns().filter( function( column ){
|
||||
return column.currentHistory || column.inView( vp.left, vp.right );
|
||||
});
|
||||
},
|
||||
|
||||
//TODO: sortByInView - return cols in view, then others
|
||||
//TODO: sortByInView - return cols in view, then others
|
||||
/** trigger in-view from columns in-view */
|
||||
checkColumnsInView : function(){
|
||||
//TODO: assbackward
|
||||
//console.debug( 'checking columns in view', this.columnsInView() );
|
||||
//TODO: assbackward - don't fire from the column, fire from here and listen from here
|
||||
this.columnsInView().forEach( function( column ){
|
||||
column.trigger( 'in-view', column );
|
||||
});
|
||||
@@ -1073,7 +943,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
currentColumnDropTargetOn : function(){
|
||||
var currentColumn = this.columnMap[ this.currentHistoryId ];
|
||||
if( !currentColumn ){ return; }
|
||||
//TODO: fix this - shouldn't need monkeypatch
|
||||
//TODO: fix this - shouldn't need monkeypatch
|
||||
currentColumn.panel.dataDropped = function( data ){};
|
||||
currentColumn.panel.dropTargetOn();
|
||||
},
|
||||
@@ -1090,7 +960,73 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
/** String rep */
|
||||
toString : function(){
|
||||
return 'MultiPanelColumns(' + ( this.columns? this.columns.length : 0 ) + ')';
|
||||
}
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------ templates
|
||||
mainTemplate : _.template([
|
||||
'<div class="header flex-column-container">',
|
||||
'<div class="control-column control-column-left flex-column">',
|
||||
'<button class="create-new btn btn-default">', _l( 'Create new' ), '</button> ',
|
||||
'<div id="search-histories" class="search-control"></div>',
|
||||
'<div id="search-datasets" class="search-control"></div>',
|
||||
'<button class="open-more-options btn btn-default">',
|
||||
//TODO: tip not working
|
||||
'<span class="fa fa-ellipsis-h" title="More options"></span>',
|
||||
'</button>',
|
||||
'</div>',
|
||||
// feedback
|
||||
'<div class="control-column control-column-center flex-column">',
|
||||
'<div class="header-info">',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="control-column control-column-right flex-column">',
|
||||
'<button class="done btn btn-default">', _l( 'Done' ), '</button>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
// middle - where the columns go
|
||||
'<div class="outer-middle flex-row flex-row-container">',
|
||||
'<div class="middle flex-column-container flex-row"></div>',
|
||||
'</div>',
|
||||
// footer
|
||||
'<div class="footer flex-column-container">',
|
||||
'</div>'
|
||||
].join(''), { variable: 'view' }),
|
||||
|
||||
optionsPopoverTemplate : _.template([
|
||||
'<div class="more-options">',
|
||||
'<div class="checkbox"><label><input id="include-deleted" type="checkbox"',
|
||||
'<%= view.collection.includeDeleted? " checked" : "" %>>',
|
||||
_l( 'Include deleted histories' ),
|
||||
'</label></div>',
|
||||
|
||||
'<div class="order btn-group">',
|
||||
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',
|
||||
_l( 'Order histories by' ) + ' ',
|
||||
'<span class="current-order"><%= view.order %></span> ',
|
||||
'<span class="caret"></span>',
|
||||
'</button>',
|
||||
'<ul class="dropdown-menu" role="menu">',
|
||||
'<li><a href="javascript:void(0);" class="order-update">',
|
||||
_l( 'Time of last update' ),
|
||||
'</a></li>',
|
||||
'<li><a href="javascript:void(0);" class="order-name">',
|
||||
_l( 'Name' ),
|
||||
'</a></li>',
|
||||
'<li><a href="javascript:void(0);" class="order-size">',
|
||||
_l( 'Size' ),
|
||||
'</a></li>',
|
||||
'</ul>',
|
||||
'</div>',
|
||||
|
||||
'<div class="checkbox"><label><input id="toggle-deleted" type="checkbox">',
|
||||
_l( 'Include deleted datasets' ),
|
||||
'</label></div>',
|
||||
'<div class="checkbox"><label><input id="toggle-hidden" type="checkbox">',
|
||||
_l( 'Include hidden datasets' ),
|
||||
'</label></div>',
|
||||
'</div>'
|
||||
].join(''), { variable: 'view' }),
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ define([
|
||||
"ui/mode-button",
|
||||
"ui/search-input"
|
||||
], function( HISTORY_MODEL, HPANEL_EDIT, baseMVC, ajaxQueue ){
|
||||
window.HISTORY_MODEL = HISTORY_MODEL;
|
||||
//==============================================================================
|
||||
/** */
|
||||
function historyCopyDialog( history, options ){
|
||||
@@ -265,7 +264,7 @@ var HistoryPanelColumn = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return ( this.currentHistory )?
|
||||
[
|
||||
'<div class="pull-left">',
|
||||
'<button class="create-new btn btn-default">', _l( 'Create new' ), '</button> ',
|
||||
'<strong class="current-label">', _l( 'Current History' ), '</strong>',
|
||||
'</div>'
|
||||
].join( '' )
|
||||
:[
|
||||
@@ -328,6 +327,7 @@ var HistoryPanelColumn = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
//logger : console,
|
||||
className : 'multi-history-columns',
|
||||
|
||||
// ------------------------------------------------------------------------ set up
|
||||
/** Set up internals, history collection, and columns to display the history */
|
||||
@@ -366,9 +366,8 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
/** model id to column map */
|
||||
this.columnMap = {};
|
||||
//TODO: why create here?
|
||||
//TODO: why create here?
|
||||
this.createColumns( options.columnOptions );
|
||||
|
||||
this.setUpListeners();
|
||||
},
|
||||
|
||||
@@ -386,10 +385,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
var multipanel = this;
|
||||
multipanel.stopListening( multipanel.collection );
|
||||
multipanel.collection = models;
|
||||
//TODO: slow... esp. on start up
|
||||
//if( multipanel.order !== 'update' ){
|
||||
multipanel.sortCollection( multipanel.order, { silent: true });
|
||||
//}
|
||||
multipanel.sortCollection( multipanel.order, { silent: true });
|
||||
multipanel.setUpCollectionListeners();
|
||||
multipanel.trigger( 'new-collection', multipanel );
|
||||
return multipanel;
|
||||
@@ -408,11 +404,6 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
'change:deleted': multipanel.handleDeletedHistory,
|
||||
|
||||
'sort' : function(){ multipanel.renderColumns( 0 ); }
|
||||
|
||||
// debugging
|
||||
//'all' : function(){
|
||||
// console.info( 'collection:', arguments );
|
||||
//}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -430,11 +421,6 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
this.sortCollection();
|
||||
|
||||
////TODO: this actually means these render twice (1st from setCollection) - good enough for now
|
||||
//if( oldCurrentColumn ){ oldCurrentColumn.render().delegateEvents(); }
|
||||
//TODO:?? this occasionally causes race with hdaQueue
|
||||
//newCurrentColumn.panel.render( 'fast' ).delegateEvents();
|
||||
|
||||
multipanel._recalcFirstColumnHeight();
|
||||
return newCurrentColumn;
|
||||
},
|
||||
@@ -451,14 +437,14 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
|
||||
// if it's the current column, create a new, empty history as the new current
|
||||
if( column.model.id === this.currentHistoryId ){
|
||||
//TODO: figuring out the order of async here is tricky - for now let the user handle the two step process
|
||||
//TODO: figuring out the order of async here is tricky
|
||||
// - for now let the user handle the two step process
|
||||
//multipanel.collection.create().done( function(){
|
||||
// if( !multipanel.collection.includeDeleted ){ multipanel.removeColumn( column, false ); }
|
||||
//});
|
||||
} else if( !multipanel.collection.includeDeleted ){
|
||||
multipanel.removeColumn( column );
|
||||
}
|
||||
//TODO: prob. be done better
|
||||
}
|
||||
},
|
||||
|
||||
@@ -475,13 +461,12 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
//TODO: we can use a 2 arg version and return 1/0/-1
|
||||
//this.collection.comparator = function( h1, h2 ){
|
||||
this.collection.comparator = function( h ){
|
||||
//TODO: this won't do reverse order well
|
||||
//TODO: this won't do reverse order well
|
||||
return [ h.id !== currentHistoryId, h.get( 'name' ).toLowerCase() ];
|
||||
};
|
||||
break;
|
||||
case 'size':
|
||||
this.collection.comparator = function( h ){
|
||||
//console.debug( 'name sort', arguments )
|
||||
return [ h.id !== currentHistoryId, h.get( 'size' ) ];
|
||||
};
|
||||
break;
|
||||
@@ -501,6 +486,8 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
order = 'update';
|
||||
}
|
||||
this.order = order;
|
||||
this.trigger( 'order:change', order, this );
|
||||
this.$( '.current-order' ).text( order );
|
||||
this.sortCollection();
|
||||
return this;
|
||||
},
|
||||
@@ -533,6 +520,9 @@ 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 ){
|
||||
@@ -547,6 +537,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
});
|
||||
},
|
||||
|
||||
/** return array of Columns sorted to match the collection */
|
||||
sortedColumns : function(){
|
||||
var multipanel = this;
|
||||
var sorted = this.collection.map( function( history, index ){
|
||||
@@ -555,9 +546,9 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
/** */
|
||||
/** add a new column for history and render all columns if render is true */
|
||||
addColumn : function add( history, render ){
|
||||
//console.debug( 'adding column for:', history );
|
||||
//this.debug( 'adding column for:', history );
|
||||
render = render !== undefined? render: true;
|
||||
var newColumn = this.createColumn( history );
|
||||
this.columnMap[ history.id ] = newColumn;
|
||||
@@ -567,9 +558,9 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return newColumn;
|
||||
},
|
||||
|
||||
/** */
|
||||
/** add a new column for history and make it the current history/column */
|
||||
addAsCurrentColumn : function add( history ){
|
||||
//console.log( 'adding current column for:', history );
|
||||
//this.log( 'adding current column for:', history );
|
||||
var multipanel = this,
|
||||
newColumn = this.addColumn( history, false );
|
||||
this.setCurrentHistory( history );
|
||||
@@ -579,7 +570,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
return newColumn;
|
||||
},
|
||||
|
||||
/** */
|
||||
/** remove the given column, it's listeners, and optionally render */
|
||||
removeColumn : function remove( column, render ){
|
||||
render = render !== undefined? render : true;
|
||||
this.log( 'removeColumn', column );
|
||||
@@ -657,79 +648,17 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
var multipanel = this;
|
||||
|
||||
multipanel.log( multipanel + '.render' );
|
||||
multipanel.$el.html( multipanel.template( multipanel.options ) );
|
||||
//console.debug( multipanel.$( '.loading-overlay' ).fadeIn( 0 ) );
|
||||
multipanel.$el.html( multipanel.mainTemplate( multipanel ) );
|
||||
multipanel.renderColumns( speed );
|
||||
//console.debug( multipanel.$( '.loading-overlay' ).fadeOut( 'fast' ) );
|
||||
|
||||
// set the columns to full height allowed and set up behaviors for thie multipanel
|
||||
multipanel.setUpBehaviors();
|
||||
//TODO: wrong - has to wait for columns to render
|
||||
//TODO: wrong - has to wait for columns to render
|
||||
// - create a column listener that fires this when all columns are rendered
|
||||
multipanel.trigger( 'rendered', multipanel );
|
||||
return multipanel;
|
||||
},
|
||||
|
||||
/** Template - overall structure relies on flex-boxes and is 3 components: header, middle, footer */
|
||||
template : function template( options ){
|
||||
options = options || {};
|
||||
var html = [];
|
||||
if( this.options.headerHeight ){
|
||||
html = html.concat([
|
||||
// a loading overlay
|
||||
'<div class="loading-overlay flex-row"><div class="loading-overlay-message">loading...</div></div>',
|
||||
'<div class="header flex-column-container">',
|
||||
// page & history controls
|
||||
'<div class="header-control header-control-left flex-column">',
|
||||
'<button class="done btn btn-default">', _l( 'Done' ), '</button>',
|
||||
'<button class="include-deleted btn btn-default"></button>',
|
||||
'<div class="order btn-group">',
|
||||
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',
|
||||
_l( 'Order histories by' ) + '... <span class="caret"></span>',
|
||||
'</button>',
|
||||
'<ul class="dropdown-menu" role="menu">',
|
||||
'<li><a href="javascript:void(0);" class="order-update">',
|
||||
_l( 'Time of last update' ),
|
||||
'</a></li>',
|
||||
'<li><a href="javascript:void(0);" class="order-name">',
|
||||
_l( 'Name' ),
|
||||
'</a></li>',
|
||||
'<li><a href="javascript:void(0);" class="order-size">',
|
||||
_l( 'Size' ),
|
||||
'</a></li>',
|
||||
'</ul>',
|
||||
'</div>',
|
||||
'<div id="search-histories" class="header-search"></div>',
|
||||
'</div>',
|
||||
// feedback
|
||||
'<div class="header-control header-control-center flex-column">',
|
||||
'<div class="header-info">',
|
||||
'</div>',
|
||||
'</div>',
|
||||
// dataset controls
|
||||
'<div class="header-control header-control-right flex-column">',
|
||||
'<div id="search-datasets" class="header-search"></div>',
|
||||
'<button id="toggle-deleted" class="btn btn-default">',
|
||||
_l( 'Include deleted datasets' ),
|
||||
'</button>',
|
||||
'<button id="toggle-hidden" class="btn btn-default">',
|
||||
_l( 'Include hidden datasets' ),
|
||||
'</button>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
]);
|
||||
}
|
||||
|
||||
html = html.concat([
|
||||
// middle - where the columns go
|
||||
'<div class="outer-middle flex-row flex-row-container">',
|
||||
'<div class="middle flex-column-container flex-row"></div>',
|
||||
'</div>',
|
||||
// footer
|
||||
'<div class="footer flex-column-container">','</div>'
|
||||
]);
|
||||
return $( html.join( '' ) );
|
||||
},
|
||||
|
||||
/** Render the columns and panels */
|
||||
renderColumns : function renderColumns( speed ){
|
||||
speed = speed !== undefined? speed: this.fxSpeed;
|
||||
@@ -737,61 +666,21 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
// render columns and track the total number rendered, firing an event when all are rendered
|
||||
var multipanel = this,
|
||||
sortedAndFiltered = multipanel.sortedFilteredColumns();
|
||||
//console.log( '\t columnMapLength:', this.columnMapLength(), this.columnMap );
|
||||
//this.log( '\t sortedAndFiltered:', sortedAndFiltered );
|
||||
|
||||
// set up width based on collection size
|
||||
//console.debug( '(render) width before:', multipanel.$( '.middle' ).width() )
|
||||
multipanel.$( '.middle' ).width( sortedAndFiltered.length
|
||||
//TODO: magic number 16 === the amount that safely prevents stacking of columns when adding a new one
|
||||
* ( this.options.columnWidth + this.options.columnGap ) + this.options.columnGap + 16 );
|
||||
//console.debug( '(render) width now:', multipanel.$( '.middle' ).width() )
|
||||
|
||||
//console.debug( 'sortedAndFiltered:', sortedAndFiltered )
|
||||
//multipanel.$( '.middle' ).empty();
|
||||
|
||||
// this.$( '.middle' ).html( sortedAndFiltered.map( function( column, i ){
|
||||
// return column.$el.hide();
|
||||
// }));
|
||||
// sortedAndFiltered.forEach( function( column, i ){
|
||||
////console.debug( 'rendering:', column, i )
|
||||
// //multipanel.$( '.middle' ).append( column.$el.hide() );
|
||||
// column.delegateEvents();
|
||||
////TODO: current column in-view is never fired
|
||||
// multipanel.renderColumn( column, speed ).$el.show();
|
||||
// });
|
||||
|
||||
// var $els = sortedAndFiltered.map( function( column, i ){
|
||||
////console.debug( 'rendering:', column, i )
|
||||
// multipanel.renderColumn( column, speed );
|
||||
// return column.$el;
|
||||
// });
|
||||
//// this breaks the event map
|
||||
// //this.$( '.middle' ).html( $els );
|
||||
//// this doesn't
|
||||
// this.$( '.middle' ).append( $els );
|
||||
|
||||
var $middle = multipanel.$( '.middle' );
|
||||
$middle.empty();
|
||||
sortedAndFiltered.forEach( function( column, i ){
|
||||
//console.debug( 'rendering:', column, i, column.panel )
|
||||
|
||||
column.$el.appendTo( $middle );
|
||||
column.delegateEvents();
|
||||
multipanel.renderColumn( column, speed );
|
||||
|
||||
//column.$el.hide().appendTo( $middle );
|
||||
//multipanel.renderColumn( column, speed );
|
||||
// //.panel.on( 'all', function(){
|
||||
// // console.debug( 'column rendered:', arguments );
|
||||
// //});
|
||||
//// this won't work until we checkColumnsInView after the render
|
||||
////column.$el.fadeIn( speed );
|
||||
//column.$el.show();
|
||||
});
|
||||
//this.log( 'column rendering done' );
|
||||
|
||||
//TODO: event columns-rendered
|
||||
//TODO: event columns-rendered
|
||||
|
||||
if( this.searchFor && sortedAndFiltered.length <= 1 ){
|
||||
} else {
|
||||
@@ -808,15 +697,11 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
renderColumn : function( column, speed ){
|
||||
speed = speed !== undefined? speed: this.fxSpeed;
|
||||
return column.render( speed );
|
||||
//TODO: causes weirdness
|
||||
//return _.delay( function(){
|
||||
// return column.render( speed );
|
||||
//}, 0 );
|
||||
},
|
||||
|
||||
//TODO: combine the following two more sensibly
|
||||
//TODO: could have HistoryContents.haveDetails return false
|
||||
// if column.model.contents.length === 0 && !column.model.get( 'empty' ) then just check that
|
||||
//TODO: combine the following two more sensibly
|
||||
//TODO: could have HistoryContents.haveDetails return false
|
||||
// if column.model.contents.length === 0 && !column.model.get( 'empty' ) then just check that
|
||||
/** Get the *summary* contents of a column's history (and details on any expanded contents),
|
||||
* queueing the ajax call and using a named queue to prevent the call being sent twice
|
||||
*/
|
||||
@@ -874,14 +759,17 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
events : {
|
||||
// will move to the server root (gen. Analyze data)
|
||||
'click .done.btn' : 'close',
|
||||
//TODO:?? could just go back - but that's not always correct/desired behav.
|
||||
//'click .done.btn' : function(){ window.history.back(); },
|
||||
// creates a new empty history and makes it current
|
||||
'click .create-new.btn' : 'create',
|
||||
|
||||
'click #include-deleted' : '_clickToggleDeletedHistories',
|
||||
// these change the collection and column sort order
|
||||
'click .order .order-update' : function( e ){ this.setOrder( 'update' ); },
|
||||
'click .order .order-name' : function( e ){ this.setOrder( 'name' ); },
|
||||
'click .order .order-size' : function( e ){ this.setOrder( 'size' ); }
|
||||
'click .order .order-size' : function( e ){ this.setOrder( 'size' ); },
|
||||
|
||||
'click #toggle-deleted' : '_clickToggleDeletedDatasets',
|
||||
'click #toggle-hidden' : '_clickToggleHiddenDatasets'
|
||||
|
||||
//'dragstart .list-item .title-bar' : function( e ){ console.debug( 'ok' ); }
|
||||
},
|
||||
@@ -897,37 +785,48 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
window.location = destination;
|
||||
},
|
||||
|
||||
_clickToggleDeletedHistories : function( ev ){
|
||||
return this.toggleDeletedHistories( $( ev.currentTarget ).is( ':checked' ) );
|
||||
},
|
||||
/** Include deleted histories in the collection */
|
||||
includeDeletedHistories : function(){
|
||||
//TODO: better through API/limit+offset
|
||||
window.location += ( /\?/.test( window.location.toString() ) )?( '&' ):( '?' )
|
||||
+ 'include_deleted_histories=True';
|
||||
toggleDeletedHistories : function( show ){
|
||||
if( show ){
|
||||
window.location = Galaxy.options.root + 'history/view_multiple?include_deleted_histories=True';
|
||||
} else {
|
||||
window.location = Galaxy.options.root + 'history/view_multiple';
|
||||
}
|
||||
},
|
||||
|
||||
/** Show only non-deleted histories */
|
||||
excludeDeletedHistories : function(){
|
||||
//TODO: better through API/limit+offset
|
||||
window.location = window.location.toString().replace( /[&\?]include_deleted_histories=True/g, '' );
|
||||
_clickToggleDeletedDatasets : function( ev ){
|
||||
return this.toggleDeletedDatasets( $( ev.currentTarget ).is( ':checked' ) );
|
||||
},
|
||||
toggleDeletedDatasets : function( show ){
|
||||
show = show !== undefined? show : false;
|
||||
var multipanel = this;
|
||||
multipanel.sortedFilteredColumns().forEach( function( column, i ){
|
||||
_.delay( function(){
|
||||
column.panel.toggleShowDeleted( show, false );
|
||||
}, i * 200 );
|
||||
});
|
||||
},
|
||||
|
||||
_clickToggleHiddenDatasets : function( ev ){
|
||||
return this.toggleHiddenDatasets( $( ev.currentTarget ).is( ':checked' ) );
|
||||
},
|
||||
toggleHiddenDatasets : function( show ){
|
||||
show = show !== undefined? show : false;
|
||||
var multipanel = this;
|
||||
multipanel.sortedFilteredColumns().forEach( function( column, i ){
|
||||
_.delay( function(){
|
||||
column.panel.toggleShowHidden( show, false );
|
||||
}, i * 200 );
|
||||
});
|
||||
},
|
||||
|
||||
/** Set up any view plugins */
|
||||
setUpBehaviors : function(){
|
||||
var multipanel = this;
|
||||
|
||||
//TODO: currently doesn't need to be a mode button
|
||||
// toggle button for include deleted
|
||||
multipanel.$( '.include-deleted' ).modeButton({
|
||||
initialMode : this.collection.includeDeleted? 'exclude' : 'include',
|
||||
switchModesOnClick : false,
|
||||
modes: [
|
||||
{ mode: 'include', html: _l( 'Include deleted histories' ),
|
||||
onclick: _.bind( multipanel.includeDeletedHistories, multipanel )
|
||||
},
|
||||
{ mode: 'exclude', html: _l( 'Exclude deleted histories' ),
|
||||
onclick: _.bind( multipanel.excludeDeletedHistories, multipanel )
|
||||
}
|
||||
]
|
||||
});
|
||||
multipanel._moreOptionsPopover();
|
||||
|
||||
// input to search histories
|
||||
multipanel.$( '#search-histories' ).searchInput({
|
||||
@@ -942,7 +841,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
},
|
||||
onclear : function( searchFor ){
|
||||
multipanel.searchFor = null;
|
||||
//TODO: remove specifically not just reset
|
||||
//TODO: remove specifically not just reset
|
||||
multipanel.filters = [];
|
||||
multipanel.renderColumns( 0 );
|
||||
}
|
||||
@@ -986,53 +885,25 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
}
|
||||
});
|
||||
|
||||
//TODO: each panel stores the hidden/deleted state - and that isn't reflected in the buttons
|
||||
// toggle button for showing deleted history contents
|
||||
multipanel.$( '#toggle-deleted' ).modeButton({
|
||||
initialMode : 'include',
|
||||
modes: [
|
||||
{ mode: 'exclude', html: _l( 'Exclude deleted datasets' ) },
|
||||
{ mode: 'include', html: _l( 'Include deleted datasets' ) }
|
||||
]
|
||||
}).click( function(){
|
||||
var show = $( this ).modeButton( 'getMode' ).mode === 'exclude';
|
||||
multipanel.sortedFilteredColumns().forEach( function( column, i ){
|
||||
_.delay( function(){
|
||||
column.panel.toggleShowDeleted( show, false );
|
||||
}, i * 200 );
|
||||
});
|
||||
});
|
||||
|
||||
// toggle button for showing hidden history contents
|
||||
multipanel.$( '#toggle-hidden' ).modeButton({
|
||||
initialMode : 'include',
|
||||
modes: [
|
||||
{ mode: 'exclude', html: _l( 'Exclude hidden datasets' ) },
|
||||
{ mode: 'include', html: _l( 'Include hidden datasets' ) }
|
||||
]
|
||||
}).click( function(){
|
||||
var show = $( this ).modeButton( 'getMode' ).mode === 'exclude';
|
||||
multipanel.sortedFilteredColumns().forEach( function( column, i ){
|
||||
_.delay( function(){
|
||||
column.panel.toggleShowHidden( show, false );
|
||||
}, i * 200 );
|
||||
});
|
||||
});
|
||||
|
||||
// resize first (fixed position) column on page resize
|
||||
$( window ).resize( function(){
|
||||
multipanel._recalcFirstColumnHeight();
|
||||
});
|
||||
|
||||
// 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
|
||||
//TODO:?? might be able to simplify and not use pub-sub
|
||||
var debouncedInView = _.debounce( _.bind( this.checkColumnsInView, this ), 100 );
|
||||
this.$( '.middle' ).parent().scroll( debouncedInView );
|
||||
},
|
||||
|
||||
///** Put the in-view columns then the other columns in a queue, rendering each one at a time */
|
||||
//panelRenderQueue : function( columns, fn, args, renderEventName ){
|
||||
//},
|
||||
_moreOptionsPopover : function(){
|
||||
return this.$( '.open-more-options.btn' ).popover({
|
||||
container : '.header',
|
||||
placement : 'bottom',
|
||||
html : true,
|
||||
content : $( this.optionsPopoverTemplate( this ) )
|
||||
});
|
||||
},
|
||||
|
||||
/** Adjust the height of the first, current column since flex-boxes won't work with fixed postiion elements */
|
||||
_recalcFirstColumnHeight : function(){
|
||||
@@ -1052,18 +923,17 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
/** returns the columns currently in the viewport */
|
||||
columnsInView : function(){
|
||||
//TODO: uses offset which is render intensive
|
||||
//TODO: 2N - could use arg filter (sortedFilteredColumns( filter )) instead
|
||||
//TODO: 2N - could use arg filter (sortedFilteredColumns( filter )) instead
|
||||
var vp = this._viewport();
|
||||
return this.sortedFilteredColumns().filter( function( column ){
|
||||
return column.currentHistory || column.inView( vp.left, vp.right );
|
||||
});
|
||||
},
|
||||
|
||||
//TODO: sortByInView - return cols in view, then others
|
||||
//TODO: sortByInView - return cols in view, then others
|
||||
/** trigger in-view from columns in-view */
|
||||
checkColumnsInView : function(){
|
||||
//TODO: assbackward
|
||||
//console.debug( 'checking columns in view', this.columnsInView() );
|
||||
//TODO: assbackward - don't fire from the column, fire from here and listen from here
|
||||
this.columnsInView().forEach( function( column ){
|
||||
column.trigger( 'in-view', column );
|
||||
});
|
||||
@@ -1073,7 +943,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
currentColumnDropTargetOn : function(){
|
||||
var currentColumn = this.columnMap[ this.currentHistoryId ];
|
||||
if( !currentColumn ){ return; }
|
||||
//TODO: fix this - shouldn't need monkeypatch
|
||||
//TODO: fix this - shouldn't need monkeypatch
|
||||
currentColumn.panel.dataDropped = function( data ){};
|
||||
currentColumn.panel.dropTargetOn();
|
||||
},
|
||||
@@ -1090,7 +960,73 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
|
||||
/** String rep */
|
||||
toString : function(){
|
||||
return 'MultiPanelColumns(' + ( this.columns? this.columns.length : 0 ) + ')';
|
||||
}
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------ templates
|
||||
mainTemplate : _.template([
|
||||
'<div class="header flex-column-container">',
|
||||
'<div class="control-column control-column-left flex-column">',
|
||||
'<button class="create-new btn btn-default">', _l( 'Create new' ), '</button> ',
|
||||
'<div id="search-histories" class="search-control"></div>',
|
||||
'<div id="search-datasets" class="search-control"></div>',
|
||||
'<button class="open-more-options btn btn-default">',
|
||||
//TODO: tip not working
|
||||
'<span class="fa fa-ellipsis-h" title="More options"></span>',
|
||||
'</button>',
|
||||
'</div>',
|
||||
// feedback
|
||||
'<div class="control-column control-column-center flex-column">',
|
||||
'<div class="header-info">',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="control-column control-column-right flex-column">',
|
||||
'<button class="done btn btn-default">', _l( 'Done' ), '</button>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
// middle - where the columns go
|
||||
'<div class="outer-middle flex-row flex-row-container">',
|
||||
'<div class="middle flex-column-container flex-row"></div>',
|
||||
'</div>',
|
||||
// footer
|
||||
'<div class="footer flex-column-container">',
|
||||
'</div>'
|
||||
].join(''), { variable: 'view' }),
|
||||
|
||||
optionsPopoverTemplate : _.template([
|
||||
'<div class="more-options">',
|
||||
'<div class="checkbox"><label><input id="include-deleted" type="checkbox"',
|
||||
'<%= view.collection.includeDeleted? " checked" : "" %>>',
|
||||
_l( 'Include deleted histories' ),
|
||||
'</label></div>',
|
||||
|
||||
'<div class="order btn-group">',
|
||||
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',
|
||||
_l( 'Order histories by' ) + ' ',
|
||||
'<span class="current-order"><%= view.order %></span> ',
|
||||
'<span class="caret"></span>',
|
||||
'</button>',
|
||||
'<ul class="dropdown-menu" role="menu">',
|
||||
'<li><a href="javascript:void(0);" class="order-update">',
|
||||
_l( 'Time of last update' ),
|
||||
'</a></li>',
|
||||
'<li><a href="javascript:void(0);" class="order-name">',
|
||||
_l( 'Name' ),
|
||||
'</a></li>',
|
||||
'<li><a href="javascript:void(0);" class="order-size">',
|
||||
_l( 'Size' ),
|
||||
'</a></li>',
|
||||
'</ul>',
|
||||
'</div>',
|
||||
|
||||
'<div class="checkbox"><label><input id="toggle-deleted" type="checkbox">',
|
||||
_l( 'Include deleted datasets' ),
|
||||
'</label></div>',
|
||||
'<div class="checkbox"><label><input id="toggle-hidden" type="checkbox">',
|
||||
_l( 'Include hidden datasets' ),
|
||||
'</label></div>',
|
||||
'</div>'
|
||||
].join(''), { variable: 'view' }),
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -75,29 +75,36 @@
|
||||
.flex-column {
|
||||
}
|
||||
|
||||
/* ---------------------- header & footer */
|
||||
.header, .footer {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ---------------------- header */
|
||||
.header {
|
||||
background-color: lightgrey;
|
||||
min-height: ${header_height}px;
|
||||
max-height: ${header_height}px;
|
||||
}
|
||||
.header-control {
|
||||
.control-column {
|
||||
margin-top: 4px;
|
||||
}
|
||||
.header-control-right,
|
||||
.header-control-left {
|
||||
|
||||
.control-column-right,
|
||||
.control-column-left {
|
||||
margin-right: 8px;
|
||||
margin-left: 8px;
|
||||
/*background-color: green;*/
|
||||
}
|
||||
|
||||
.header-control-left > * {
|
||||
.control-column-left > * {
|
||||
margin: 0px 4px 4px 0px;
|
||||
}
|
||||
.more-options input[type=checkbox] {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.header-control-center {
|
||||
.control-column-center {
|
||||
text-align: center;
|
||||
max-height: 22px;
|
||||
-webkit-flex: 0 1 auto;
|
||||
@@ -117,26 +124,35 @@
|
||||
|
||||
}
|
||||
|
||||
.header-control-right {
|
||||
.control-column-right {
|
||||
text-align: right;
|
||||
}
|
||||
.header-control-right > * {
|
||||
.control-column-right > * {
|
||||
margin: 0px 0px 4px 4px;
|
||||
}
|
||||
|
||||
.header-search {
|
||||
.search-control {
|
||||
display: inline-block;
|
||||
width: 40%;
|
||||
}
|
||||
.header-search .search-clear,
|
||||
.header-search .search-loading {
|
||||
.search-control .search-clear,
|
||||
.search-control .search-loading {
|
||||
margin-top: -22px;
|
||||
}
|
||||
.footer input.search-query,
|
||||
.header input.search-query {
|
||||
font-size: 90%;
|
||||
height: 21px;
|
||||
padding: 2px;
|
||||
line-height: normal;
|
||||
padding: 2px 2px 1px 2px;
|
||||
}
|
||||
|
||||
.open-more-options {
|
||||
padding: 0 4px 0 4px;
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
/* ---------------------- middle */
|
||||
.outer-middle {
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -169,13 +185,18 @@
|
||||
align-self: auto;
|
||||
}
|
||||
.header .btn,
|
||||
.footer .btn,
|
||||
.panel-controls .btn {
|
||||
height: ${controls_height}px;
|
||||
line-height: ${controls_height - 2}px;
|
||||
height: 20px;
|
||||
/*line-height: ${controls_height - 2}px;*/
|
||||
line-height: normal;
|
||||
font-size: 90%;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
.header .btn {
|
||||
height: 21px;
|
||||
}
|
||||
.panel-controls .pull-left .btn {
|
||||
margin-right: 4px;
|
||||
}
|
||||
@@ -183,13 +204,14 @@
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
/* ---------------------- footer */
|
||||
.footer {
|
||||
min-height: ${footer_height}px;
|
||||
max-height: ${footer_height}px;
|
||||
background-color: grey;
|
||||
background-color: lightgrey;
|
||||
}
|
||||
|
||||
/* ---- columns */
|
||||
/* ---------------------- columns */
|
||||
.history-panel {
|
||||
width: 100%;
|
||||
margin-top: 4px;
|
||||
@@ -230,6 +252,12 @@
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.current-label {
|
||||
display: inline-block;
|
||||
color: grey;
|
||||
padding-left: 2px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
</%def>
|
||||
|
||||
Reference in New Issue
Block a user