base_panels: move quota meter js into base_panels, provide bootstrapped user JSON, create Galaxy js namespace; history panel: don't use backbone-relational in dataset, user, or history; misc jsHint cleanup; expose_api: defend against no key provided; pack scripts

This commit is contained in:
Carl Eberhard
2013-04-11 13:00:38 -04:00
parent ba8f274aa8
commit 062387374c
31 changed files with 240 additions and 209 deletions
+2
View File
@@ -126,6 +126,8 @@ def expose_api( func, to_json=True, key_required=True ):
#If no key supplied, we use the existing session which may be an anonymous user.
if key_required and not trans.user:
try:
if 'key' not in kwargs:
raise NoResultFound( 'No key provided' )
provided_key = trans.sa_session.query( trans.app.model.APIKeys ).filter( trans.app.model.APIKeys.table.c.key == kwargs['key'] ).one()
except NoResultFound:
error_message = 'Provided API key is not valid.'
@@ -134,6 +134,8 @@ class RootController( BaseUIController, UsesHistoryMixin, UsesHistoryDatasetAsso
show_hidden = util.string_as_bool_or_none( show_hidden )
params = util.Params( kwd )
message = params.get( 'message', '' )
#TODO: ugh...
message = message if message != 'None' else ''
status = params.get( 'status', 'done' )
if trans.app.config.require_login and not trans.user:
+56 -51
View File
@@ -12,7 +12,7 @@
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
@@ -70,7 +70,7 @@ $.fn.makeAbsolute = function(rebase) {
*/
function make_popupmenu(button_element, initial_options) {
/* Use the $.data feature to store options with the link element.
This allows options to be changed at a later time
This allows options to be changed at a later time
*/
var element_menu_exists = (button_element.data("menu_options"));
button_element.data("menu_options", initial_options);
@@ -82,7 +82,7 @@ function make_popupmenu(button_element, initial_options) {
// Close existing visible menus
$(".popmenu-wrapper").remove();
// Need setTimeouts so clicks don't interfere with each other
// Need setTimeouts so clicks don't interfere with each other
setTimeout( function() {
// Dynamically generate the wrapper holding all the selectable options of the menu.
var menu_element = $( "<ul class='dropdown-menu' id='" + button_element.attr('id') + "-menu'></ul>" );
@@ -171,15 +171,15 @@ function make_popup_menus( parent ) {
if ( !confirmtext || confirm( confirmtext ) ) {
var f;
// relocate the center panel
if ( target == "_parent" ) {
if ( target === "_parent" ) {
window.parent.location = href;
// relocate the entire window
} else if ( target == "_top" ) {
} else if ( target === "_top" ) {
window.top.location = href;
//??...wot?
} else if ( target == "demo" ) {
} else if ( target === "demo" ) {
// Http request target is a window named
// demolocal on the local box
if ( f === undefined || f.closed ) {
@@ -242,7 +242,7 @@ function naturalSort(a, b) {
$.fn.refresh_select2 = function() {
var select_elt = $(this);
var options = { width: "resolve",
closeOnSelect: !select_elt.is("[MULTIPLE]"),
closeOnSelect: !select_elt.is("[MULTIPLE]")
};
return select_elt.select2( options );
}
@@ -263,7 +263,7 @@ function replace_big_select_inputs(min_length, max_length, select_elts) {
max_length = 3000;
}
var select_elts = select_elts || $('select');
select_elts = select_elts || $('select');
select_elts.each( function() {
var select_elt = $(this);
@@ -278,18 +278,18 @@ function replace_big_select_inputs(min_length, max_length, select_elts) {
}
/* Replaced jQuery.autocomplete with select2, notes:
* - multiple selects are supported
* - multiple selects are supported
* - the original element is updated with the value, convert_to_values should not be needed
* - events are fired when updating the original element, so refresh_on_change should just work
*
* - should we still sort dbkey fields here?
* - should we still sort dbkey fields here?
*/
select_elt.refresh_select2();
});
}
/**
* Make an element with text editable: (a) when user clicks on text, a textbox/area
* Make an element with text editable: (a) when user clicks on text, a textbox/area
* is provided for editing; (b) when enter key pressed, element's text is set and on_finish
* is called.
*/
@@ -336,12 +336,14 @@ $.fn.make_text_editable = function(config_dict) {
input_elt, button_elt;
if (use_textarea) {
input_elt = $("<textarea/>").attr({ rows: num_rows, cols: num_cols }).text($.trim(cur_text)).keyup(function(e) {
if (e.keyCode === 27) {
// Escape key.
set_text(cur_text);
}
});
input_elt = $("<textarea/>")
.attr({ rows: num_rows, cols: num_cols }).text($.trim(cur_text))
.keyup(function(e) {
if (e.keyCode === 27) {
// Escape key.
set_text(cur_text);
}
});
button_elt = $("<button/>").text("Done").click(function() {
set_text(input_elt.val());
// Return false so that click does not propogate to container.
@@ -361,7 +363,7 @@ $.fn.make_text_editable = function(config_dict) {
set_text($(this).val());
}
});
}
}
// Replace text with input object(s) and focus & select.
container.text("");
@@ -384,10 +386,11 @@ $.fn.make_text_editable = function(config_dict) {
return container;
};
/**
/**
* Edit and save text asynchronously.
*/
function async_save_text(click_to_edit_elt, text_elt_id, save_url, text_parm_name, num_cols, use_textarea, num_rows, on_start, on_finish) {
function async_save_text( click_to_edit_elt, text_elt_id, save_url,
text_parm_name, num_cols, use_textarea, num_rows, on_start, on_finish ) {
// Set defaults if necessary.
if (num_cols === undefined) {
num_cols = 30;
@@ -431,7 +434,7 @@ function async_save_text(click_to_edit_elt, text_elt_id, save_url, text_parm_nam
$.ajax({
url: save_url,
data: ajax_data,
error: function() {
error: function() {
alert( "Text editing for elt " + text_elt_id + " failed" );
// TODO: call finish or no? For now, let's not because error occurred.
},
@@ -464,6 +467,7 @@ function async_save_text(click_to_edit_elt, text_elt_id, save_url, text_parm_nam
}
function init_history_items(historywrapper, noinit, nochanges) {
//NOTE: still needed for non-panel history views
var action = function() {
// Load saved state and show as necessary
@@ -490,37 +494,38 @@ function init_history_items(historywrapper, noinit, nochanges) {
var id = this.id,
body = $(this).children( "div.historyItemBody" ),
peek = body.find( "pre.peek" );
$(this).find( ".historyItemTitleBar > .historyItemTitle" ).wrap( "<a href='javascript:void(0);'></a>" ).click( function() {
var prefs;
if ( body.is(":visible") ) {
// Hiding stuff here
if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ); }
body.slideUp( "fast" );
if (!nochanges) { // Ignore embedded item actions
// Save setting
prefs = $.jStorage.get("history_expand_state");
if (prefs) {
delete prefs[id];
$(this).find( ".historyItemTitleBar > .historyItemTitle" ).wrap( "<a href='javascript:void(0);'></a>" )
.click( function() {
var prefs;
if ( body.is(":visible") ) {
// Hiding stuff here
if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ); }
body.slideUp( "fast" );
if (!nochanges) { // Ignore embedded item actions
// Save setting
prefs = $.jStorage.get("history_expand_state");
if (prefs) {
delete prefs[id];
$.jStorage.set("history_expand_state", prefs);
}
}
} else {
// Showing stuff here
body.slideDown( "fast", function() {
if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); }
});
if (!nochanges) {
// Save setting
prefs = $.jStorage.get("history_expand_state");
if (!prefs) { prefs = {}; }
prefs[id] = true;
$.jStorage.set("history_expand_state", prefs);
}
}
} else {
// Showing stuff here
body.slideDown( "fast", function() {
if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); }
});
if (!nochanges) {
// Save setting
prefs = $.jStorage.get("history_expand_state");
if (!prefs) { prefs = {}; }
prefs[id] = true;
$.jStorage.set("history_expand_state", prefs);
}
}
return false;
});
return false;
});
});
// Generate 'collapse all' link
@@ -554,7 +559,7 @@ function commatize( number ) {
// Reset tool search to start state.
function reset_tool_search( initValue ) {
// Function may be called in top frame or in tool_menu_frame;
// Function may be called in top frame or in tool_menu_frame;
// in either case, get the tool menu frame.
var tool_menu_frame = $("#galaxy_tools").contents();
if (tool_menu_frame.length === 0) {
@@ -570,7 +575,7 @@ function reset_tool_search( initValue ) {
tool_menu_frame.find(".toolTitle").show();
tool_menu_frame.find(".toolPanelLabel").show();
tool_menu_frame.find(".toolSectionWrapper").each( function() {
if ($(this).attr('id') != 'recently_used_wrapper') {
if ($(this).attr('id') !== 'recently_used_wrapper') {
// Default action.
$(this).show();
} else if ($(this).hasClass("user_pref_visible")) {
+4 -9
View File
@@ -1,5 +1,5 @@
/**
* Simple base model for any visible element. Includes useful attributes and ability
* Simple base model for any visible element. Includes useful attributes and ability
* to set and track visibility.
*/
var BaseModel = Backbone.RelationalModel.extend({
@@ -38,7 +38,7 @@ var BaseView = Backbone.View.extend({
} else {
this.$el.show();
}
}
}
});
@@ -79,7 +79,7 @@ var LoggableMixin = /** @lends LoggableMixin# */{
log : function(){
if( this.logger ){
var log = this.logger.log;
if( typeof this.logger.log == 'object' ){
if( typeof this.logger.log === 'object' ){
log = Function.prototype.bind.call( this.logger.log, this.logger );
}
return log.apply( this.logger, arguments );
@@ -136,7 +136,7 @@ var GalaxyLocalization = jQuery.extend( {}, {
});
} else {
throw( 'Localization.setLocalizedString needs either a string or object as the first argument,' +
throw( 'Localization.setLocalizedString needs either a string or object as the first argument,' +
' given: ' + str_or_obj );
}
},
@@ -166,11 +166,6 @@ var GalaxyLocalization = jQuery.extend( {}, {
// global localization alias
window[ GalaxyLocalization.ALIAS_NAME ] = function( str ){ return GalaxyLocalization.localize( str ); };
//TEST: setLocalizedString( string, string ), _l( string )
//TEST: setLocalizedString( hash ), _l( string )
//TEST: setLocalizedString( string === string ), _l( string )
//TEST: _l( non assigned string )
//==============================================================================
/**
+3 -3
View File
@@ -2,17 +2,17 @@
// "../mvc/base-mvc"
//], function(){
/* global BaseView, LoggableMixin, HistoryDatasetAssociation, HDABaseView */
/* global Backbone, LoggableMixin, HistoryDatasetAssociation, HDABaseView */
//==============================================================================
/** @class Read only view for HistoryDatasetAssociation.
* @name HDABaseView
*
* @augments BaseView
* @augments Backbone.View
* @borrows LoggableMixin#logger as #logger
* @borrows LoggableMixin#log as #log
* @constructs
*/
var HDABaseView = BaseView.extend( LoggableMixin ).extend(
var HDABaseView = Backbone.View.extend( LoggableMixin ).extend(
/** @lends HDABaseView.prototype */{
///** logger used to record this.log messages, commonly set to console */
+9 -5
View File
@@ -53,11 +53,12 @@ var HDAEditView = HDABaseView.extend( LoggableMixin ).extend(
var ajaxPromise = jQuery.ajax( purge_url );
ajaxPromise.success( function( message, status, responseObj ){
hdaView.model.set( 'purged', true );
hdaView.trigger( 'purged', hdaView );
});
ajaxPromise.error( function( error, status, message ){
//TODO: Exception messages are hidden within error page
//!NOTE: that includes the 'Removal of datasets by users is not allowed in this Galaxy instance.'
alert( '(' + error.status + ') ' + _l( 'Unable to purge this dataset' ) + ':\n' + error );
hdaView.trigger( 'error', _l( "Unable to purge this dataset" ), error, status, message );
});
});
}
@@ -152,7 +153,7 @@ var HDAEditView = HDABaseView.extend( LoggableMixin ).extend(
icon_class : 'delete',
on_click : function() {
// Delete the dataset on the server and update HDA + view depending on success/failure.
// FIXME: when HDA-delete is implemented in the API, can call set(), then save directly
// FIXME: when HDA-delete is implemented in the API, can call set(), then save directly
// on the model.
$.ajax({
url: delete_url,
@@ -485,7 +486,7 @@ var HDAEditView = HDABaseView.extend( LoggableMixin ).extend(
// Hide.
tagArea.slideUp("fast");
}
return false;
return false;
},
/** Find the annotation area and, if initial: load the html (via ajax) for displaying them; otherwise, unhide/hide
@@ -504,7 +505,10 @@ var HDAEditView = HDABaseView.extend( LoggableMixin ).extend(
// Need to fill annotation element.
$.ajax({
url: this.urls.annotation.get,
error: function(){ alert( _l( "Annotations failed" ) ); },
error: function(){
view.log( "Annotation failed", xhr, status, error );
view.trigger( 'error', _l( "Annotation failed" ), xhr, status, error );
},
success: function( htmlFromAjax ){
if( htmlFromAjax === "" ){
htmlFromAjax = "<em>" + _l( "Describe or add notes to dataset" ) + "</em>";
@@ -528,7 +532,7 @@ var HDAEditView = HDABaseView.extend( LoggableMixin ).extend(
// Hide.
annotationArea.slideUp("fast");
}
return false;
return false;
},
// ......................................................................... UTILTIY
+2 -2
View File
@@ -6,12 +6,12 @@
* related to a history.
* @name HistoryDatasetAssociation
*
* @augments BaseModel
* @augments Backbone.Model
* @borrows LoggableMixin#logger as #logger
* @borrows LoggableMixin#log as #log
* @constructs
*/
var HistoryDatasetAssociation = BaseModel.extend( LoggableMixin ).extend(
var HistoryDatasetAssociation = Backbone.Model.extend( LoggableMixin ).extend(
/** @lends HistoryDatasetAssociation.prototype */{
///** logger used to record this.log messages, commonly set to console */
+2 -2
View File
@@ -6,12 +6,12 @@
* tool use and a collection of the datasets those tools produced.
* @name History
*
* @augments BaseModel
* @augments Backbone.Model
* @borrows LoggableMixin#logger as #logger
* @borrows LoggableMixin#log as #log
* @constructs
*/
var History = BaseModel.extend( LoggableMixin ).extend(
var History = Backbone.Model.extend( LoggableMixin ).extend(
/** @lends History.prototype */{
//TODO: bind change events from items and collection to this (itemLengths, states)
+8 -4
View File
@@ -54,12 +54,12 @@ TODO:
* panel (current right hand panel).
* @name HistoryPanel
*
* @augments BaseView
* @augments Backbone.View
* @borrows LoggableMixin#logger as #logger
* @borrows LoggableMixin#log as #log
* @constructs
*/
var HistoryPanel = BaseView.extend( LoggableMixin ).extend(
var HistoryPanel = Backbone.View.extend( LoggableMixin ).extend(
/** @lends HistoryPanel.prototype */{
///** logger used to record this.log messages, commonly set to console */
@@ -132,9 +132,13 @@ var HistoryPanel = BaseView.extend( LoggableMixin ).extend(
this.model.hdas.bind( 'reset', this.addAll, this );
// when a hda model is (un)deleted or (un)hidden, re-render entirely
//TODO??: purged
//TODO??: could be more selective here
this.model.hdas.bind( 'change:deleted', this.handleHdaDeletionChange, this );
// when an hda is purge the disk size changes
this.model.hdas.bind( 'change:purged', function( hda ){
// hafta get the new nice-size w/o the purged hda
//TODO: any beter way?
this.model.fetch();
}, this );
// if an a hidden hda is created (gen. by a workflow), moves thru the updater to the ready state,
// then: remove it from the collection if the panel is set to NOT show hidden datasets
+3 -3
View File
@@ -1,12 +1,12 @@
/** @class Model for a Galaxy user (including anonymous users).
* @name User
*
* @augments BaseModel
* @augments Backbone.Model
* @borrows LoggableMixin#logger as #logger
* @borrows LoggableMixin#log as #log
* @constructs
*/
var User = BaseModel.extend( LoggableMixin ).extend(
var User = Backbone.Model.extend( LoggableMixin ).extend(
/** @lends User.prototype */{
///** logger used to record this.log messages, commonly set to console */
@@ -25,7 +25,7 @@ var User = BaseModel.extend( LoggableMixin ).extend(
username : '(' + _l( "anonymous user" ) + ')',
email : "",
total_disk_usage : 0,
nice_total_disk_usage : "0 bytes",
nice_total_disk_usage : "",
quota_percent : null
},
+5 -3
View File
@@ -3,12 +3,12 @@
* or a simple text element displaying the human readable size used.
* @name UserQuotaMeter
*
* @augments BaseModel
* @augments Backbone.View
* @borrows LoggableMixin#logger as #logger
* @borrows LoggableMixin#log as #log
* @constructs
*/
var UserQuotaMeter = BaseView.extend( LoggableMixin ).extend(
var UserQuotaMeter = Backbone.View.extend( LoggableMixin ).extend(
/** @lends UserQuotaMeter.prototype */{
///** logger used to record this.log messages, commonly set to console */
@@ -111,10 +111,12 @@ var UserQuotaMeter = BaseView.extend( LoggableMixin ).extend(
// otherwise, render percent of quota (and warning, error)
} else {
meterHtml = this._render_quota();
//TODO: add the original text for unregistered quotas
//tooltip = "Your disk quota is %s. You can increase your quota by registering a Galaxy account."
}
this.$el.html( meterHtml );
//this.log( this + '.$el:', this.$el );
this.$el.find( '.quota-meter-text' ).tooltip();
return this;
},
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -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){var a=this.logger.log;if(typeof this.logger.log=="object"){a=Function.prototype.bind.call(this.logger.log,this.logger)}return a.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};
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){var a=this.logger.log;if(typeof this.logger.log==="object"){a=Function.prototype.bind.call(this.logger.log,this.logger)}return a.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
File diff suppressed because one or more lines are too long
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:"new",data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:"",deleted:false,purged:false,visible:true,accessible:true},urlRoot:"api/histories/",url:function(){return this.urlRoot+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",b,a,this.previous("state"))}})},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(this.isDeletedOrPurged()||(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("hid")+' :"'+this.get("name")+'",'+a}return"HDA("+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})},getByHid:function(a){return _.first(this.filter(function(b){return b.get("hid")===a}))},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},set:function(a){var b=this;if(!a||!_.isArray(a)){return}a.forEach(function(c){var d=b.get(c.id);if(d){d.set(c)}})},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=Backbone.Model.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"new",data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:"",deleted:false,purged:false,visible:true,accessible:true},urlRoot:"api/histories/",url:function(){return this.urlRoot+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",b,a,this.previous("state"))}})},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(this.isDeletedOrPurged()||(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("hid")+' :"'+this.get("name")+'",'+a}return"HDA("+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})},getByHid:function(a){return _.first(this.filter(function(b){return b.get("hid")===a}))},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},set:function(a){var b=this;if(!a||!_.isArray(a)){return}a.forEach(function(c){var d=b.get(c.id);if(d){d.set(c)}})},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()")}});
@@ -1 +1 @@
var History=BaseModel.extend(LoggableMixin).extend({defaults:{id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("id")},initialize:function(b,c,a){a=a||null;this.log(this+".initialize:",b,c);this.hdas=new HDACollection();if(c&&_.isArray(c)){this.hdas.reset(c);this.checkForUpdates();if(this.hdas.length>0){this.updateDisplayApplications()}}this.hdas.bind("state:ready",function(e,g,d){if(e.get("force_history_refresh")){var f=this;setTimeout(function(){f.stateUpdater()},History.UPDATE_DELAY)}},this);if(this.logger){this.bind("all",function(d){this.log(this+"",arguments)},this)}},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(g,d,e){if(g.status===502){setTimeout(function(){c.log("Bad Gateway error. Retrying...");c.stateUpdater()},History.UPDATE_DELAY)}else{if(!((g.readyState===0)&&(g.status===0))){c.log("stateUpdater error:",e,"responseText:",g.responseText);var f=_l("An error occurred while getting updates from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{a.log("Error updating hdas from api history contents",b,h,c,d,f);var g=_l("An error occurred while getting dataset details from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");a.trigger("error",g,h,c,d)}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},updateDisplayApplications:function(a){this.log(this+"updateDisplayApplications:",a);var c=this,b=(a&&_.isArray(a))?({hda_ids:a.join(",")}):({});c.log(this+": fetching display application data");jQuery.ajax("history/get_display_application_links",{data:b,success:function(e,d,f){c.hdas.set(e)},error:function(g,d,e){if(!((g.readyState===0)&&(g.status===0))){c.log("Error fetching display applications:",a,g,d,e);var f=_l("An error occurred while getting display applications from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"});
var History=Backbone.Model.extend(LoggableMixin).extend({defaults:{id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("id")},initialize:function(b,c,a){a=a||null;this.log(this+".initialize:",b,c);this.hdas=new HDACollection();if(c&&_.isArray(c)){this.hdas.reset(c);this.checkForUpdates();if(this.hdas.length>0){this.updateDisplayApplications()}}this.hdas.bind("state:ready",function(e,g,d){if(e.get("force_history_refresh")){var f=this;setTimeout(function(){f.stateUpdater()},History.UPDATE_DELAY)}},this);if(this.logger){this.bind("all",function(d){this.log(this+"",arguments)},this)}},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(g,d,e){if(g.status===502){setTimeout(function(){c.log("Bad Gateway error. Retrying...");c.stateUpdater()},History.UPDATE_DELAY)}else{if(!((g.readyState===0)&&(g.status===0))){c.log("stateUpdater error:",e,"responseText:",g.responseText);var f=_l("An error occurred while getting updates from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{a.log("Error updating hdas from api history contents",b,h,c,d,f);var g=_l("An error occurred while getting dataset details from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");a.trigger("error",g,h,c,d)}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},updateDisplayApplications:function(a){this.log(this+"updateDisplayApplications:",a);var c=this,b=(a&&_.isArray(a))?({hda_ids:a.join(",")}):({});c.log(this+": fetching display application data");jQuery.ajax("history/get_display_application_links",{data:b,success:function(e,d,f){c.hdas.set(e)},error:function(g,d,e){if(!((g.readyState===0)&&(g.status===0))){c.log("Error fetching display applications:",a,g,d,e);var f=_l("An error occurred while getting display applications from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"});
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
var User=BaseModel.extend(LoggableMixin).extend({urlRoot:"api/users",defaults:{id:null,username:"("+_l("anonymous user")+")",email:"",total_disk_usage:0,nice_total_disk_usage:"0 bytes",quota_percent:null},initialize:function(a){this.log("User.initialize:",a);this.on("loaded",function(b,c){this.log(this+" has loaded:",b,c)});this.on("change",function(b,c){this.log(this+" has changed:",b,c.changes)})},isAnonymous:function(){return(!this.get("email"))},loadFromApi:function(d,b){d=d||User.CURRENT_ID_STR;b=b||{};var a=this,c=b.success;b.success=function(f,e){a.trigger("loaded",f,e);if(c){c(f,e)}};if(d===User.CURRENT_ID_STR){b.url=this.urlRoot+"/"+User.CURRENT_ID_STR}return BaseModel.prototype.fetch.call(this,b)},toString:function(){var a=[this.get("username")];if(this.get("id")){a.unshift(this.get("id"));a.push(this.get("email"))}return"User("+a.join(":")+")"}});User.CURRENT_ID_STR="current";User.getCurrentUserFromApi=function(b){var a=new User();a.loadFromApi(User.CURRENT_ID_STR,b);return a};var UserCollection=Backbone.Collection.extend(LoggableMixin).extend({model:User,urlRoot:"api/users"});
var User=Backbone.Model.extend(LoggableMixin).extend({urlRoot:"api/users",defaults:{id:null,username:"("+_l("anonymous user")+")",email:"",total_disk_usage:0,nice_total_disk_usage:"",quota_percent:null},initialize:function(a){this.log("User.initialize:",a);this.on("loaded",function(b,c){this.log(this+" has loaded:",b,c)});this.on("change",function(b,c){this.log(this+" has changed:",b,c.changes)})},isAnonymous:function(){return(!this.get("email"))},loadFromApi:function(d,b){d=d||User.CURRENT_ID_STR;b=b||{};var a=this,c=b.success;b.success=function(f,e){a.trigger("loaded",f,e);if(c){c(f,e)}};if(d===User.CURRENT_ID_STR){b.url=this.urlRoot+"/"+User.CURRENT_ID_STR}return BaseModel.prototype.fetch.call(this,b)},toString:function(){var a=[this.get("username")];if(this.get("id")){a.unshift(this.get("id"));a.push(this.get("email"))}return"User("+a.join(":")+")"}});User.CURRENT_ID_STR="current";User.getCurrentUserFromApi=function(b){var a=new User();a.loadFromApi(User.CURRENT_ID_STR,b);return a};var UserCollection=Backbone.Collection.extend(LoggableMixin).extend({model:User,urlRoot:"api/users"});
@@ -1 +1 @@
var UserQuotaMeter=BaseView.extend(LoggableMixin).extend({options:{warnAtPercent:85,errorAtPercent:100},initialize:function(a){this.log(this+".initialize:",a);_.extend(this.options,a);this.model.bind("change:quota_percent change:total_disk_usage",this.render,this)},update:function(a){this.log(this+" updating user data...",a);this.model.loadFromApi(this.model.get("id"),a);return this},isOverQuota:function(){return(this.model.get("quota_percent")!==null&&this.model.get("quota_percent")>=this.options.errorAtPercent)},_render_quota:function(){var a=this.model.toJSON(),b=a.quota_percent,c=$(UserQuotaMeter.templates.quota(a));if(this.isOverQuota()){c.addClass("progress-danger");c.find("#quota-meter-text").css("color","white");this.trigger("quota:over",a)}else{if(b>=this.options.warnAtPercent){c.addClass("progress-warning");this.trigger("quota:under quota:under:approaching",a)}else{c.addClass("progress-success");this.trigger("quota:under quota:under:ok",a)}}return c},_render_usage:function(){var a=$(UserQuotaMeter.templates.usage(this.model.toJSON()));this.log(this+".rendering usage:",a);return a},render:function(){var a=null;this.log(this+".model.quota_percent:",this.model.get("quota_percent"));if((this.model.get("quota_percent")===null)||(this.model.get("quota_percent")===undefined)){a=this._render_usage()}else{a=this._render_quota()}this.$el.html(a);return this},toString:function(){return"UserQuotaMeter("+this.model+")"}});UserQuotaMeter.templates={quota:Handlebars.templates["template-user-quotaMeter-quota"],usage:Handlebars.templates["template-user-quotaMeter-usage"]};
var UserQuotaMeter=Backbone.View.extend(LoggableMixin).extend({options:{warnAtPercent:85,errorAtPercent:100},initialize:function(a){this.log(this+".initialize:",a);_.extend(this.options,a);this.model.bind("change:quota_percent change:total_disk_usage",this.render,this)},update:function(a){this.log(this+" updating user data...",a);this.model.loadFromApi(this.model.get("id"),a);return this},isOverQuota:function(){return(this.model.get("quota_percent")!==null&&this.model.get("quota_percent")>=this.options.errorAtPercent)},_render_quota:function(){var a=this.model.toJSON(),b=a.quota_percent,c=$(UserQuotaMeter.templates.quota(a));if(this.isOverQuota()){c.addClass("progress-danger");c.find("#quota-meter-text").css("color","white");this.trigger("quota:over",a)}else{if(b>=this.options.warnAtPercent){c.addClass("progress-warning");this.trigger("quota:under quota:under:approaching",a)}else{c.addClass("progress-success");this.trigger("quota:under quota:under:ok",a)}}return c},_render_usage:function(){var a=$(UserQuotaMeter.templates.usage(this.model.toJSON()));this.log(this+".rendering usage:",a);return a},render:function(){var a=null;this.log(this+".model.quota_percent:",this.model.get("quota_percent"));if((this.model.get("quota_percent")===null)||(this.model.get("quota_percent")===undefined)){a=this._render_usage()}else{a=this._render_quota()}this.$el.html(a);this.$el.find(".quota-meter-text").tooltip();return this},toString:function(){return"UserQuotaMeter("+this.model+")"}});UserQuotaMeter.templates={quota:Handlebars.templates["template-user-quotaMeter-quota"],usage:Handlebars.templates["template-user-quotaMeter-usage"]};
@@ -1 +1 @@
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-user-quotaMeter-quota"]=b(function(f,l,e,k,j){this.compilerInfo=[2,">= 1.0.0-rc.3"];e=e||f.helpers;j=j||{};var h="",c,o,g="function",i=this.escapeExpression,n=this,m=e.blockHelperMissing;function d(q,p){return"Using"}h+='<div id="quota-meter" class="quota-meter progress">\n <div id="quota-meter-bar" class="quota-meter-bar bar" style="width: ';if(c=e.quota_percent){c=c.call(l,{hash:{},data:j})}else{c=l.quota_percent;c=typeof c===g?c.apply(l):c}h+=i(c)+'%"></div>\n \n <div id="quota-meter-text" class="quota-meter-text"style="top: 6px">\n ';o={hash:{},inverse:n.noop,fn:n.program(1,d,j),data:j};if(c=e.local){c=c.call(l,o)}else{c=l.local;c=typeof c===g?c.apply(l):c}if(!e.local){c=m.call(l,c,o)}if(c||c===0){h+=c}h+=" ";if(c=e.quota_percent){c=c.call(l,{hash:{},data:j})}else{c=l.quota_percent;c=typeof c===g?c.apply(l):c}h+=i(c)+"%\n </div>\n</div>";return h})})();
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-user-quotaMeter-quota"]=b(function(g,m,f,l,k){this.compilerInfo=[2,">= 1.0.0-rc.3"];f=f||g.helpers;k=k||{};var i="",d,p,h="function",j=this.escapeExpression,o=this,n=f.blockHelperMissing;function e(t,s){var q="",r;q+=' title="Using ';if(r=f.nice_total_disk_usage){r=r.call(t,{hash:{},data:s})}else{r=t.nice_total_disk_usage;r=typeof r===h?r.apply(t):r}q+=j(r)+'"';return q}function c(r,q){return"Using"}i+='<div id="quota-meter" class="quota-meter progress">\n <div id="quota-meter-bar" class="quota-meter-bar bar" style="width: ';if(d=f.quota_percent){d=d.call(m,{hash:{},data:k})}else{d=m.quota_percent;d=typeof d===h?d.apply(m):d}i+=j(d)+'%"></div>\n \n <div id="quota-meter-text" class="quota-meter-text tooltip"\n style="top: 6px"';d=f["if"].call(m,m.nice_total_disk_usage,{hash:{},inverse:o.noop,fn:o.program(1,e,k),data:k});if(d||d===0){i+=d}i+=">\n ";p={hash:{},inverse:o.noop,fn:o.program(3,c,k),data:k};if(d=f.local){d=d.call(m,p)}else{d=m.local;d=typeof d===h?d.apply(m):d}if(!f.local){d=n.call(m,d,p)}if(d||d===0){i+=d}i+=" ";if(d=f.quota_percent){d=d.call(m,{hash:{},data:k})}else{d=m.quota_percent;d=typeof d===h?d.apply(m):d}i+=j(d)+"%\n </div>\n</div>";return i})})();
@@ -1 +1 @@
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-user-quotaMeter-usage"]=b(function(f,l,e,k,j){this.compilerInfo=[2,">= 1.0.0-rc.3"];e=e||f.helpers;j=j||{};var h="",c,o,n=this,g="function",m=e.blockHelperMissing,i=this.escapeExpression;function d(q,p){return"Using"}h+='\n<div id="quota-meter" class="quota-meter" style="background-color: transparent">\n <div id="quota-meter-text" class="quota-meter-text" style="top: 6px; color: white">\n ';o={hash:{},inverse:n.noop,fn:n.program(1,d,j),data:j};if(c=e.local){c=c.call(l,o)}else{c=l.local;c=typeof c===g?c.apply(l):c}if(!e.local){c=m.call(l,c,o)}if(c||c===0){h+=c}h+=" ";if(c=e.nice_total_disk_usage){c=c.call(l,{hash:{},data:j})}else{c=l.nice_total_disk_usage;c=typeof c===g?c.apply(l):c}h+=i(c)+"\n </div>\n</div>";return h})})();
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-user-quotaMeter-usage"]=b(function(g,m,f,l,k){this.compilerInfo=[2,">= 1.0.0-rc.3"];f=f||g.helpers;k=k||{};var i="",c,o=this,h="function",n=f.blockHelperMissing,j=this.escapeExpression;function e(t,s){var p="",r,q;q={hash:{},inverse:o.noop,fn:o.program(2,d,s),data:s};if(r=f.local){r=r.call(t,q)}else{r=t.local;r=typeof r===h?r.apply(t):r}if(!f.local){r=n.call(t,r,q)}if(r||r===0){p+=r}p+=" ";if(r=f.nice_total_disk_usage){r=r.call(t,{hash:{},data:s})}else{r=t.nice_total_disk_usage;r=typeof r===h?r.apply(t):r}p+=j(r);return p}function d(q,p){return"Using"}i+='\n<div id="quota-meter" class="quota-meter" style="background-color: transparent">\n <div id="quota-meter-text" class="quota-meter-text" style="top: 6px; color: white">\n ';c=f["if"].call(m,m.nice_total_disk_usage,{hash:{},inverse:o.noop,fn:o.program(1,e,k),data:k});if(c||c===0){i+=c}i+="\n </div>\n</div>";return i})})();
@@ -7,6 +7,17 @@ helpers = helpers || Handlebars.helpers; data = data || {};
function program1(depth0,data) {
var buffer = "", stack1;
buffer += " title=\"Using ";
if (stack1 = helpers.nice_total_disk_usage) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.nice_total_disk_usage; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\"";
return buffer;
}
function program3(depth0,data) {
return "Using";
}
@@ -16,8 +27,11 @@ function program1(depth0,data) {
else { stack1 = depth0.quota_percent; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "%\"></div>\n "
+ "\n <div id=\"quota-meter-text\" class=\"quota-meter-text\"style=\"top: 6px\">\n ";
options = {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data};
+ "\n <div id=\"quota-meter-text\" class=\"quota-meter-text tooltip\"\n style=\"top: 6px\"";
stack1 = helpers['if'].call(depth0, depth0.nice_total_disk_usage, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += ">\n ";
options = {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data};
if (stack1 = helpers.local) { stack1 = stack1.call(depth0, options); }
else { stack1 = depth0.local; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
if (!helpers.local) { stack1 = blockHelperMissing.call(depth0, stack1, options); }
@@ -3,16 +3,12 @@
templates['template-user-quotaMeter-usage'] = template(function (Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [2,'>= 1.0.0-rc.3'];
helpers = helpers || Handlebars.helpers; data = data || {};
var buffer = "", stack1, options, self=this, functionType="function", blockHelperMissing=helpers.blockHelperMissing, escapeExpression=this.escapeExpression;
var buffer = "", stack1, self=this, functionType="function", blockHelperMissing=helpers.blockHelperMissing, escapeExpression=this.escapeExpression;
function program1(depth0,data) {
return "Using";
}
buffer += "\n<div id=\"quota-meter\" class=\"quota-meter\" style=\"background-color: transparent\">\n <div id=\"quota-meter-text\" class=\"quota-meter-text\" style=\"top: 6px; color: white\">\n ";
options = {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data};
var buffer = "", stack1, options;
options = {hash:{},inverse:self.noop,fn:self.program(2, program2, data),data:data};
if (stack1 = helpers.local) { stack1 = stack1.call(depth0, options); }
else { stack1 = depth0.local; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
if (!helpers.local) { stack1 = blockHelperMissing.call(depth0, stack1, options); }
@@ -20,8 +16,19 @@ function program1(depth0,data) {
buffer += " ";
if (stack1 = helpers.nice_total_disk_usage) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.nice_total_disk_usage; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\n </div>\n</div>";
buffer += escapeExpression(stack1);
return buffer;
}
function program2(depth0,data) {
return "Using";
}
buffer += "\n<div id=\"quota-meter\" class=\"quota-meter\" style=\"background-color: transparent\">\n <div id=\"quota-meter-text\" class=\"quota-meter-text\" style=\"top: 6px; color: white\">\n ";
stack1 = helpers['if'].call(depth0, depth0.nice_total_disk_usage, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n </div>\n</div>";
return buffer;
});
})();
+3 -2
View File
@@ -2,7 +2,8 @@
<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 }}
<div id="quota-meter-text" class="quota-meter-text"style="top: 6px">
<div id="quota-meter-text" class="quota-meter-text tooltip"
style="top: 6px"{{#if nice_total_disk_usage}} title="Using {{nice_total_disk_usage}}"{{/if}}>
{{#local}}Using{{/local}} {{ quota_percent }}%
</div>
</div>
@@ -12,7 +13,7 @@
{{! 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">
{{#local}}Using{{/local}} {{ nice_total_disk_usage }}
{{#if nice_total_disk_usage }}{{#local}}Using{{/local}} {{ nice_total_disk_usage }}{{/if}}
</div>
</div>
</script>
+1
View File
@@ -1,6 +1,7 @@
<% _=n_ %>
<!DOCTYPE HTML>
<html>
<!--base.mako-->
<head>
<title>${self.title()}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+1
View File
@@ -251,6 +251,7 @@
## Document
<html>
<!--base_panels.mako-->
${self.init()}
<head>
<title>${self.title()}</title>
+48 -39
View File
@@ -7,6 +7,53 @@
${parent.javascripts()}
</%def>
<%def name="get_user_json()">
<%
"""Bootstrapping user API JSON"""
#TODO: move into common location (poss. BaseController)
if trans.user:
user_dict = trans.user.get_api_value( view='element', value_mapper={ 'id': trans.security.encode_id,
'total_disk_usage': float } )
user_dict['quota_percent'] = trans.app.quota_agent.get_percent( trans=trans )
else:
usage = 0
percent = None
try:
usage = trans.app.quota_agent.get_usage( trans, history=trans.history )
percent = trans.app.quota_agent.get_percent( trans=trans, usage=usage )
except AssertionError, assertion:
# no history for quota_agent.get_usage assertion
pass
user_dict = {
'total_disk_usage' : int( usage ),
'nice_total_disk_usage' : util.nice_size( usage ),
'quota_percent' : percent
}
%>
${h.to_json_string( user_dict )}
</%def>
<%def name="late_javascripts()">
${parent.late_javascripts()}
<!-- quota meter -->
${h.templates( "helpers-common-templates", "template-user-quotaMeter-quota", "template-user-quotaMeter-usage" )}
${h.js( "mvc/base-mvc", "mvc/user/user-model", "mvc/user/user-quotameter" )}
<script type="text/javascript">
// start a Galaxy namespace for objects created
window.Galaxy = window.Galaxy || {};
// set up the quota meter (And fetch the current user data from trans)
Galaxy.currUser = new User( ${get_user_json()} );
Galaxy.quotaMeter = new UserQuotaMeter({
model : Galaxy.currUser,
el : $( document ).find( '.quota-meter-container' )
}).render();
</script>
</%def>
## Masthead
<%def name="masthead()">
@@ -190,44 +237,6 @@
</a>
</div>
## Quota meter
<%
bar_style = "quota-meter-bar"
usage = 0
percent = 0
quota = None
try:
usage = trans.app.quota_agent.get_usage( trans=trans )
quota = trans.app.quota_agent.get_quota( trans.user )
percent = trans.app.quota_agent.get_percent( usage=usage, quota=quota )
if percent is not None:
if percent >= 100:
bar_style += " quota-meter-bar-error"
elif percent >= 85:
bar_style += " quota-meter-bar-warn"
else:
percent = 0
except AssertionError:
pass # Probably no history yet
tooltip = None
if not trans.user and quota and trans.app.config.allow_user_creation:
if trans.app.quota_agent.default_registered_quota is None or trans.app.quota_agent.default_unregistered_quota < trans.app.quota_agent.default_registered_quota:
tooltip = "Your disk quota is %s. You can increase your quota by registering a Galaxy account." % util.nice_size( quota )
%>
<div class="quota-meter-container"></div>
<div class="quota-meter-container">
%if tooltip:
<div id="quota-meter" class="quota-meter tooltip" title="${tooltip}">
%else:
<div id="quota-meter" class="quota-meter">
%endif
<div id="quota-meter-bar" class="${bar_style}" style="width: ${percent}px;"></div>
%if quota is not None:
<div id="quota-meter-text" class="quota-meter-text">Using ${percent}%</div>
%else:
<div id="quota-meter-text" class="quota-meter-text">Using ${util.nice_size( usage )}</div>
%endif
</div>
</div>
</%def>
+43 -62
View File
@@ -118,9 +118,6 @@ ${ unquote_plus( h.to_json_string( url_dict ) ) }
hda_ext_template = '<%= file_ext %>'
meta_type_template = '<%= file_type %>'
display_app_name_template = '<%= name %>'
display_app_link_template = '<%= link %>'
url_dict = {
# ................................................................ warning message links
'purge' : h.url_for( controller='dataset', action='purge_async',
@@ -139,7 +136,8 @@ ${ unquote_plus( h.to_json_string( url_dict ) ) }
dataset_id=encoded_id_template ),
#TODO: via api
'delete' : h.url_for( controller='dataset', action='delete_async', dataset_id=encoded_id_template ),
'delete' : h.url_for( controller='dataset', action='delete_async',
dataset_id=encoded_id_template ),
# ................................................................ download links (and associated meta files),
'download' : h.url_for( controller='dataset', action='display',
@@ -178,6 +176,7 @@ ${ unquote_plus( h.to_json_string( url_dict ) ) }
## -----------------------------------------------------------------------------
<%def name="get_current_user()">
<%
#TODO: move to root.history, using base.controller.usesUser, unify that with users api
user_json = trans.webapp.api_controllers[ 'users' ].show( trans, 'current' )
return user_json
%>
@@ -222,6 +221,7 @@ ${h.js(
<script type="text/javascript">
function galaxyPageSetUp(){
//TODO: move to base.mako
// moving global functions, objects into Galaxy namespace
top.Galaxy = top.Galaxy || {};
@@ -230,25 +230,11 @@ function galaxyPageSetUp(){
top.Galaxy.toolWindow = top.Galaxy.toolWindow || top.frames.galaxy_tools;
top.Galaxy.historyWindow = top.Galaxy.historyWindow || top.frames.galaxy_history;
top.Galaxy.$masthead = top.Galaxy.$masthead || $( top.document ).find( 'div#masthead' );
top.Galaxy.$messagebox = top.Galaxy.$messagebox || $( top.document ).find( 'div#messagebox' );
top.Galaxy.$leftPanel = top.Galaxy.$leftPanel || $( top.document ).find( 'div#left' );
top.Galaxy.$centerPanel = top.Galaxy.$centerPanel || $( top.document ).find( 'div#center' );
top.Galaxy.$rightPanel = top.Galaxy.$rightPanel || $( top.document ).find( 'div#right' );
//modals
top.Galaxy.show_modal = top.show_modal;
top.Galaxy.hide_modal = top.hide_modal;
}
// other base functions
// global backbone models
top.Galaxy.currUser = top.Galaxy.currUser;
top.Galaxy.currHistoryPanel = top.Galaxy.currHistoryPanel;
//top.Galaxy.paths = galaxy_paths;
top.Galaxy.localization = GalaxyLocalization;
window.Galaxy = top.Galaxy;
}
@@ -263,36 +249,38 @@ galaxy_paths.set( 'history', ${get_history_url_templates()} );
$(function(){
galaxyPageSetUp();
// ostensibly, this is the App
//NOTE: for debugging on non-local instances (main/test)
// 1. load history panel in own tab
// 2. from console: new PersistantStorage( '__history_panel' ).set( 'debugging', true )
// -> history panel and hdas will display console logs in console
var debugging = false;
if( jQuery.jStorage.get( '__history_panel' ) ){
debugging = new PersistantStorage( '__history_panel' ).get( 'debugging' );
}
// ostensibly, this is the App
// LOAD INITIAL DATA IN THIS PAGE - since we're already sending it...
// ...use mako to 'bootstrap' the models
// get the current user (either from the top frame's Galaxy or if in tab via the bootstrap)
Galaxy.currUser = Galaxy.currUser || new User(${ get_current_user() });
if( debugging ){ Galaxy.currUser.logger = console; }
var page_show_deleted = ${ 'true' if show_deleted == True else ( 'null' if show_deleted == None else 'false' ) },
page_show_hidden = ${ 'true' if show_hidden == True else ( 'null' if show_hidden == None else 'false' ) },
userJson = ${ get_current_user() },
// ...use mako to 'bootstrap' the models
historyJson = ${ history_json },
hdaJson = ${ hda_json };
//TODO: add these two in root.history
// add user data to history
// i don't like this history+user relationship, but user authentication changes views/behaviour
historyJson.user = Galaxy.currUser.toJSON();
// set up messages passed in
%if message:
historyJson.message = "${_( message )}"; historyJson.status = "${status}";
%endif
// add user data to history
// i don't like this history+user relationship, but user authentication changes views/behaviour
historyJson.user = userJson;
// create the history panel
var history = new History( historyJson, hdaJson, ( debugging )?( console ):( null ) );
var historyPanel = new HistoryPanel({
@@ -305,46 +293,41 @@ $(function(){
});
historyPanel.render();
// set it up to be accessible across iframes
//TODO:?? mem leak
top.Galaxy.currHistoryPanel = historyPanel;
var currUser = new User( userJson );
if( !Galaxy.currUser ){ Galaxy.currUser = currUser; }
// 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)
//TODO: this really belongs in the masthead
//TODO: and the quota message (curr. in the history panel) belongs somewhere else
//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
quotaMeter.render();
// show/hide the 'over quota message' in the history when the meter tells it to
quotaMeter.bind( 'quota:over', historyPanel.showQuotaMessage, historyPanel );
quotaMeter.bind( 'quota:under', historyPanel.hideQuotaMessage, historyPanel );
// having to add this to handle re-render of hview while overquota (the above do not fire)
historyPanel.on( 'rendered rendered:initial', function(){
if( quotaMeter.isOverQuota() ){
historyPanel.showQuotaMessage();
// QUOTA METER is a cross-frame ui element (meter in masthead, watches hist. size built here)
//TODO: the quota message (curr. in the history panel) belongs somewhere else
//TODO: does not display if in own tab
if( Galaxy.quotaMeter ){
// unbind prev. so we don't build up massive no.s of event handlers as history refreshes
if( top.Galaxy.currHistoryPanel ){
Galaxy.quotaMeter.unbind( 'quota:over', top.Galaxy.currHistoryPanel.showQuotaMessage );
Galaxy.quotaMeter.unbind( 'quota:under', top.Galaxy.currHistoryPanel.hideQuotaMessage );
}
});
//TODO: this _is_ sent to the page (over_quota)...
// update the quota meter when current history changes size
historyPanel.model.bind( 'change:nice_size', function(){
quotaMeter.update()
}, quotaMeter );
// show/hide the 'over quota message' in the history when the meter tells it to
Galaxy.quotaMeter.bind( 'quota:over', historyPanel.showQuotaMessage, historyPanel );
Galaxy.quotaMeter.bind( 'quota:under', historyPanel.hideQuotaMessage, historyPanel );
// update the quota meter when current history changes size
//TODO: can we consolidate the two following?
historyPanel.model.bind( 'rendered:initial change:nice_size', function(){
if( Galaxy.quotaMeter ){ Galaxy.quotaMeter.update() }
});
// having to add this to handle re-render of hview while overquota (the above do not fire)
historyPanel.on( 'rendered rendered:initial', function(){
if( Galaxy.quotaMeter && Galaxy.quotaMeter.isOverQuota() ){
historyPanel.showQuotaMessage();
}
});
}
// set it up to be accessible across iframes
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
//TODO: the options-menu stuff need to be moved out when iframes are removed
(function(){
// don't try this if the history panel is in it's own window
if( top.document === window.document ){
@@ -421,8 +404,6 @@ $(function(){
hiddenOption.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;
});
</script>
+4 -1
View File
@@ -2,11 +2,14 @@
<%def name="late_javascripts()">
${parent.late_javascripts()}
<script type="text/javascript">
// Set up GalaxyAsync object.
var galaxy_async = new GalaxyAsync();
galaxy_async.set_func_url(galaxy_async.set_user_pref, "${h.url_for( controller='user', action='set_user_pref_async' )}");
galaxy_async.set_func_url( galaxy_async.set_user_pref,
"${h.url_for( controller='user', action='set_user_pref_async' )}");
// set up history options menu
$(function(){
// Init history options.
$("#history-options-button").css( "position", "relative" );