mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
ui: adding PopupMenu view as alternate to make_popup_menu and allow changing option text, adding/removing options, and adding checkmarks for togglable options; index.mako: use PopupMenu for history-options-button; history panel: use alternate_history.mako to add 'collapse all', 'Include hidden datasets'(toggle), 'Include deleted datasets'(toggle) to history-options-button; alternate_history.mako: include better system for debugging js when changing source directly is problematic (main/test); pack_scripts;
This commit is contained in:
@@ -98,7 +98,6 @@ class RootController( BaseUIController, UsesHistoryMixin, UsesAnnotations ):
|
||||
return trans.fill_template_mako( "/my_data.mako" )
|
||||
|
||||
@web.expose
|
||||
#def history( self, trans, as_xml=False, show_deleted=False, show_hidden=False, hda_id=None, **kwd ):
|
||||
def history( self, trans, as_xml=False, show_deleted=None, show_hidden=None, hda_id=None, **kwd ):
|
||||
"""
|
||||
Display the current history, creating a new history if necessary.
|
||||
|
||||
@@ -288,7 +288,7 @@ var PersistantStorage = function( storageKey, storageDefaults ){
|
||||
},
|
||||
/** String representation.
|
||||
*/
|
||||
toString : function(){ return 'PersistantStorage(' + data + ')'; }
|
||||
toString : function(){ return 'PersistantStorage(' + storageKey + ')'; }
|
||||
});
|
||||
|
||||
return returnedStorage;
|
||||
|
||||
@@ -28,6 +28,7 @@ var HDABaseView = BaseView.extend( LoggableMixin ).extend(
|
||||
* @see Backbone.View#initialize
|
||||
*/
|
||||
initialize : function( attributes ){
|
||||
if( attributes.logger ){ this.logger = this.model.logger = attributes.logger; }
|
||||
this.log( this + '.initialize:', attributes );
|
||||
|
||||
/** list of rendering functions for the default, primary icon-buttons. */
|
||||
@@ -334,6 +335,8 @@ var HDABaseView = BaseView.extend( LoggableMixin ).extend(
|
||||
|
||||
//TODO: not a fan of this dispatch
|
||||
switch( this.model.get( 'state' ) ){
|
||||
case HistoryDatasetAssociation.STATES.NEW :
|
||||
break;
|
||||
case HistoryDatasetAssociation.STATES.NOT_VIEWABLE :
|
||||
this._render_body_not_viewable( body );
|
||||
break;
|
||||
|
||||
@@ -130,8 +130,7 @@ var HistoryDatasetAssociation = BaseModel.extend( LoggableMixin ).extend(
|
||||
//TODO: to list inclusion test
|
||||
//TODO: class level readyStates list
|
||||
return (
|
||||
( state === HistoryDatasetAssociation.STATES.NEW )
|
||||
|| ( state === HistoryDatasetAssociation.STATES.OK )
|
||||
( state === HistoryDatasetAssociation.STATES.OK )
|
||||
|| ( state === HistoryDatasetAssociation.STATES.EMPTY )
|
||||
|| ( state === HistoryDatasetAssociation.STATES.FAILED_METADATA )
|
||||
|| ( state === HistoryDatasetAssociation.STATES.NOT_VIEWABLE )
|
||||
|
||||
@@ -140,6 +140,8 @@ var HistoryPanel = BaseView.extend( LoggableMixin ).extend(
|
||||
* @see Backbone.View#initialize
|
||||
*/
|
||||
initialize : function( attributes ){
|
||||
// set the logger if requested
|
||||
if( attributes.logger ){ this.logger = this.model.logger = attributes.logger; }
|
||||
this.log( this + '.initialize:', attributes );
|
||||
|
||||
// set up url templates
|
||||
@@ -203,7 +205,7 @@ var HistoryPanel = BaseView.extend( LoggableMixin ).extend(
|
||||
show_deleted : false,
|
||||
show_hidden : false
|
||||
});
|
||||
this.log( 'this.storage:', this.storage.get() );
|
||||
this.log( this + ' (prev) storage:', JSON.stringify( this.storage.get(), null, 2 ) );
|
||||
|
||||
// expanded Hdas is a map of hda.ids -> a boolean rep'ing whether this hda's body is expanded
|
||||
// store any pre-expanded ids passed in
|
||||
@@ -226,7 +228,7 @@ var HistoryPanel = BaseView.extend( LoggableMixin ).extend(
|
||||
this.show_deleted = this.storage.get( 'show_deleted' );
|
||||
this.show_hidden = this.storage.get( 'show_hidden' );
|
||||
//this.log( 'this.show_deleted:', this.show_deleted, 'show_hidden', this.show_hidden );
|
||||
this.log( '(init\'d) this.storage:', this.storage.get() );
|
||||
this.log( this + ' (init\'d) storage:', this.storage.get() );
|
||||
},
|
||||
|
||||
/** Add an hda to this history's collection
|
||||
@@ -351,7 +353,8 @@ var HistoryPanel = BaseView.extend( LoggableMixin ).extend(
|
||||
historyView.hdaViews[ hdaId ] = new historyView.HDAView({
|
||||
model : hda,
|
||||
expanded : expanded,
|
||||
urlTemplates : historyView.hdaUrlTemplates
|
||||
urlTemplates : historyView.hdaUrlTemplates,
|
||||
logger : historyView.logger
|
||||
});
|
||||
historyView._setUpHdaListeners( historyView.hdaViews[ hdaId ] );
|
||||
|
||||
@@ -432,19 +435,23 @@ var HistoryPanel = BaseView.extend( LoggableMixin ).extend(
|
||||
/** Handle the user toggling the deleted visibility by:
|
||||
* (1) storing the new value in the persistant storage
|
||||
* (2) re-rendering the history
|
||||
* @returns {Boolean} new show_deleted setting
|
||||
*/
|
||||
toggleShowDeleted : function(){
|
||||
this.storage.set( 'show_deleted', !this.storage.get( 'show_deleted' ) );
|
||||
this.render();
|
||||
return this.storage.get( 'show_deleted' );
|
||||
},
|
||||
|
||||
/** Handle the user toggling the deleted visibility by:
|
||||
* (1) storing the new value in the persistant storage
|
||||
* (2) re-rendering the history
|
||||
* @returns {Boolean} new show_hidden setting
|
||||
*/
|
||||
toggleShowHidden : function(){
|
||||
this.storage.set( 'show_hidden', !this.storage.get( 'show_hidden' ) );
|
||||
this.render();
|
||||
return this.storage.get( 'show_hidden' );
|
||||
},
|
||||
|
||||
/** Collapse all hda bodies and clear expandedHdas in the storage
|
||||
|
||||
+305
-1
@@ -76,11 +76,11 @@ IconButtonView.templates = {
|
||||
iconButton : Handlebars.partials.iconButton
|
||||
};
|
||||
|
||||
|
||||
var IconButtonCollection = Backbone.Collection.extend({
|
||||
model: IconButton
|
||||
});
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Menu with multiple icon buttons. Views are not needed nor used for individual buttons.
|
||||
@@ -166,15 +166,319 @@ var GalaxyPaths = Backbone.Model.extend({
|
||||
});
|
||||
|
||||
|
||||
// =============================================================================
|
||||
/** @class View for a popup menu
|
||||
* @name PopupMenu
|
||||
*
|
||||
* @constructs
|
||||
*/
|
||||
var PopupMenu = Backbone.View.extend(
|
||||
/** @lends PopupMenu.prototype */{
|
||||
|
||||
/* TODO:
|
||||
add submenus
|
||||
add hrefs
|
||||
test various html keys
|
||||
add make_popupmenus style
|
||||
get template inside this file somehow
|
||||
*/
|
||||
/** Cache the desired button element and options, set up the button click handler
|
||||
* NOTE: attaches this view as HTML/jQ data on the button for later use.
|
||||
*/
|
||||
//TODO: include docs on special option keys (divider, checked, etc.)
|
||||
initialize : function( $button, options ){
|
||||
// default settings
|
||||
this.$button = $button || $( '<div/>' );
|
||||
this.options = options || [];
|
||||
//console.debug( this + '.initialize, button:', $button, ', options:', options );
|
||||
|
||||
// set up button click -> open menu behavior
|
||||
var menu = this;
|
||||
this.$button.click( function( event ){
|
||||
menu._renderAndShow( event );
|
||||
//event.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
// attach this view as a data object on the button - for later access
|
||||
//TODO:?? memleak?
|
||||
this.$button.data( 'PopupMenu', this );
|
||||
|
||||
// template loading is problematic - ui is loaded in base.mako
|
||||
// and the template (prev.) needed to be loaded before ui
|
||||
if( !this.templates.wrapper ){
|
||||
this.templates.wrapper = Handlebars.templates[ 'template-popupmenu-wrapper' ];
|
||||
}
|
||||
},
|
||||
|
||||
/** Render the menu. NOTE: doesn't attach itself to the DOM.
|
||||
* @see PopupMenu#_renderAndShow
|
||||
*/
|
||||
render : function(){
|
||||
var menu = this;
|
||||
|
||||
// render the menu body
|
||||
this.$el.addClass( 'popmenu-wrapper' )
|
||||
.css({
|
||||
position: 'absolute',
|
||||
display: 'none'
|
||||
});
|
||||
|
||||
//BUG: anchors within a.popupmenu-option render OUTSIDE the a.popupmenu-option!?
|
||||
this.$el.html( PopupMenu.templates.menu({
|
||||
options : this.options,
|
||||
// sets menu div id to '{{ id }}-menu'
|
||||
id : this.$button.attr( 'id' )
|
||||
}));
|
||||
//console.debug( this.$el, ':', this.$el.html() );
|
||||
|
||||
// set up behavior on each link/anchor elem
|
||||
if( this.options.length ){
|
||||
this.$el.find( 'li' ).each( function( i, li ){
|
||||
var $li = $( li ),
|
||||
$anchor = $li.children( 'a.popupmenu-option' ),
|
||||
menuFunc = menu.options[ i ].func;
|
||||
|
||||
//console.debug( 'setting up behavior:', i, menu.options[ i ], $li, $anchor );
|
||||
if( $anchor.length && menuFunc ){
|
||||
$anchor.click( function( event ){
|
||||
menuFunc( event, menu.options[ i ] );
|
||||
});
|
||||
}
|
||||
|
||||
// cache the anchor as a jq obj within the options obj
|
||||
menu.options[ i ].$li = $li;
|
||||
});
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/** Get the absolute position/offset for the menu
|
||||
*/
|
||||
_getShownPosition : function( clickEvent ){
|
||||
var menuWidth = this.$el.width(),
|
||||
// display menu horiz. centered on click...
|
||||
x = clickEvent.pageX - menuWidth / 2 ;
|
||||
|
||||
// ...but adjust that to handle horiz. scroll and window dimensions (draw entirely on visible screen area)
|
||||
x = Math.min( x, $( document ).scrollLeft() + $( window ).width() - menuWidth - 5 );
|
||||
x = Math.max( x, $( document ).scrollLeft() + 5 );
|
||||
|
||||
return {
|
||||
top: clickEvent.pageY,
|
||||
left: x
|
||||
};
|
||||
},
|
||||
|
||||
/** Render the menu, append to the page body at the click position, and set up the 'click-away' handlers, show
|
||||
*/
|
||||
_renderAndShow : function( clickEvent ){
|
||||
this.render();
|
||||
this.$el.appendTo( 'body' );
|
||||
this.$el.css( this._getShownPosition( clickEvent ) );
|
||||
this._setUpCloseBehavior();
|
||||
this.$el.show();
|
||||
},
|
||||
|
||||
/** Bind an event handler to all available frames so that when anything is clicked
|
||||
* * the menu is removed from the DOM
|
||||
* * The event handler unbinds itself
|
||||
*/
|
||||
_setUpCloseBehavior : function(){
|
||||
var menu = this,
|
||||
// function to close popup and unbind itself
|
||||
closePopupWhenClicked = function( $elClicked ){
|
||||
$elClicked.bind( "click.close_popup", function(){
|
||||
menu.remove();
|
||||
$elClicked.unbind( "click.close_popup" );
|
||||
});
|
||||
};
|
||||
|
||||
// bind to current, parent, and sibling frames
|
||||
//TODO: (Assuming for now that this is the best way to do this...)
|
||||
closePopupWhenClicked( $( window.document ) );
|
||||
closePopupWhenClicked( $( window.top.document ) );
|
||||
_.each( window.top.frames, function( siblingFrame ){
|
||||
closePopupWhenClicked( $( siblingFrame.document ) );
|
||||
});
|
||||
},
|
||||
|
||||
/** Add a menu option/item at the given index
|
||||
*/
|
||||
addItem : function( item, index ){
|
||||
// append to end if no index
|
||||
index = ( index >= 0 )?( index ):( this.options.length );
|
||||
this.options.splice( index, 0, item );
|
||||
return this;
|
||||
},
|
||||
|
||||
/** Remove a menu option/item at the given index
|
||||
*/
|
||||
removeItem : function( index ){
|
||||
if( index >=0 ){
|
||||
this.options.splice( index, 1 );
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/** Search for a menu option by it's html
|
||||
*/
|
||||
findIndexByHtml : function( html ){
|
||||
for( var i=0; i<this.options.length; i++ ){
|
||||
if( ( _.has( this.options[i], 'html' ) )
|
||||
&& ( this.options[i].html === html ) ){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/** Search for a menu option by it's html
|
||||
*/
|
||||
findItemByHtml : function( html ){
|
||||
return this.options[( this.findIndexByHtml( html ) )];
|
||||
},
|
||||
|
||||
/** String representation. */
|
||||
toString : function(){
|
||||
return 'PopupMenu';
|
||||
}
|
||||
});
|
||||
PopupMenu.templates = {
|
||||
menu : Handlebars.templates[ 'template-popupmenu-menu' ]
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// the following class functions are bridges from the original make_popupmenu and make_popup_menus
|
||||
// to the newer backbone.js PopupMenu
|
||||
|
||||
/** Create a PopupMenu from simple map initial_options activated by clicking button_element.
|
||||
* Converts initial_options to object array used by PopupMenu.
|
||||
* @param {jQuery|DOMElement} button_element element which, when clicked, activates menu
|
||||
* @param {Object} initial_options map of key -> values, where
|
||||
* key is option text, value is fn to call when option is clicked
|
||||
* @returns {PopupMenu} the PopupMenu created
|
||||
*/
|
||||
PopupMenu.make_popupmenu = function( button_element, initial_options ){
|
||||
var convertedOptions = [];
|
||||
_.each( initial_options, function( optionVal, optionKey ){
|
||||
var newOption = { html: optionKey };
|
||||
|
||||
// keys with null values indicate: header
|
||||
if( optionVal === null ){ // !optionVal? (null only?)
|
||||
newOption.header = true;
|
||||
|
||||
// keys with function values indicate: a menu option
|
||||
} else if( jQuery.type( optionVal ) === 'function' ){
|
||||
newOption.func = optionVal;
|
||||
}
|
||||
//TODO:?? any other special optionVals?
|
||||
// there was no divider option originally
|
||||
convertedOptions.push( newOption );
|
||||
});
|
||||
return new PopupMenu( $( button_element ), convertedOptions );
|
||||
};
|
||||
|
||||
/** Find all anchors in $parent (using selector) and covert anchors into a PopupMenu options map.
|
||||
* @param {jQuery} $parent the element that contains the links to convert to options
|
||||
* @param {String} selector jq selector string to find links
|
||||
* @returns {Object[]} the options array to initialize a PopupMenu
|
||||
*/
|
||||
//TODO: lose parent and selector, pass in array of links, use map to return options
|
||||
PopupMenu.convertLinksToOptions = function( $parent, selector ){
|
||||
$parent = $( $parent );
|
||||
selector = selector || 'a';
|
||||
var options = [];
|
||||
$parent.find( selector ).each( function( elem, i ){
|
||||
var option = {},
|
||||
$link = $( elem );
|
||||
|
||||
// convert link text to the option text (html) and the href into the option func
|
||||
option.html = $link.text();
|
||||
if( linkHref ){
|
||||
var linkHref = $link.attr( 'href' ),
|
||||
linkTarget = $link.attr( 'target' ),
|
||||
confirmText = $link.attr( 'confirm' );
|
||||
|
||||
option.func = function(){
|
||||
// if there's a "confirm" attribute, throw up a confirmation dialog, and
|
||||
// if the user cancels - do nothing
|
||||
if( ( confirmText ) && ( !confirm( confirmText ) ) ){ return; }
|
||||
|
||||
// if there's no confirm attribute, or the user accepted the confirm dialog:
|
||||
var f;
|
||||
switch( linkTarget ){
|
||||
// relocate the center panel
|
||||
case '_parent':
|
||||
window.parent.location = linkHref;
|
||||
break;
|
||||
|
||||
// relocate the entire window
|
||||
case '_top':
|
||||
window.top.location = linkHref;
|
||||
break;
|
||||
|
||||
// Http request target is a window named demolocal on the local box
|
||||
//TODO: I still don't understand this option (where the hell does f get set? confirm?)
|
||||
case 'demo':
|
||||
if( f === undefined || f.closed ){
|
||||
f = window.open( linkHref, linkTarget );
|
||||
f.creator = self;
|
||||
}
|
||||
break;
|
||||
|
||||
// relocate this panel
|
||||
default:
|
||||
window.location = linkHref;
|
||||
}
|
||||
};
|
||||
}
|
||||
options.push( option );
|
||||
});
|
||||
return options;
|
||||
};
|
||||
|
||||
/** Create a single popupmenu from existing DOM button and anchor elements
|
||||
* @param {jQuery} $buttonElement the element that when clicked will open the menu
|
||||
* @param {jQuery} $menuElement the element that contains the anchors to convert into a menu
|
||||
* @param {String} menuElementLinkSelector jq selector string used to find anchors to be made into menu options
|
||||
* @returns {PopupMenu} the PopupMenu (Backbone View) that can render, control the menu
|
||||
*/
|
||||
PopupMenu.fromExistingDom = function( $buttonElement, $menuElement, menuElementLinkSelector ){
|
||||
$buttonElement = $( $buttonElement );
|
||||
$menuElement = $( $menuElement );
|
||||
var options = PopupMenu.convertLinksToOptions( $menuElement, menuElementLinkSelector );
|
||||
// we're done with the menu (having converted it to an options map)
|
||||
$menuElement.remove();
|
||||
return new PopupMenu( $buttonElement, options );
|
||||
};
|
||||
|
||||
/** Create all popupmenus within a document or a more specific element
|
||||
* @param {DOMElement} parent the DOM element in which to search for popupmenus to build (defaults to document)
|
||||
* @param {String} menuSelector jq selector string to find popupmenu menu elements (defaults to "div[popupmenu]")
|
||||
* @param {Function} buttonSelectorBuildFn the function to build the jq button selector.
|
||||
* Will be passed $menuElement, parent.
|
||||
* (Defaults to return '#' + $menuElement.attr( 'popupmenu' ); )
|
||||
* @returns {PopupMenu[]} array of popupmenus created
|
||||
*/
|
||||
PopupMenu.make_popup_menus = function( parent, menuSelector, buttonSelectorBuildFn ){
|
||||
parent = parent || document;
|
||||
// orig. Glx popupmenu menus have a (non-std) attribute 'popupmenu'
|
||||
// which contains the id of the button that activates the menu
|
||||
menuSelector = menuSelector || 'div[popupmenu]';
|
||||
// default to (orig. Glx) matching button to menu by using the popupmenu attr of the menu as the id of the button
|
||||
buttonSelectorBuildFn = buttonSelectorBuildFn || function( $menuElement, parent ){
|
||||
return '#' + $menuElement.attr( 'popupmenu' );
|
||||
};
|
||||
|
||||
// aggregate and return all PopupMenus
|
||||
var popupMenusCreated = [];
|
||||
$( parent ).find( menuSelector ).each( function(){
|
||||
var $menuElement = $( this ),
|
||||
$buttonElement = $( parent ).find( buttonSelectorBuildFn( $menuElement, parent ) );
|
||||
popupMenusCreated.push( PopupMenu.fromDom( $buttonElement, $menuElement ) );
|
||||
$buttonElement.addClass( 'popup' );
|
||||
});
|
||||
return popupMenusCreated;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){return this.logger.log.apply(this.logger,arguments)}return undefined}};var GalaxyLocalization=jQuery.extend({},{ALIAS_NAME:"_l",localizedStrings:{},setLocalizedString:function(b,a){var c=this;var d=function(f,e){if(f!==e){c.localizedStrings[f]=e}};if(jQuery.type(b)==="string"){d(b,a)}else{if(jQuery.type(b)==="object"){jQuery.each(b,function(e,f){d(e,f)})}else{throw ("Localization.setLocalizedString needs either a string or object as the first argument, given: "+b)}}},localize:function(a){return this.localizedStrings[a]||a},toString:function(){return"GalaxyLocalization"}});window[GalaxyLocalization.ALIAS_NAME]=function(a){return GalaxyLocalization.localize(a)};var PersistantStorage=function(g,d){if(!g){throw ("PersistantStorage needs storageKey argument")}d=d||{};var b=jQuery.jStorage.get,c=jQuery.jStorage.set,a=jQuery.jStorage.deleteKey;function e(i,h){i=i||{};h=h||null;return{get:function(j){if(j===undefined){return i}else{if(i.hasOwnProperty(j)){return(jQuery.type(i[j])==="object")?(new e(i[j],this)):(i[j])}}return undefined},set:function(j,k){i[j]=k;this._save();return this},deleteKey:function(j){delete i[j];this._save();return this},_save:function(){return h._save()},toString:function(){return("StorageRecursionHelper("+i+")")}}}var f={};data=b(g);if(data===null){data=jQuery.extend(true,{},d);c(g,data)}f=new e(data);jQuery.extend(f,{_save:function(h){return c(g,f.get())},destroy:function(){return a(g)},toString:function(){return"PersistantStorage("+data+")"}});return f};
|
||||
var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){return this.logger.log.apply(this.logger,arguments)}return undefined}};var GalaxyLocalization=jQuery.extend({},{ALIAS_NAME:"_l",localizedStrings:{},setLocalizedString:function(b,a){var c=this;var d=function(f,e){if(f!==e){c.localizedStrings[f]=e}};if(jQuery.type(b)==="string"){d(b,a)}else{if(jQuery.type(b)==="object"){jQuery.each(b,function(e,f){d(e,f)})}else{throw ("Localization.setLocalizedString needs either a string or object as the first argument, given: "+b)}}},localize:function(a){return this.localizedStrings[a]||a},toString:function(){return"GalaxyLocalization"}});window[GalaxyLocalization.ALIAS_NAME]=function(a){return GalaxyLocalization.localize(a)};var PersistantStorage=function(g,d){if(!g){throw ("PersistantStorage needs storageKey argument")}d=d||{};var b=jQuery.jStorage.get,c=jQuery.jStorage.set,a=jQuery.jStorage.deleteKey;function e(i,h){i=i||{};h=h||null;return{get:function(j){if(j===undefined){return i}else{if(i.hasOwnProperty(j)){return(jQuery.type(i[j])==="object")?(new e(i[j],this)):(i[j])}}return undefined},set:function(j,k){i[j]=k;this._save();return this},deleteKey:function(j){delete i[j];this._save();return this},_save:function(){return h._save()},toString:function(){return("StorageRecursionHelper("+i+")")}}}var f={};data=b(g);if(data===null){data=jQuery.extend(true,{},d);c(g,data)}f=new e(data);jQuery.extend(f,{_save:function(h){return c(g,f.get())},destroy:function(){return a(g)},toString:function(){return"PersistantStorage("+g+")"}});return f};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
var HistoryDatasetAssociation=BaseModel.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"ok",data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:"",deleted:false,purged:false,visible:false,accessible:true},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("history_id")+"/contents/"+this.get("id")},initialize:function(){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",HistoryDatasetAssociation.STATES.NOT_VIEWABLE)}this.on("change:state",function(b,a){this.log(this+" has changed state:",b,a);if(this.inReadyState()){this.trigger("state:ready",this.get("id"),a,this.previous("state"),b)}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(b,c){var a=true;if((!b)&&(this.get("deleted")||this.get("purged"))){a=false}if((!c)&&(!this.get("visible"))){a=false}return a},inReadyState:function(){var a=this.get("state");return((a===HistoryDatasetAssociation.STATES.NEW)||(a===HistoryDatasetAssociation.STATES.OK)||(a===HistoryDatasetAssociation.STATES.EMPTY)||(a===HistoryDatasetAssociation.STATES.FAILED_METADATA)||(a===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(a===HistoryDatasetAssociation.STATES.DISCARDED)||(a===HistoryDatasetAssociation.STATES.ERROR))},hasData:function(){return(this.get("file_size")>0)},toString:function(){var a=this.get("id")||"";if(this.get("name")){a+=':"'+this.get("name")+'"'}return"HistoryDatasetAssociation("+a+")"}});HistoryDatasetAssociation.STATES={UPLOAD:"upload",QUEUED:"queued",PAUSED:"paused",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};var HDACollection=Backbone.Collection.extend(LoggableMixin).extend({model:HistoryDatasetAssociation,initialize:function(){},ids:function(){return this.map(function(a){return a.id})},hidToCollectionIndex:function(a){if(!a){return this.models.length}var d=this.models.length-1;for(var b=d;b>=0;b--){var c=this.at(b).get("hid");if(c==a){return b}if(c<a){return b+1}}return null},getVisible:function(a,b){return this.filter(function(c){return c.isVisible(a,b)})},getStateLists:function(){var a={};_.each(_.values(HistoryDatasetAssociation.STATES),function(b){a[b]=[]});this.each(function(b){a[b.get("state")].push(b.get("id"))});return a},running:function(){var a=[];this.each(function(b){if(!b.inReadyState()){a.push(b.get("id"))}});return a},update:function(a){this.log(this+"update:",a);if(!(a&&a.length)){return[]}var c=this,b=null;_.each(a,function(f,d){var e=c.get(f);if(e){e.fetch();b.push(e)}});return b},toString:function(){return("HDACollection()")}});
|
||||
var HistoryDatasetAssociation=BaseModel.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"ok",data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:"",deleted:false,purged:false,visible:false,accessible:true},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("history_id")+"/contents/"+this.get("id")},initialize:function(){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",HistoryDatasetAssociation.STATES.NOT_VIEWABLE)}this.on("change:state",function(b,a){this.log(this+" has changed state:",b,a);if(this.inReadyState()){this.trigger("state:ready",this.get("id"),a,this.previous("state"),b)}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(b,c){var a=true;if((!b)&&(this.get("deleted")||this.get("purged"))){a=false}if((!c)&&(!this.get("visible"))){a=false}return a},inReadyState:function(){var a=this.get("state");return((a===HistoryDatasetAssociation.STATES.OK)||(a===HistoryDatasetAssociation.STATES.EMPTY)||(a===HistoryDatasetAssociation.STATES.FAILED_METADATA)||(a===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(a===HistoryDatasetAssociation.STATES.DISCARDED)||(a===HistoryDatasetAssociation.STATES.ERROR))},hasData:function(){return(this.get("file_size")>0)},toString:function(){var a=this.get("id")||"";if(this.get("name")){a+=':"'+this.get("name")+'"'}return"HistoryDatasetAssociation("+a+")"}});HistoryDatasetAssociation.STATES={UPLOAD:"upload",QUEUED:"queued",PAUSED:"paused",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};var HDACollection=Backbone.Collection.extend(LoggableMixin).extend({model:HistoryDatasetAssociation,initialize:function(){},ids:function(){return this.map(function(a){return a.id})},hidToCollectionIndex:function(a){if(!a){return this.models.length}var d=this.models.length-1;for(var b=d;b>=0;b--){var c=this.at(b).get("hid");if(c==a){return b}if(c<a){return b+1}}return null},getVisible:function(a,b){return this.filter(function(c){return c.isVisible(a,b)})},getStateLists:function(){var a={};_.each(_.values(HistoryDatasetAssociation.STATES),function(b){a[b]=[]});this.each(function(b){a[b.get("state")].push(b.get("id"))});return a},running:function(){var a=[];this.each(function(b){if(!b.inReadyState()){a.push(b.get("id"))}});return a},update:function(a){this.log(this+"update:",a);if(!(a&&a.length)){return[]}var c=this,b=null;_.each(a,function(f,d){var e=c.get(f);if(e){e.fetch();b.push(e)}});return b},toString:function(){return("HDACollection()")}});
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-popupmenu-menu"]=b(function(f,s,q,l,x){q=q||f.helpers;var r="",i,h,d="function",c=this.escapeExpression,p=this;function o(B,A){var y="",z;y+="\n ";z=B.options;z=q.each.call(B,z,{hash:{},inverse:p.noop,fn:p.program(2,n,A)});if(z||z===0){y+=z}y+="\n";return y}function n(B,A){var y="",z;y+="\n ";z=B.divider;z=q["if"].call(B,z,{hash:{},inverse:p.program(5,k,A),fn:p.program(3,m,A)});if(z||z===0){y+=z}y+="\n ";return y}function m(z,y){return'\n <li class="divider"></li>\n '}function k(B,A){var y="",z;y+="\n ";z=B.header;z=q["if"].call(B,z,{hash:{},inverse:p.program(8,g,A),fn:p.program(6,j,A)});if(z||z===0){y+=z}y+="\n ";return y}function j(C,B){var z="",A,y;z+='\n <li class="head"><a href=""javascript:void(0);">';y=q.html;if(y){A=y.call(C,{hash:{}})}else{A=C.html;A=typeof A===d?A():A}if(A||A===0){z+=A}z+="</a></li>\n ";return z}function g(C,B){var z="",A,y;z+="\n ";z+='\n <li><a href="';A=C.href;A=q["if"].call(C,A,{hash:{},inverse:p.program(11,w,B),fn:p.program(9,e,B)});if(A||A===0){z+=A}z+='"\n ';A=C.href;A=q["if"].call(C,A,{hash:{},inverse:p.noop,fn:p.program(13,v,B)});if(A||A===0){z+=A}z+=' class="popupmenu-option">\n ';A=C.checked;A=q["if"].call(C,A,{hash:{},inverse:p.noop,fn:p.program(15,u,B)});if(A||A===0){z+=A}z+="\n ";y=q.html;if(y){A=y.call(C,{hash:{}})}else{A=C.html;A=typeof A===d?A():A}if(A||A===0){z+=A}z+="\n </a></li>\n ";return z}function e(B,A){var z,y;y=q.href;if(y){z=y.call(B,{hash:{}})}else{z=B.href;z=typeof z===d?z():z}return c(z)}function w(z,y){return"javascript:void(0);"}function v(C,B){var z="",A,y;z+='target="';y=q.target;if(y){A=y.call(C,{hash:{}})}else{A=C.target;A=typeof A===d?A():A}z+=c(A)+'"';return z}function u(z,y){return'<span class="ficon ok"></span>'}function t(z,y){return"\n <li>No Options.</li>\n"}r+='<ul id="';h=q.id;if(h){i=h.call(s,{hash:{}})}else{i=s.id;i=typeof i===d?i():i}r+=c(i)+'-menu" class="dropdown-menu">\n';i=s.options;i=i==null||i===false?i:i.length;i=q["if"].call(s,i,{hash:{},inverse:p.program(17,t,x),fn:p.program(1,o,x)});if(i||i===0){r+=i}r+="\n</ul>";return r})})();
|
||||
@@ -0,0 +1,117 @@
|
||||
(function() {
|
||||
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
|
||||
templates['template-popupmenu-menu'] = template(function (Handlebars,depth0,helpers,partials,data) {
|
||||
helpers = helpers || Handlebars.helpers;
|
||||
var buffer = "", stack1, foundHelper, functionType="function", escapeExpression=this.escapeExpression, self=this;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
var buffer = "", stack1;
|
||||
buffer += "\n ";
|
||||
stack1 = depth0.options;
|
||||
stack1 = helpers.each.call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(2, program2, data)});
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += "\n";
|
||||
return buffer;}
|
||||
function program2(depth0,data) {
|
||||
|
||||
var buffer = "", stack1;
|
||||
buffer += "\n ";
|
||||
stack1 = depth0.divider;
|
||||
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data)});
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += "\n ";
|
||||
return buffer;}
|
||||
function program3(depth0,data) {
|
||||
|
||||
|
||||
return "\n <li class=\"divider\"></li>\n ";}
|
||||
|
||||
function program5(depth0,data) {
|
||||
|
||||
var buffer = "", stack1;
|
||||
buffer += "\n ";
|
||||
stack1 = depth0.header;
|
||||
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(8, program8, data),fn:self.program(6, program6, data)});
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += "\n ";
|
||||
return buffer;}
|
||||
function program6(depth0,data) {
|
||||
|
||||
var buffer = "", stack1, foundHelper;
|
||||
buffer += "\n <li class=\"head\"><a href=\"\"javascript:void(0);\">";
|
||||
foundHelper = helpers.html;
|
||||
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
|
||||
else { stack1 = depth0.html; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += "</a></li>\n ";
|
||||
return buffer;}
|
||||
|
||||
function program8(depth0,data) {
|
||||
|
||||
var buffer = "", stack1, foundHelper;
|
||||
buffer += "\n ";
|
||||
buffer += "\n <li><a href=\"";
|
||||
stack1 = depth0.href;
|
||||
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(11, program11, data),fn:self.program(9, program9, data)});
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += "\"\n ";
|
||||
stack1 = depth0.href;
|
||||
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(13, program13, data)});
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += " class=\"popupmenu-option\">\n ";
|
||||
stack1 = depth0.checked;
|
||||
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(15, program15, data)});
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += "\n ";
|
||||
foundHelper = helpers.html;
|
||||
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
|
||||
else { stack1 = depth0.html; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += "\n </a></li>\n ";
|
||||
return buffer;}
|
||||
function program9(depth0,data) {
|
||||
|
||||
var stack1, foundHelper;
|
||||
foundHelper = helpers.href;
|
||||
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
|
||||
else { stack1 = depth0.href; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
|
||||
return escapeExpression(stack1);}
|
||||
|
||||
function program11(depth0,data) {
|
||||
|
||||
|
||||
return "javascript:void(0);";}
|
||||
|
||||
function program13(depth0,data) {
|
||||
|
||||
var buffer = "", stack1, foundHelper;
|
||||
buffer += "target=\"";
|
||||
foundHelper = helpers.target;
|
||||
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
|
||||
else { stack1 = depth0.target; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
|
||||
buffer += escapeExpression(stack1) + "\"";
|
||||
return buffer;}
|
||||
|
||||
function program15(depth0,data) {
|
||||
|
||||
|
||||
return "<span class=\"ficon ok\"></span>";}
|
||||
|
||||
function program17(depth0,data) {
|
||||
|
||||
|
||||
return "\n <li>No Options.</li>\n";}
|
||||
|
||||
buffer += "<ul id=\"";
|
||||
foundHelper = helpers.id;
|
||||
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
|
||||
else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
|
||||
buffer += escapeExpression(stack1) + "-menu\" class=\"dropdown-menu\">\n";
|
||||
stack1 = depth0.options;
|
||||
stack1 = stack1 == null || stack1 === false ? stack1 : stack1.length;
|
||||
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(17, program17, data),fn:self.program(1, program1, data)});
|
||||
if(stack1 || stack1 === 0) { buffer += stack1; }
|
||||
buffer += "\n</ul>";
|
||||
return buffer;});
|
||||
})();
|
||||
@@ -1,4 +1,4 @@
|
||||
<script type="text/template" class="template-history" id="template-user-quotaMeter-quota">
|
||||
<script type="text/template" class="template-user" id="template-user-quotaMeter-quota">
|
||||
<div id="quota-meter" class="quota-meter progress">
|
||||
<div id="quota-meter-bar" class="quota-meter-bar bar" style="width: {{quota_percent}}%"></div>
|
||||
{{! TODO: remove the hardcoded style }}
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" class="template-history" id="template-user-quotaMeter-usage">
|
||||
<script type="text/template" class="template-user" id="template-user-quotaMeter-usage">
|
||||
{{! TODO: remove the hardcoded styles }}
|
||||
<div id="quota-meter" class="quota-meter" style="background-color: transparent">
|
||||
<div id="quota-meter-text" class="quota-meter-text" style="top: 6px; color: white">
|
||||
@@ -16,3 +16,28 @@
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" class="template-ui" id="template-popupmenu-menu">
|
||||
<ul id="{{ id }}-menu" class="dropdown-menu">
|
||||
{{#if options.length }}
|
||||
{{#each options }}
|
||||
{{#if divider }}
|
||||
<li class="divider"></li>
|
||||
{{else}}
|
||||
{{#if header }}
|
||||
<li class="head"><a href=""javascript:void(0);">{{{ html }}}</a></li>
|
||||
{{else}}
|
||||
{{!NOTE: changed from # to void fn }}
|
||||
<li><a href="{{#if href }}{{ href }}{{else}}javascript:void(0);{{/if}}"
|
||||
{{#if href }}target="{{ target }}"{{/if}} class="popupmenu-option">
|
||||
{{#if checked }}<span class="ficon ok"></span>{{/if}}
|
||||
{{{ html }}}
|
||||
</a></li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<li>No Options.</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</script>
|
||||
|
||||
+8
-1
@@ -31,11 +31,18 @@
|
||||
"libs/jquery/jquery",
|
||||
"libs/json2",
|
||||
"libs/bootstrap",
|
||||
"galaxy.base",
|
||||
"libs/underscore",
|
||||
"libs/backbone/backbone",
|
||||
"libs/backbone/backbone-relational",
|
||||
"libs/handlebars.runtime",
|
||||
"galaxy.base"
|
||||
)}
|
||||
|
||||
${h.templates(
|
||||
"template-popupmenu-menu"
|
||||
)}
|
||||
|
||||
${h.js(
|
||||
"mvc/ui"
|
||||
)}
|
||||
|
||||
|
||||
@@ -56,9 +56,17 @@
|
||||
'libs/backbone/backbone',
|
||||
'libs/backbone/backbone-relational',
|
||||
'libs/handlebars.runtime',
|
||||
'mvc/ui',
|
||||
'galaxy.base'
|
||||
)}
|
||||
|
||||
${h.templates(
|
||||
"template-popupmenu-menu"
|
||||
)}
|
||||
|
||||
${h.js(
|
||||
"mvc/ui"
|
||||
)}
|
||||
|
||||
<script type="text/javascript">
|
||||
// console protection
|
||||
window.console = window.console || {
|
||||
|
||||
@@ -223,10 +223,12 @@ ${parent.javascripts()}
|
||||
${h.js(
|
||||
"libs/jquery/jstorage",
|
||||
"libs/jquery/jquery.autocomplete", "galaxy.autocom_tagging",
|
||||
"libs/json2",
|
||||
##"libs/json2",
|
||||
##"libs/bootstrap",
|
||||
"libs/backbone/backbone-relational",
|
||||
"mvc/base-mvc", "mvc/ui"
|
||||
## I think we can remove some of these
|
||||
##"libs/backbone/backbone-relational",
|
||||
"mvc/base-mvc",
|
||||
##"mvc/ui"
|
||||
)}
|
||||
|
||||
${h.templates(
|
||||
@@ -302,13 +304,9 @@ $(function(){
|
||||
galaxyPageSetUp();
|
||||
Galaxy.historyFrame = window;
|
||||
|
||||
// ostensibly, this is the App
|
||||
//if( window.console && console.debug ){
|
||||
// //if( console.clear ){ console.clear(); }
|
||||
// console.pretty = function( o ){ $( '<pre/>' ).text( JSON.stringify( o, null, ' ' ) ).appendTo( 'body' ); }
|
||||
// top.storage = jQuery.jStorage
|
||||
//}
|
||||
var debugging = ( new PersistantStorage( '__history_panel' ).get( 'debugging' ) || false );
|
||||
|
||||
// ostensibly, this is the App
|
||||
// LOAD INITIAL DATA IN THIS PAGE - since we're already sending it...
|
||||
// ...use mako to 'bootstrap' the models
|
||||
var user = ${ get_current_user() },
|
||||
@@ -325,7 +323,7 @@ $(function(){
|
||||
var historyPanel = new HistoryPanel({
|
||||
model : new History( history, hdas ),
|
||||
urlTemplates : galaxy_paths.attributes,
|
||||
//logger : console,
|
||||
logger : ( debugging )?( console ):( null ),
|
||||
// is page sending in show settings? if so override history's
|
||||
show_deleted : ${ 'true' if show_deleted == True else ( 'null' if show_deleted == None else 'false' ) },
|
||||
show_hidden : ${ 'true' if show_hidden == True else ( 'null' if show_hidden == None else 'false' ) }
|
||||
@@ -336,13 +334,17 @@ $(function(){
|
||||
//historyPanel = new HistoryPanel({
|
||||
// model: new History(),
|
||||
// urlTemplates : galaxy_paths.attributes,
|
||||
// logger : console,
|
||||
// logger : ( debugging )?( console ):( null ),
|
||||
// // is page sending in show settings? if so override history's
|
||||
// show_deleted : ${ 'true' if show_deleted == True else ( 'null' if show_deleted == None else 'false' ) },
|
||||
// show_hidden : ${ 'true' if show_hidden == True else ( 'null' if show_hidden == None else 'false' ) }
|
||||
//});
|
||||
//historyPanel.model.loadFromApi( history.id );
|
||||
|
||||
// set it up to be accessible across iframes
|
||||
//TODO:?? mem leak
|
||||
top.Galaxy.currHistoryPanel = historyPanel;
|
||||
|
||||
|
||||
// QUOTA METER is a cross-frame ui element (meter in masthead, over quota message in history)
|
||||
// create it and join them here for now (via events)
|
||||
@@ -352,6 +354,7 @@ $(function(){
|
||||
//window.currUser.logger = console;
|
||||
var quotaMeter = new UserQuotaMeter({
|
||||
model : currUser,
|
||||
//logger : ( debugging )?( console ):( null ),
|
||||
el : $( top.document ).find( '.quota-meter-container' )
|
||||
});
|
||||
//quotaMeter.logger = console; window.quotaMeter = quotaMeter
|
||||
@@ -373,9 +376,81 @@ $(function(){
|
||||
quotaMeter.update()
|
||||
}, quotaMeter );
|
||||
|
||||
// set it up to be accessible across iframes
|
||||
//TODO:?? mem leak
|
||||
top.Galaxy.currHistoryPanel = historyPanel;
|
||||
|
||||
//ANOTHER cross-frame element is the history-options-button...
|
||||
// in this case, we need to change the popupmenu options listed to include some functions for this history
|
||||
// these include: current (1 & 2) 'show/hide' delete and hidden functions, and (3) the collapse all option
|
||||
(function(){
|
||||
// don't try this if the history panel is in it's own window
|
||||
if( top.document === window.document ){
|
||||
return;
|
||||
}
|
||||
|
||||
// lots of wtf here...due to infernalframes
|
||||
var $historyButtonWindow = $( top.document ),
|
||||
HISTORY_MENU_BUTTON_ID = 'history-options-button',
|
||||
$historyMenuButton = $historyButtonWindow.find( '#' + HISTORY_MENU_BUTTON_ID ),
|
||||
// jq data in another frame can only be accessed by the jQuery in that frame,
|
||||
// get the jQuery from the top frame (that contains the history-options-button)
|
||||
START_INSERTING_AT_INDEX = 11,
|
||||
COLLAPSE_OPTION_TEXT = _l("Collapse Expanded Datasets"),
|
||||
DELETED_OPTION_TEXT = _l("Include Deleted Datasets"),
|
||||
HIDDEN_OPTION_TEXT = _l("Include Hidden Datasets");
|
||||
windowJQ = $( top )[0].jQuery,
|
||||
popupMenu = ( windowJQ && $historyMenuButton[0] )?( windowJQ.data( $historyMenuButton[0], 'PopupMenu' ) )
|
||||
:( null );
|
||||
|
||||
//console.debug(
|
||||
// '$historyButtonWindow:', $historyButtonWindow,
|
||||
// '$historyMenuButton:', $historyMenuButton,
|
||||
// 'windowJQ:', windowJQ,
|
||||
// 'popupmenu:', popupMenu
|
||||
//);
|
||||
if( !popupMenu ){ return; }
|
||||
|
||||
// since the history frame reloads so often (compared to the main window),
|
||||
// we need to check whether these options are there already before we add them again
|
||||
//NOTE: we use the global here because these remain bound in the main window even if panel refreshes
|
||||
//TODO: too much boilerplate
|
||||
if( popupMenu.findIndexByHtml( COLLAPSE_OPTION_TEXT ) === null ){
|
||||
popupMenu.addItem({
|
||||
html : COLLAPSE_OPTION_TEXT,
|
||||
func : function() {
|
||||
Galaxy.currHistoryPanel.collapseAllHdaBodies();
|
||||
}
|
||||
}, START_INSERTING_AT_INDEX )
|
||||
}
|
||||
|
||||
var deletedOptionIndex = popupMenu.findIndexByHtml( DELETED_OPTION_TEXT );
|
||||
if( deletedOptionIndex === null ){
|
||||
popupMenu.addItem({
|
||||
html : DELETED_OPTION_TEXT,
|
||||
func : function( clickEvent, thisMenuOption ){
|
||||
var show_deleted = Galaxy.currHistoryPanel.toggleShowDeleted();
|
||||
thisMenuOption.checked = show_deleted;
|
||||
}
|
||||
}, START_INSERTING_AT_INDEX + 1 )
|
||||
deletedOptionIndex = START_INSERTING_AT_INDEX + 1;
|
||||
}
|
||||
// whether was there or added, update the checked option to reflect the panel's settings on the panel render
|
||||
popupMenu.options[ deletedOptionIndex ].checked = Galaxy.currHistoryPanel.storage.get( 'show_deleted' );
|
||||
|
||||
var hiddenOptionIndex = popupMenu.findIndexByHtml( HIDDEN_OPTION_TEXT );
|
||||
if( hiddenOptionIndex === null ){
|
||||
popupMenu.addItem({
|
||||
html : HIDDEN_OPTION_TEXT,
|
||||
func : function( clickEvent, thisMenuOption ){
|
||||
var show_hidden = Galaxy.currHistoryPanel.toggleShowHidden();
|
||||
thisMenuOption.checked = show_hidden;
|
||||
}
|
||||
}, START_INSERTING_AT_INDEX + 2 )
|
||||
hiddenOptionIndex = START_INSERTING_AT_INDEX + 2;
|
||||
}
|
||||
// whether was there or added, update the checked option to reflect the panel's settings on the panel render
|
||||
popupMenu.options[ hiddenOptionIndex ].checked = Galaxy.currHistoryPanel.storage.get( 'show_hidden' );
|
||||
})();
|
||||
|
||||
//TODO: both the quota meter and the options-menu stuff need to be moved out when iframes are removed
|
||||
|
||||
return;
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
$(function(){
|
||||
// Init history options.
|
||||
$("#history-options-button").css( "position", "relative" );
|
||||
make_popupmenu( $("#history-options-button"), {
|
||||
var popupmenu = PopupMenu.make_popupmenu( $("#history-options-button"), {
|
||||
"${_("History Lists")}": null,
|
||||
"${_("Saved Histories")}": function() {
|
||||
galaxy_main.location = "${h.url_for( controller='history', action='list')}";
|
||||
@@ -40,18 +40,6 @@
|
||||
"${_("Resume Paused Jobs")}": function() {
|
||||
galaxy_history.location = "${h.url_for( controller='history', action='resume_paused_jobs', current=True)}";
|
||||
},
|
||||
"${_("Collapse Expanded Datasets")}": function() {
|
||||
Galaxy.currHistoryPanel.collapseAllHdaBodies();
|
||||
//galaxy_history.location = "${h.url_for( controller='root', action='history', show_deleted=True)}";
|
||||
},
|
||||
"${_("Show/Hide Deleted Datasets")}": function() {
|
||||
Galaxy.currHistoryPanel.toggleShowDeleted();
|
||||
//galaxy_history.location = "${h.url_for( controller='root', action='history', show_deleted=True)}";
|
||||
},
|
||||
"${_("Show/Hide Hidden Datasets")}": function() {
|
||||
Galaxy.currHistoryPanel.toggleShowHidden();
|
||||
//galaxy_history.location = "${h.url_for( controller='root', action='history', show_hidden=True)}";
|
||||
},
|
||||
"${_("Unhide Hidden Datasets")}": function() {
|
||||
if ( confirm( "Really unhide all hidden datasets?" ) ) {
|
||||
galaxy_main.location = "${h.url_for( controller='history', action='unhide_datasets', current=True )}";
|
||||
@@ -83,7 +71,6 @@
|
||||
galaxy_main.location = "${h.url_for( controller='history', action='import_archive' )}";
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
@@ -14,11 +14,12 @@ class TestHistory( TwillTestCase ):
|
||||
name = 'anonymous'
|
||||
self.new_history( name=name )
|
||||
global anonymous_history
|
||||
anonymous_history = sa_session.query( galaxy.model.History ) \
|
||||
.filter( and_( galaxy.model.History.table.c.deleted==False,
|
||||
galaxy.model.History.table.c.name==name ) ) \
|
||||
.order_by( desc( galaxy.model.History.table.c.create_time ) ) \
|
||||
.first()
|
||||
anonymous_history = (
|
||||
sa_session.query( galaxy.model.History )
|
||||
.filter( and_( galaxy.model.History.table.c.deleted==False, galaxy.model.History.table.c.name==name ) )
|
||||
.order_by( desc( galaxy.model.History.table.c.create_time ) )
|
||||
.first()
|
||||
)
|
||||
assert anonymous_history is not None, "Problem retrieving anonymous_history from database"
|
||||
# Upload a dataset to anonymous_history so it will be set as the current history after login
|
||||
self.upload_file( '1.bed', dbkey='hg18' )
|
||||
@@ -235,27 +236,35 @@ class TestHistory( TwillTestCase ):
|
||||
# Check list of histories to make sure shared history3 was cloned
|
||||
strings_displayed=[ "Clone of '%s' shared by '%s'" % ( history3.name, admin_user.email ) ]
|
||||
self.view_stored_active_histories( strings_displayed=strings_displayed )
|
||||
|
||||
def test_035_clone_current_history( self ):
|
||||
"""Testing cloning the current history"""
|
||||
# logged in as regular_user1
|
||||
self.logout()
|
||||
self.login( email=admin_user.email )
|
||||
|
||||
# Current history should be history3, add more datasets to history3, then delete them so we can
|
||||
# test cloning activatable datasets as well as only the active datasets
|
||||
self.upload_file( '2.bed', dbkey='hg18' )
|
||||
hda_2_bed = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \
|
||||
.filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id==history3.id,
|
||||
galaxy.model.HistoryDatasetAssociation.table.c.name=='2.bed' ) ) \
|
||||
.first()
|
||||
hda_2_bed = (
|
||||
sa_session.query( galaxy.model.HistoryDatasetAssociation )
|
||||
.filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id==history3.id,
|
||||
galaxy.model.HistoryDatasetAssociation.table.c.name=='2.bed' ) )
|
||||
.first()
|
||||
)
|
||||
assert hda_2_bed is not None, "Problem retrieving hda_2_bed from database"
|
||||
self.delete_history_item( str( hda_2_bed.id ) )
|
||||
|
||||
self.upload_file( '3.bed', dbkey='hg18' )
|
||||
hda_3_bed = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \
|
||||
.filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id==history3.id,
|
||||
galaxy.model.HistoryDatasetAssociation.table.c.name=='3.bed' ) ) \
|
||||
.first()
|
||||
hda_3_bed = (
|
||||
sa_session.query( galaxy.model.HistoryDatasetAssociation )
|
||||
.filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id==history3.id,
|
||||
galaxy.model.HistoryDatasetAssociation.table.c.name=='3.bed' ) )
|
||||
.first()
|
||||
)
|
||||
assert hda_3_bed is not None, "Problem retrieving hda_3_bed from database"
|
||||
self.delete_history_item( str( hda_3_bed.id ) )
|
||||
|
||||
# Test cloning activatable datasets
|
||||
self.clone_history( self.security.encode_id( history3.id ),
|
||||
'activatable',
|
||||
@@ -267,6 +276,7 @@ class TestHistory( TwillTestCase ):
|
||||
.order_by( desc( galaxy.model.History.table.c.create_time ) ) \
|
||||
.first()
|
||||
assert history3_clone2 is not None, "Problem retrieving history3_clone2 from database"
|
||||
|
||||
# Check list of histories to make sure shared history3 was cloned
|
||||
self.view_stored_active_histories( strings_displayed=[ "Clone of '%s'" % history3.name ] )
|
||||
# Switch to the cloned history to make sure activatable datasets were cloned
|
||||
@@ -307,6 +317,7 @@ class TestHistory( TwillTestCase ):
|
||||
raise AssertionError, "Deleted datasets incorrectly included in cloned history history3_clone3"
|
||||
except:
|
||||
pass
|
||||
|
||||
def test_040_sharing_mulitple_histories_with_multiple_users( self ):
|
||||
"""Testing sharing multiple histories containing only public datasets with multiple users"""
|
||||
# Logged in as admin_user
|
||||
|
||||
Reference in New Issue
Block a user