galaxy-dev
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
July 2009
- 14 participants
- 68 discussions
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/3f407d489ade
changeset: 2479:3f407d489ade
user: James Taylor <james(a)jamestaylor.org>
date: Fri May 22 14:46:17 2009 -0400
description:
Performance improvements for large histories (both on database query and javascript)
5 file(s) affected in this change:
lib/galaxy/datatypes/registry.py
lib/galaxy/model/mapping.py
lib/galaxy/web/controllers/root.py
lib/galaxy/web/framework/__init__.py
templates/root/history.mako
diffs (243 lines):
diff -r feb7438276fb -r 3f407d489ade lib/galaxy/datatypes/registry.py
--- a/lib/galaxy/datatypes/registry.py Mon Jul 13 13:08:52 2009 -0400
+++ b/lib/galaxy/datatypes/registry.py Fri May 22 14:46:17 2009 -0400
@@ -211,7 +211,8 @@
builder = self.datatypes_by_extension[ext]
except KeyError:
builder = data.Text()
- self.log.warning('unknown extension in data factory %s' % ext)
+ if ext is not None:
+ self.log.warning('unknown extension in data factory %s', ext)
return builder
def change_datatype(self, data, ext ):
diff -r feb7438276fb -r 3f407d489ade lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Mon Jul 13 13:08:52 2009 -0400
+++ b/lib/galaxy/model/mapping.py Fri May 22 14:46:17 2009 -0400
@@ -690,7 +690,7 @@
assign_mapper( context, History, History.table,
properties=dict( galaxy_sessions=relation( GalaxySessionToHistoryAssociation ),
datasets=relation( HistoryDatasetAssociation, backref="history", order_by=asc(HistoryDatasetAssociation.table.c.hid) ),
- active_datasets=relation( HistoryDatasetAssociation, primaryjoin=( ( HistoryDatasetAssociation.table.c.history_id == History.table.c.id ) & ( not_( HistoryDatasetAssociation.table.c.deleted ) ) ), order_by=asc( HistoryDatasetAssociation.table.c.hid ), lazy=False, viewonly=True )
+ active_datasets=relation( HistoryDatasetAssociation, primaryjoin=( ( HistoryDatasetAssociation.table.c.history_id == History.table.c.id ) & ( not_( HistoryDatasetAssociation.table.c.deleted ) ) ), order_by=asc( HistoryDatasetAssociation.table.c.hid ), viewonly=True )
) )
assign_mapper( context, HistoryUserShareAssociation, HistoryUserShareAssociation.table,
diff -r feb7438276fb -r 3f407d489ade lib/galaxy/web/controllers/root.py
--- a/lib/galaxy/web/controllers/root.py Mon Jul 13 13:08:52 2009 -0400
+++ b/lib/galaxy/web/controllers/root.py Fri May 22 14:46:17 2009 -0400
@@ -61,7 +61,18 @@
return trans.fill_template_mako( "root/history_as_xml.mako", history=history, show_deleted=util.string_as_bool( show_deleted ) )
else:
template = "root/history.mako"
- return trans.fill_template( "root/history.mako", history=history, show_deleted=util.string_as_bool( show_deleted ) )
+ show_deleted = util.string_as_bool( show_deleted )
+ query = trans.sa_session.query( model.HistoryDatasetAssociation ) \
+ .filter( model.HistoryDatasetAssociation.history == history ) \
+ .options( eagerload( "children" ) ) \
+ .join( "dataset" ).filter( model.Dataset.purged == False ) \
+ .options( eagerload_all( "dataset.actions" ) )
+ if not show_deleted:
+ query.filter_by( deleted=False )
+ return trans.stream_template_mako( "root/history.mako",
+ history = history,
+ datasets = query.all(),
+ show_deleted = show_deleted )
@web.expose
def dataset_state ( self, trans, id=None, stamp=None ):
diff -r feb7438276fb -r 3f407d489ade lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py Mon Jul 13 13:08:52 2009 -0400
+++ b/lib/galaxy/web/framework/__init__.py Fri May 22 14:46:17 2009 -0400
@@ -23,6 +23,7 @@
pkg_resources.require( "Mako" )
import mako.template
import mako.lookup
+import mako.runtime
pkg_resources.require( "Babel" )
from babel.support import Translations
@@ -575,6 +576,23 @@
data.update( self.template_context )
data.update( kwargs )
return template.render( **data )
+ def stream_template_mako( self, filename, **kwargs ):
+ template = self.webapp.mako_template_lookup.get_template( filename )
+ template.output_encoding = 'utf-8'
+ data = dict( caller=self, t=self, trans=self, h=webhelpers, util=util, request=self.request, response=self.response, app=self.app )
+ data.update( self.template_context )
+ data.update( kwargs )
+ ## return template.render( **data )
+ def render( environ, start_response ):
+ response_write = start_response( self.response.wsgi_status(),
+ self.response.wsgi_headeritems() )
+ class C:
+ def write( self, *args, **kwargs ):
+ response_write( *args, **kwargs )
+ context = mako.runtime.Context( C(), **data )
+ template.render_context( context )
+ return []
+ return render
def fill_template_string(self, template_string, context=None, **kwargs):
"""
Fill in a template, putting any keyword arguments on the context.
diff -r feb7438276fb -r 3f407d489ade templates/root/history.mako
--- a/templates/root/history.mako Mon Jul 13 13:08:52 2009 -0400
+++ b/templates/root/history.mako Fri May 22 14:46:17 2009 -0400
@@ -70,7 +70,15 @@
$("#history-name-area").append( t );
t.focus();
return false;
- })
+ });
+ // Updater
+ updater({
+ %for data in reversed( datasets ):
+ %if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]:
+ "${data.id}": "${data.state}";
+ %endif
+ %endfor
+ });
})
//' Functionized so AJAX'd datasets can call them
// Get shown/hidden state from cookie
@@ -80,7 +88,7 @@
var state = new CookieSet( "galaxy.history.expand_state" );
for ( id in state.store ) {
if ( id ) {
- $( "#" + id ).children( "div.historyItemBody" ).show();
+ $( "#" + id + " div.historyItemBody" ).show();
}
}
// If Mozilla, hide scrollbars in hidden items since they cause animation bugs
@@ -114,51 +122,51 @@
state.add( id ); state.save();
delete state;
}
- return false;
+ return false;
});
// Delete link
$(this).find( "a.historyItemDelete" ).each( function() {
- var data_id = this.id.split( "-" )[1];
- $(this).click( function() {
- $( '#progress-' + data_id ).show();
- $.ajax({
- url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ),
- error: function() { alert( "Delete failed" ) },
- success: function() {
- %if show_deleted:
- var to_update = {};
- to_update[data_id] = "none";
- updater( to_update );
- %else:
- $( "#historyItem-" + data_id ).fadeOut( "fast", function() {
- $( "#historyItemContainer-" + data_id ).remove();
- if ( $( "div.historyItemContainer" ).length < 1 ) {
- $( "#emptyHistoryMessage" ).show();
- }
+ var data_id = this.id.split( "-" )[1];
+ $(this).click( function() {
+ $( '#progress-' + data_id ).show();
+ $.ajax({
+ url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ),
+ error: function() { alert( "Delete failed" ) },
+ success: function() {
+ %if show_deleted:
+ var to_update = {};
+ to_update[data_id] = "none";
+ updater( to_update );
+ %else:
+ $( "#historyItem-" + data_id ).fadeOut( "fast", function() {
+ $( "#historyItemContainer-" + data_id ).remove();
+ if ( $( "div.historyItemContainer" ).length < 1 ) {
+ $( "#emptyHistoryMessage" ).show();
+ }
+ });
+ %endif
+ }
+ });
+ return false;
});
- %endif
- }
});
- return false;
- });
- });
// Undelete link
$(this).find( "a.historyItemUndelete" ).each( function() {
- var data_id = this.id.split( "-" )[1];
- $(this).click( function() {
- $( '#progress-' + data_id ).show();
- $.ajax({
- url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ),
- error: function() { alert( "Undelete failed" ) },
- success: function() {
- var to_update = {};
- to_update[data_id] = "none";
- updater( to_update );
- }
+ var data_id = this.id.split( "-" )[1];
+ $(this).click( function() {
+ $( '#progress-' + data_id ).show();
+ $.ajax({
+ url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ),
+ error: function() { alert( "Undelete failed" ) },
+ success: function() {
+ var to_update = {};
+ to_update[data_id] = "none";
+ updater( to_update );
+ }
+ });
+ return false;
+ });
});
- return false;
- });
- });
});
};
// Looks for changes in dataset state using an async request. Keeps
@@ -261,36 +269,21 @@
<%namespace file="history_common.mako" import="render_dataset" />
-<% activatable_datasets = history.activatable_datasets %>
+%if not datasets:
-%if ( show_deleted and not activatable_datasets ) or ( not show_deleted and not history.active_datasets ):
<div class="infomessagesmall" id="emptyHistoryMessage">
+
%else:
- <%
- if show_deleted:
- ## All datasets
- datasets_to_show = activatable_datasets
- else:
- ## Active (not deleted)
- datasets_to_show = history.active_datasets
- %>
+
## Render requested datasets, ordered from newest to oldest
- %for data in reversed( datasets_to_show ):
+ %for data in reversed( datasets ):
%if data.visible:
<div class="historyItemContainer" id="historyItemContainer-${data.id}">
${render_dataset( data, data.hid, show_deleted_on_refresh = show_deleted )}
</div>
%endif
%endfor
- <script type="text/javascript">
- var tracked_datasets = {};
- %for data in reversed( history.active_datasets ):
- %if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]:
- tracked_datasets[ ${data.id} ] = "${data.state}";
- %endif
- %endfor
- updater( tracked_datasets );
- </script>
+
<div class="infomessagesmall" id="emptyHistoryMessage" style="display:none;">
%endif
${_("Your history is empty. Click 'Get Data' on the left pane to start")}
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/feb7438276fb
changeset: 2478:feb7438276fb
user: James Taylor <james(a)jamestaylor.org>
date: Mon Jul 13 13:08:52 2009 -0400
description:
Pre-compressing CSS with yui-compressor
10 file(s) affected in this change:
static/june_2007_style/blue/base.css
static/june_2007_style/blue/history.css
static/june_2007_style/blue/iphone.css
static/june_2007_style/blue/library.css
static/june_2007_style/blue/masthead.css
static/june_2007_style/blue/panel_layout.css
static/june_2007_style/blue/reset.css
static/june_2007_style/blue/tool_menu.css
static/june_2007_style/make_style.py
static/june_2007_style/panel_layout.css.tmpl
diffs (1871 lines):
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/blue/base.css Mon Jul 13 13:08:52 2009 -0400
@@ -1,645 +1,1 @@
-@import url( "reset.css" );
-
-body
-{
- font: 75% verdana, "Bitstream Vera Sans", geneva, arial, helvetica, helve, sans-serif;
- background: #FFFFFF;
- color: #303030;
- background-image: url(base_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- margin: 10px;
-}
-
-img
-{
- border: 0;
-}
-
-
-a:link, a:visited, a:active
-{
- color: #303030;
-}
-
-h1, h2, h3, h4
-{
- color: #023858;
- /*text-shadow: #bbb 2px 2px 1px;*/
-}
-
-hr
-{
- border: none;
- height: 0px;
- border-bottom: dotted #303030 1px;
-}
-
-div.toolForm
-{
- border: solid #d8b365 1px;
-}
-
-div.toolFormTitle
-{
- font-weight: bold;
- padding: 5px;
- padding-left: 10px;
- padding-right: 10px;
- background: #d2c099;
- background-image: url(form_title_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- border-bottom: solid #d8b365 1px;
-}
-
-div.toolParamHelp
-{
- color: #666;
-}
-
-div.toolParamHelp a
-{
- color: #666;
-}
-
-div.toolFormBody
-{
- background: #FFFFFF;
- background-image: url(form_body_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- padding: 5px 0;
-}
-
-div.toolFormBody div.toolFormTitle
-{
- background: transparent;
- border: none;
- font-weight: bold;
- border-bottom: solid #d8b365 1px;
- margin-bottom: 5px;
-}
-
-div.toolFormDisabled div.toolFormTitle {
- background: #eee;
- border-color: #999;
-}
-
-div.toolFormDisabled {
- border-color: #999;
-}
-
-div.toolHelp
-{
-}
-
-div.toolHelpBody
-{
- width: 100%;
- overflow: auto;
-}
-
-div.titleRow {
- font-weight: bold;
- border-bottom: dotted gray 1px;
- margin-bottom: 0.5em;
- padding-bottom: 0.25em;
-}
-
-/* Forms */
-
-div.form
-{
- border: solid #d8b365 1px;
-}
-
-div.form-title
-{
- font-weight: bold;
- padding: 5px 10px;
- background: #d2c099;
- background-image: url(form_title_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- border-bottom: solid #d8b365 1px;
-}
-
-div.form-body
-{
- padding: 5px 0;
-}
-
-div.form-row
-{
- padding: 5px 10px;
-}
-
-div.form-title-row
-{
- padding: 5px 10px;
-}
-
-div.repeat-group-item
-{
- border-left: solid #d8b365 5px;
- margin-left: 10px;
- margin-bottom: 10px;
-}
-
-div.form-row-error
-{
- background: #FFCCCC;
-}
-
-div.form-row label
-{
- font-weight: bold;
- display: block;
- margin-bottom: .2em;
-}
-
-div.form-row-input
-{
- float: left;
- width: 300px;
-}
-
-div.form-row-input > input
-{
- max-width: 300px;
-}
-
-div.form-row-error-message
-{
- width: 300px;
- float: left;
- color: red;
- font-weight: bold;
- padding: 3px 0 0 1em;
-}
-
-select, input, textarea
-{
- font: inherit;
- font-size: 115%;
-}
-
-select, textarea, input[type="text"], input[type="file"], input[type="password"]
-{
- -webkit-box-sizing: border-box;
- max-width: 300px;
-}
-
-/* Messages */
-
-.errormessage, .warningmessage, .donemessage, .infomessage, .welcomeBlue, .welcomeRed , .screencastBox, .yellowbox, .redbox, .bluebox, .greenbox
-{
- padding: 10px;
- padding-left: 52px;
- min-height: 32px;
- border: 1px solid #AA6666;
- background-color: #FFCCCC;
- background-image: url(error_message_icon.png);
- background-repeat: no-repeat;
- background-position: 10px 10px;
-}
-
-.warningmessage
-{
- background-image: url(warn_message_icon.png);
- border-color: #AAAA66;
- background-color: #FFFFCC;
-}
-
-.donemessage
-{
- background-image: url(done_message_icon.png);
- border-color: #66AA66;
- background-color: #CCFFCC;
-}
-
-.infomessage
-{
- background-image: url(info_message_icon.png);
- border-color: #6666AA;
- background-color: #CCCCFF;
-}
-
-.welcomeBlue
-{
- padding-left: 10px;
- border-color: #6666AA;
- background-color: #CCCCFF;
- background-image: none;
-}
-
-.welcomeRed
-{
- padding-left: 10px;
- border-color: #AA6666;
- background-color: #FFCCCC;
- background-image: none;
-}
-
-.screencastBox
-{
- padding-left: 10px;
- border-color: #AAAA66;
- background-color: #FFFFCC;
- background-image: none;
-}
-
-.redbox
-{
- border: none;
- padding: 10px;
- border-color: #000000;
- background-color: #FF6666;
- background-image: none;
- border-right-width: 1px;
- border-right-style: dotted;
- border-bottom-width: 1px;
- border-bottom-style: dotted;
- margin-top: 5px;
- min-height: 32px;
-
-}
-
-.yellowbox
-{
- border: none;
- padding: 10px;
- border-color: #000000;
- background-color: #FFCC00;
- background-image: none;
- border-right-width: 1px;
- border-right-style: dotted;
- border-bottom-width: 1px;
- border-bottom-style: dotted;
- margin-top: 5px;
- min-height: 32px;
-}
-
-.bluebox
-{
- border: none;
- padding: 10px;
- border-color: #000000;
- background-color: #6666FF;
- background-image: none;
- border-right-width: 1px;
- border-right-style: dotted;
- border-bottom-width: 1px;
- border-bottom-style: dotted;
- margin-top: 5px;
- color: #FFFFFF;
- min-height: 32px;
-}
-
-.greenbox
-{
- border: none;
- padding: 10px;
- border-color: #000000;
- background-color: #00CC00;
- background-image: none;
- border-right-width: 1px;
- border-right-style: dotted;
- border-bottom-width: 1px;
- border-bottom-style: dotted;
- margin-top: 5px;
- min-height: 32px;
-}
-
-.redbox li, .yellowbox li, .bluebox li, .greenbox li {
- list-style: disc;
- text-transform: none;
- list-style-position: inside;
- list-style-image: none;
- margin: 3px;
-}
-
-
-.errormessagesmall, .warningmessagesmall, .donemessagesmall, .infomessagesmall
-{
- padding: 5px;
- padding-left: 25px;
- min-height: 25px;
- border: 1px solid #AA6666;
- background-color: #FFCCCC;
- background-image: url(error_small.png);
- background-repeat: no-repeat;
- background-position: 5px 5px;
-}
-
-.warningmessagesmall
-{
- background-image: url(warn_small.png);
- border-color: #AAAA66;
- background-color: #FFFFCC;
-}
-
-.donemessagesmall
-{
- background-image: url(ok_small.png);
- border-color: #66AA66;
- background-color: #CCFFCC;
-}
-
-.infomessagesmall
-{
- background-image: url(info_small.png);
- border-color: #6666AA;
- background-color: #CCCCFF;
-}
-
-.errormark, .warningmark, .donemark, .infomark, .ok_bgr, .err_bgr
-{
- padding-left: 20px;
- min-height: 15px;
- background: url(error_small.png) no-repeat;
-}
-
-.warningmark
-{
- background-image: url(warn_small.png);
-}
-
-.donemark
-{
- background-image: url(ok_small.png);
-}
-
-.infomark, .ok_bgr
-{
- background-image: url(info_small.png);
-}
-
-table.colored
-{
- border-top: solid #d8b365 1px;
- border-bottom: solid #d8b365 1px;
-}
-
-table.colored td, table.colored th
-{
- text-align: left;
- padding: 5px;
-}
-
-table.colored tr.header
-{
- background: #ebd9b2;
- background-image: url(form_title_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- border-bottom: solid #d8b365 1px;
- font-weight: bold;
-}
-
-table.colored tr
-{
- background: white;
-}
-
-table.colored tr.odd_row
-{
- background: #DADFEF;
-}
-
-div.debug
-{
- margin: 10px;
- padding: 5px;
- background: #FFFF99;
- border: solid #FFFF33 1px;
- color: black;
-}
-
-div.odd_row
-{
- background: #DADFEF;
-}
-
-#footer {
- display: none;
-}
-
-
-td.panel-body
-{
- background: white;
- color: #303030;
- background: #C1C9E5 url(menu_bg.png) top repeat-x;
-}
-
-div.toolSectionPad
-{
- margin: 0;
- padding: 0;
- height: 5px;
- font-size: 0px;
-}
-
-div.toolSectionDetailsInner
-{
- margin-left: 5px;
- margin-right: 5px;
-}
-
-div.toolSectionTitle
-{
- padding-bottom: 0px;
- font-weight: bold;
-}
-
-div.toolTitle
-{
- padding-top: 5px;
- padding-bottom: 5px;
- margin-left: 16px;
- margin-right: 10px;
- display: list-item;
- list-style: square outside;
-}
-
-span.toolParameterExpandableCollapsable
-{
- font-weight: bold;
- cursor: pointer;
-}
-ul.toolParameterExpandableCollapsable
-{
- list-style: none;
-}
-
-ul.manage-table-actions {
- float: right;
- margin-top: -2.5em;
-}
-ul.manage-table-actions li {
- display: block;
- float: left;
- margin-left: 0.5em;
-}
-
-
-.state-color-queued {
- border-color: #888888;
- background: #EEEEEE;
-}
-
-.state-color-ok {
- border-color: #66AA66;
- background: #CCFFCC;
-}
-
-.state-color-error {
- border-color: #AA6666;
- background: #FFCCCC;
-}
-
-.state-color-running {
- border-color: #AAAA66;
- background: #FFFFCC;
-}
-
-.state-fg-queued {
- color: #888888;
-}
-.state-fg-ok {
- color: #66AA66;
-}
-.state-fg-running {
- color: #AAAA66;
-}
-.state-fg-error {
- color: #AA6666;
-}
-
-
-.action-button {
- background: #eeeeee;
- color: #333;
- text-decoration: none;
- font-size: 95%;
- font-weight: bold;
- display: inline-block;
- cursor: pointer;
- padding: 2px;
- border: solid #aaaaaa 1px;
- padding-right: 0.5em;
- padding-left: 0.5em;
- -moz-border-radius: 0.5em;
- -webkit-border-radius: 0.5em;
- border-radius: 0.5em;
- user-select: none;
- -moz-user-select: none;
- -webkit-user-select: none;
-}
-
-.action-button > * {
- vertical-align: middle;
-}
-
-.action-button:hover {
- color: black;
- background: #dddddd;
-}
-.action-button:active {
- color: white;
- background: #aaaaaa;
-}
-
-
-div.popupmenu {
- display: none;
- background: #eeeeee;
- color: #333;
- font-size: 110%;
- font-weight: bold;
- font-style: normal;
- white-space: nowrap;
- position: absolute;
- z-index: 20000;
- border: solid #aaaaaa 1px;
- padding: 3px 0;
- -moz-border-radius: 0.5em;
- -webkit-border-radius: 0.5em;
- border-radius: 0.5em;
- user-select: none;
- -moz-user-select: none;
- -webkit-user-select: none;
-}
-
-div.popupmenu-item {
- padding: 3px 1em;
- cursor: pointer;
-}
-
-div.popupmenu-item:hover {
- background: #aaaaaa;
-}
-
-.popup-arrow {
- font-size: 80%;
- cursor: pointer;
- text-decoration: none;
- color: #555
-}
-
-.popup-arrow:hover {
- color: black;
-}
-
-div.permissionContainer {
- padding-left: 20px;
-}
-
-
-.grid-header {
- padding-bottom: 1em;
-}
-
-.grid-header h2 {
- margin: 0;
- margin-bottom: 0.5em;
-}
-
-.grid-header .title {
- font-weight: bold;
-}
-
-.grid {
- padding-top: 1em;
- border-collapse: collapse;
- width: 100%;
-}
-.grid tbody td {
- border-top: solid #DDDDDD 1px;
- border-bottom: solid #DDDDDD 1px;
- padding: 0.5em 1em;
-}
-.grid tbody td:empty {
- padding: 0;
-}
-.grid thead th {
- background: #ebd9b2;
- background-image: url(form_title_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- border-top: solid #d8b365 1px;
- border-bottom: solid #d8b365 1px;
- padding: 0.5em 1em;
- text-align: left;
-}
-.grid tfoot td {
- background-color: #F8F8F8;
- border-top: solid #DDDDDD 1px;
- border-bottom: solid #DDDDDD 1px;
- padding: 0.5em 1em;
-}
-.grid .current {
- background-color: #EEEEFF;
-}
\ No newline at end of file
+@import url("reset.css");body{font:75% verdana,"Bitstream Vera Sans",geneva,arial,helvetica,helve,sans-serif;background:#FFF;color:#303030;background-image:url(base_bg.png);background-repeat:repeat-x;background-position:top;margin:10px;}img{border:0;}a:link,a:visited,a:active{color:#303030;}h1,h2,h3,h4{color:#023858;}hr{border:none;height:0;border-bottom:dotted #303030 1px;}div.toolForm{border:solid #d8b365 1px;}div.toolFormTitle{font-weight:bold;padding:5px;padding-left:10px;padding-right:10px;background:#d2c099;background-image:url(form_title_bg.png);background-repeat:repeat-x;background-position:top;border-bottom:solid #d8b365 1px;}div.toolParamHelp{color:#666;}div.toolParamHelp a{color:#666;}div.toolFormBody{background:#FFF;background-image:url(form_body_bg.png);background-repeat:repeat-x;background-position:top;padding:5px 0;}div.toolFormBody div.toolFormTitle{background:transparent;border:none;font-weight:bold;border-bottom:solid #d8b365 1px;margin-bottom:5px;}div.tool
FormDisabled div.toolFormTitle{background:#eee;border-color:#999;}div.toolFormDisabled{border-color:#999;}div.toolHelpBody{width:100%;overflow:auto;}div.titleRow{font-weight:bold;border-bottom:dotted gray 1px;margin-bottom:.5em;padding-bottom:.25em;}div.form{border:solid #d8b365 1px;}div.form-title{font-weight:bold;padding:5px 10px;background:#d2c099;background-image:url(form_title_bg.png);background-repeat:repeat-x;background-position:top;border-bottom:solid #d8b365 1px;}div.form-body{padding:5px 0;}div.form-row{padding:5px 10px;}div.form-title-row{padding:5px 10px;}div.repeat-group-item{border-left:solid #d8b365 5px;margin-left:10px;margin-bottom:10px;}div.form-row-error{background:#FCC;}div.form-row label{font-weight:bold;display:block;margin-bottom:.2em;}div.form-row-input{float:left;width:300px;}div.form-row-input>input{max-width:300px;}div.form-row-error-message{width:300px;float:left;color:red;font-weight:bold;padding:3px 0 0 1em;}select,input,textarea{font:inherit;fo
nt-size:115%;}select,textarea,input[type="text"],input[type="file"],input[type="password"]{-webkit-box-sizing:border-box;max-width:300px;}.errormessage,.warningmessage,.donemessage,.infomessage,.welcomeBlue,.welcomeRed,.screencastBox,.yellowbox,.redbox,.bluebox,.greenbox{padding:10px;padding-left:52px;min-height:32px;border:1px solid #A66;background-color:#FCC;background-image:url(error_message_icon.png);background-repeat:no-repeat;background-position:10px 10px;}.warningmessage{background-image:url(warn_message_icon.png);border-color:#AA6;background-color:#FFC;}.donemessage{background-image:url(done_message_icon.png);border-color:#6A6;background-color:#CFC;}.infomessage{background-image:url(info_message_icon.png);border-color:#66A;background-color:#CCF;}.welcomeBlue{padding-left:10px;border-color:#66A;background-color:#CCF;background-image:none;}.welcomeRed{padding-left:10px;border-color:#A66;background-color:#FCC;background-image:none;}.screencastBox{padding-left:10px;borde
r-color:#AA6;background-color:#FFC;background-image:none;}.redbox{border:none;padding:10px;border-color:#000;background-color:#F66;background-image:none;border-right-width:1px;border-right-style:dotted;border-bottom-width:1px;border-bottom-style:dotted;margin-top:5px;min-height:32px;}.yellowbox{border:none;padding:10px;border-color:#000;background-color:#FC0;background-image:none;border-right-width:1px;border-right-style:dotted;border-bottom-width:1px;border-bottom-style:dotted;margin-top:5px;min-height:32px;}.bluebox{border:none;padding:10px;border-color:#000;background-color:#66F;background-image:none;border-right-width:1px;border-right-style:dotted;border-bottom-width:1px;border-bottom-style:dotted;margin-top:5px;color:#FFF;min-height:32px;}.greenbox{border:none;padding:10px;border-color:#000;background-color:#0C0;background-image:none;border-right-width:1px;border-right-style:dotted;border-bottom-width:1px;border-bottom-style:dotted;margin-top:5px;min-height:32px;}.redbo
x li,.yellowbox li,.bluebox li,.greenbox li{list-style:disc;text-transform:none;list-style-position:inside;list-style-image:none;margin:3px;}.errormessagesmall,.warningmessagesmall,.donemessagesmall,.infomessagesmall{padding:5px;padding-left:25px;min-height:25px;border:1px solid #A66;background-color:#FCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:5px 5px;}.warningmessagesmall{background-image:url(warn_small.png);border-color:#AA6;background-color:#FFC;}.donemessagesmall{background-image:url(ok_small.png);border-color:#6A6;background-color:#CFC;}.infomessagesmall{background-image:url(info_small.png);border-color:#66A;background-color:#CCF;}.errormark,.warningmark,.donemark,.infomark,.ok_bgr,.err_bgr{padding-left:20px;min-height:15px;background:url(error_small.png) no-repeat;}.warningmark{background-image:url(warn_small.png);}.donemark{background-image:url(ok_small.png);}.infomark,.ok_bgr{background-image:url(info_small.png);}table.c
olored{border-top:solid #d8b365 1px;border-bottom:solid #d8b365 1px;}table.colored td,table.colored th{text-align:left;padding:5px;}table.colored tr.header{background:#ebd9b2;background-image:url(form_title_bg.png);background-repeat:repeat-x;background-position:top;border-bottom:solid #d8b365 1px;font-weight:bold;}table.colored tr{background:white;}table.colored tr.odd_row{background:#DADFEF;}div.debug{margin:10px;padding:5px;background:#FF9;border:solid #FF3 1px;color:black;}div.odd_row{background:#DADFEF;}#footer{display:none;}td.panel-body{background:white;color:#303030;background:#C1C9E5 url(menu_bg.png) top repeat-x;}div.toolSectionPad{margin:0;padding:0;height:5px;font-size:0;}div.toolSectionDetailsInner{margin-left:5px;margin-right:5px;}div.toolSectionTitle{padding-bottom:0;font-weight:bold;}div.toolTitle{padding-top:5px;padding-bottom:5px;margin-left:16px;margin-right:10px;display:list-item;list-style:square outside;}span.toolParameterExpandableCollapsable{font-weigh
t:bold;cursor:pointer;}ul.toolParameterExpandableCollapsable{list-style:none;}ul.manage-table-actions{float:right;margin-top:-2.5em;}ul.manage-table-actions li{display:block;float:left;margin-left:.5em;}.state-color-queued{border-color:#888;background:#EEE;}.state-color-ok{border-color:#6A6;background:#CFC;}.state-color-error{border-color:#A66;background:#FCC;}.state-color-running{border-color:#AA6;background:#FFC;}.state-fg-queued{color:#888;}.state-fg-ok{color:#6A6;}.state-fg-running{color:#AA6;}.state-fg-error{color:#A66;}.action-button{background:#eee;color:#333;text-decoration:none;font-size:95%;font-weight:bold;display:inline-block;cursor:pointer;padding:2px;border:solid #aaa 1px;padding-right:.5em;padding-left:.5em;-moz-border-radius:.5em;-webkit-border-radius:.5em;border-radius:.5em;user-select:none;-moz-user-select:none;-webkit-user-select:none;}.action-button>*{vertical-align:middle;}.action-button:hover{color:black;background:#ddd;}.action-button:active{color:whit
e;background:#aaa;}div.popupmenu{display:none;background:#eee;color:#333;font-size:110%;font-weight:bold;font-style:normal;white-space:nowrap;position:absolute;z-index:20000;border:solid #aaa 1px;padding:3px 0;-moz-border-radius:.5em;-webkit-border-radius:.5em;border-radius:.5em;user-select:none;-moz-user-select:none;-webkit-user-select:none;}div.popupmenu-item{padding:3px 1em;cursor:pointer;}div.popupmenu-item:hover{background:#aaa;}.popup-arrow{font-size:80%;cursor:pointer;text-decoration:none;color:#555;}.popup-arrow:hover{color:black;}div.permissionContainer{padding-left:20px;}.grid-header{padding-bottom:1em;}.grid-header h2{margin:0;margin-bottom:.5em;}.grid-header .title{font-weight:bold;}.grid{padding-top:1em;border-collapse:collapse;width:100%;}.grid tbody td{border-top:solid #DDD 1px;border-bottom:solid #DDD 1px;padding:.5em 1em;}.grid tbody td:empty{padding:0;}.grid thead th{background:#ebd9b2;background-image:url(form_title_bg.png);background-repeat:repeat-x;backg
round-position:top;border-top:solid #d8b365 1px;border-bottom:solid #d8b365 1px;padding:.5em 1em;text-align:left;}.grid tfoot td{background-color:#F8F8F8;border-top:solid #DDD 1px;border-bottom:solid #DDD 1px;padding:.5em 1em;}.grid .current{background-color:#EEF;}
\ No newline at end of file
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/blue/history.css
--- a/static/june_2007_style/blue/history.css Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/blue/history.css Mon Jul 13 13:08:52 2009 -0400
@@ -1,117 +1,1 @@
-body
-{
- background: #C1C9E5;
- color: #303030;
- background-image: url(menu_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- margin: 5px;
- border: 0;
- padding: 0;
-}
-
-a
-{
- color: #base_text;
-}
-
-div.historyLinks
-{
- padding: 5px;
- margin-top: 5px;
- margin-bottom: 5px;
- padding-right: 5px;
- padding-left: 5px;
- margin-bottom: 5px;
-}
-
-div.historyItem
-{
- margin-right: -5px;
- margin-top: 5px;
- margin-bottom: 5px;
- padding: 5px;
- padding-right: 11px;
-
- border: solid #888888 1px;
- border-left: solid #888888 5px;
- border-right: none;
- background: #EEEEEE;
- background-image: url(gray_bg.png);
- background-repeat: repeat-x;
- background-position: top;
-}
-
-div.historyItem div.historyItem
-{
- margin-right: -11px;
-}
-
-div.historyItem-ok
-{
- border-color: #66AA66;
- background: #CCFFCC;
- /*
- background-image: url(ok_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- */
-}
-
-div.historyItem-error, div.historyItem-empty
-{
- border-color: #AA6666;
- background: #FFCCCC;
- /*
- background-image: url(error_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- */
-}
-
-div.historyItem-running
-{
- border-color: #AAAA66;
- background: #FFFFCC;
- /*
- background-image: url(warn_bg.png);
- background-repeat: repeat-x;
- background-position: top;
- */
-}
-
-div.historyItem-upload
-{
- border-color: #6666AA;
- background: #CCCCFF;
-}
-
-div.historyItem-noPermission
-{
- filter: alpha(opacity=60);
- -moz-opacity: .60;
- opacity: .60;
-}
-
-div.historyItem-queued
-{
-}
-
-div.historyItemBody div
-{
- padding-top: 2px;
-}
-
-pre.peek
-{
- background: white;
- color: black;
- width: 100%;
- overflow: auto;
-}
-
-pre.peek th
-{
- color: white;
- background: #023858;
-}
+body{background:#C1C9E5;color:#303030;background-image:url(menu_bg.png);background-repeat:repeat-x;background-position:top;margin:5px;border:0;padding:0;}a{color:#base_text;}div.historyLinks{padding:5px;margin-top:5px;margin-bottom:5px;padding-right:5px;padding-left:5px;margin-bottom:5px;}div.historyItem{margin-right:-5px;margin-top:5px;margin-bottom:5px;padding:5px;padding-right:11px;border:solid #888 1px;border-left:solid #888 5px;border-right:none;background:#EEE;background-image:url(gray_bg.png);background-repeat:repeat-x;background-position:top;}div.historyItem div.historyItem{margin-right:-11px;}div.historyItem-ok{border-color:#6A6;background:#CFC;}div.historyItem-error,div.historyItem-empty{border-color:#A66;background:#FCC;}div.historyItem-running{border-color:#AA6;background:#FFC;}div.historyItem-upload{border-color:#66A;background:#CCF;}div.historyItem-noPermission{filter:alpha(opacity=60);-moz-opacity:.60;opacity:.60;}div.historyItemBody div{padding-top:2px;}pre.p
eek{background:white;color:black;width:100%;overflow:auto;}pre.peek th{color:white;background:#023858;}
\ No newline at end of file
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/blue/iphone.css
--- a/static/june_2007_style/blue/iphone.css Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/blue/iphone.css Mon Jul 13 13:08:52 2009 -0400
@@ -1,433 +1,1 @@
-
-body {
- margin: 0;
- font-family: Helvetica;
- background: #FFFFFF;
- color: #000000;
- overflow-x: hidden;
- -webkit-user-select: none;
- -webkit-text-size-adjust: none;
-}
-
-body > *:not(.toolbar) {
- display: none;
- position: absolute;
- margin: 0;
- padding: 0;
- left: 0;
- width: 100%;
- min-height: 372px;
-}
-
-body[orient="landscape"] > *:not(.toolbar) {
- min-height: 268px;
-}
-
-body > *[selected="true"] {
- display: block;
-}
-
-a[selected], a:active {
- background-color: #194fdb !important;
- background-image: url(../iui/listArrowSel.png), url(../iui/selection.png) !important;
- background-repeat: no-repeat, repeat-x;
- background-position: right center, left top;
- color: #FFFFFF !important;
-}
-
-a[selected="progress"] {
- background-image: url(../iui/loading.gif), url(../iui/selection.png) !important;
-}
-
-/************************************************************************************************/
-
-body > .toolbar {
- position: relative;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- border-bottom: 1px solid #2d3642;
- padding: 10px;
- height: 45px;
- background: url(../iui/toolbar.png) #6d84a2 repeat-x;
-}
-
-.toolbar > h1 {
- position: absolute;
- overflow: hidden;
- left: 50%;
- margin: 1px 0 0 -75px;
- height: 45px;
- font-size: 20px;
- width: 150px;
- font-weight: bold;
- text-shadow: rgba(0, 0, 0, 0.4) 0px -1px 0;
- text-align: center;
- text-overflow: ellipsis;
- white-space: nowrap;
- color: #FFFFFF;
-}
-
-body[orient="landscape"] > .toolbar > h1 {
- margin-left: -125px;
- width: 250px;
-}
-
-body > .toolbar.masthead {
- background: #2C3143 repeat-x;
-}
-
-body > .toolbar.masthead > h1 {
- left: 0; margin-left: 0; width: 100%;
-}
-
-
-.button {
- position: absolute;
- overflow: hidden;
- top: 8px;
- right: 6px;
- margin: 0;
- border-width: 0 5px;
- padding: 0 3px;
- width: auto;
- height: 30px;
- line-height: 30px;
- font-family: inherit;
- font-size: 12px;
- font-weight: bold;
- color: #FFFFFF;
- text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0;
- text-overflow: ellipsis;
- text-decoration: none;
- white-space: nowrap;
- background: none;
- -webkit-border-image: url(../iui/toolButton.png) 0 5 0 5;
-}
-
-.blueButton {
- -webkit-border-image: url(../iui/blueButton.png) 0 5 0 5;
- border-width: 0 5px;
-}
-
-.leftButton {
- left: 6px;
- right: auto;
-}
-
-#backButton {
- display: none;
- left: 6px;
- right: auto;
- padding: 0;
- max-width: 55px;
- border-width: 0 8px 0 14px;
- -webkit-border-image: url(../iui/backButton.png) 0 8 0 14;
-}
-
-.whiteButton,
-.grayButton {
- display: block;
- border-width: 0 12px;
- padding: 10px;
- text-align: center;
- font-size: 20px;
- font-weight: bold;
- text-decoration: inherit;
- color: inherit;
-}
-
-.whiteButton {
- -webkit-border-image: url(../iui/whiteButton.png) 0 12 0 12;
- text-shadow: rgba(255, 255, 255, 0.7) 0 1px 0;
-}
-
-.grayButton {
- -webkit-border-image: url(../iui/grayButton.png) 0 12 0 12;
- color: #FFFFFF;
-}
-
-/************************************************************************************************/
-
-body > ul > li {
- position: relative;
- margin: 0;
- border-bottom: 1px solid #E0E0E0;
- padding: 8px 0 8px 10px;
- font-size: 20px;
- font-weight: bold;
- list-style: none;
-}
-
-body > ul > li.group {
- position: relative;
- top: -1px;
- margin-bottom: -2px;
- border-top: 1px solid #7d7d7d;
- border-bottom: 1px solid #999999;
- padding: 1px 10px;
- background: url(../iui/listGroup.png) repeat-x;
- font-size: 17px;
- font-weight: bold;
- text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
- color: #FFFFFF;
-}
-
-body > ul > li.group:first-child {
- top: 0;
- border-top: none;
-}
-
-body > ul > li > a {
- display: block;
- margin: -8px 0 -8px -10px;
- padding: 8px 32px 8px 10px;
- text-decoration: none;
- color: inherit;
- background: url(../iui/listArrow.png) no-repeat right center;
-}
-
-a[target="_replace"] {
- box-sizing: border-box;
- -webkit-box-sizing: border-box;
- padding-top: 25px;
- padding-bottom: 25px;
- font-size: 18px;
- color: cornflowerblue;
- background-color: #FFFFFF;
- background-image: none;
-}
-
-/************************************************************************************************/
-
-body > .dialog {
- top: 0;
- width: 100%;
- min-height: 417px;
- z-index: 2;
- background: rgba(0, 0, 0, 0.8);
- padding: 0;
- text-align: right;
-}
-
-.dialog > fieldset {
- box-sizing: border-box;
- -webkit-box-sizing: border-box;
- width: 100%;
- margin: 0;
- border: none;
- border-top: 1px solid #6d84a2;
- padding: 10px 6px;
- background: url(../iui/toolbar.png) #7388a5 repeat-x;
-}
-
-.dialog > fieldset > h1 {
- margin: 0 10px 0 10px;
- padding: 0;
- font-size: 20px;
- font-weight: bold;
- color: #FFFFFF;
- text-shadow: rgba(0, 0, 0, 0.4) 0px -1px 0;
- text-align: center;
-}
-
-.dialog > fieldset > label {
- position: absolute;
- margin: 16px 0 0 6px;
- font-size: 14px;
- color: #999999;
-}
-
-
-
-input:not(input[type|=radio]):not(input[type|=checkbox]) {
- box-sizing: border-box;
- -webkit-box-sizing: border-box;
- width: 100%;
- margin: 8px 0 0 0;
- padding: 6px 6px 6px 44px;
- font-size: 16px;
- font-weight: normal;
-}
-
-/************************************************************************************************/
-
-body > .panel {
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- padding: 10px;
- background: #c8c8c8 url(../iui/pinstripes.png);
-}
-
-.panel > fieldset {
- position: relative;
- margin: 0 0 20px 0;
- padding: 0;
- background: #FFFFFF;
- -webkit-border-radius: 10px;
- -moz-border-radius: 10px;
- border: 1px solid #999999;
- text-align: right;
- font-size: 16px;
-}
-
-.row {
- position: relative;
- min-height: 42px;
- border-bottom: 1px solid #999999;
- -webkit-border-radius: 0;
- text-align: right;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-fieldset > .row:last-child {
- border-bottom: none !important;
-}
-
-.row > input:not(input[type|=radio]):not(input[type|=checkbox]) {
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- margin: 0;
- border: none;
- padding: 12px 10px 0 110px;
- height: 42px;
- background: none;
-}
-.row > input[type|=radio], .row > input[type|=checkbox] {
- margin: 7px 7px 0 0;
- height: 25px;
- width: 25px;
-}
-
-.row > label {
- position: absolute;
- margin: 0 0 0 14px;
- line-height: 42px;
- font-weight: bold;
-}
-
-.row > a {
- font-weight: bold;
- text-align: left;
- display: block;
- padding: 8px 32px 8px 14px;
- text-decoration: none;
- color: inherit;
- background: url(../iui/listArrow.png) no-repeat right center;
-}
-
-.row > .error {
- height: 25px;
- text-align: left;
- font-size: 14px;
- padding: 0 0 0 110px;
- color: red;
-}
-
-.row > span {
- position: absolute;
- padding: 12px 10px 0 110px;
- margin: 0;
-}
-
-.row > .toggle {
- position: absolute;
- top: 6px;
- right: 6px;
- width: 100px;
- height: 28px;
-}
-
-.toggle {
- border: 1px solid #888888;
- -webkit-border-radius: 6px;
- background: #FFFFFF url(../iui/toggle.png) repeat-x;
- font-size: 19px;
- font-weight: bold;
- line-height: 30px;
-}
-
-.toggle[toggled="true"] {
- border: 1px solid #143fae;
- background: #194fdb url(../iui/toggleOn.png) repeat-x;
-}
-
-.toggleOn {
- display: none;
- position: absolute;
- width: 60px;
- text-align: center;
- left: 0;
- top: 0;
- color: #FFFFFF;
- text-shadow: rgba(0, 0, 0, 0.4) 0px -1px 0;
-}
-
-.toggleOff {
- position: absolute;
- width: 60px;
- text-align: center;
- right: 0;
- top: 0;
- color: #666666;
-}
-
-.toggle[toggled="true"] > .toggleOn {
- display: block;
-}
-
-.toggle[toggled="true"] > .toggleOff {
- display: none;
-}
-
-.thumb {
- position: absolute;
- top: -1px;
- left: -1px;
- width: 40px;
- height: 28px;
- border: 1px solid #888888;
- -webkit-border-radius: 6px;
- background: #ffffff url(../iui/thumb.png) repeat-x;
-}
-
-.toggle[toggled="true"] > .thumb {
- left: auto;
- right: -1px;
-}
-
-.panel > h2 {
- margin: 0 0 8px 14px;
- font-size: inherit;
- font-weight: bold;
- color: #4d4d70;
- text-shadow: rgba(255, 255, 255, 0.75) 2px 2px 0;
-}
-
-/************************************************************************************************/
-
-#preloader {
- display: none;
- background-image: url(loading.gif), url(selection.png),
- url(blueButton.png), url(listArrowSel.png), url(listGroup.png);
-}
-
-
-.state-color-queued {
- background: #EEEEEE;
-}
-
-.state-color-ok {
- background: #CCFFCC;
-}
-
-.state-color-error {
- background: #FFCCCC;
-}
-
-.state-color-running {
- background: #FFFFCC;
-}
+body{margin:0;font-family:Helvetica;background:#FFF;color:#000;overflow-x:hidden;-webkit-user-select:none;-webkit-text-size-adjust:none;}body>*:not(.toolbar){display:none;position:absolute;margin:0;padding:0;left:0;width:100%;min-height:372px;}body[orient="landscape"]>*:not(.toolbar){min-height:268px;}body>*[selected="true"]{display:block;}a[selected],a:active{background-color:#194fdb!important;background-image:url(../iui/listArrowSel.png),url(../iui/selection.png)!important;background-repeat:no-repeat,repeat-x;background-position:right center,left top;color:#FFF!important;}a[selected="progress"]{background-image:url(../iui/loading.gif),url(../iui/selection.png)!important;}body>.toolbar{position:relative;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;border-bottom:1px solid #2d3642;padding:10px;height:45px;background:url(../iui/toolbar.png) #6d84a2 repeat-x;}.toolbar>h1{position:absolute;overflow:hidden;left:50%;margin:1px 0 0 -75px;height:45p
x;font-size:20px;width:150px;font-weight:bold;text-shadow:rgba(0,0,0,0.4) 0 -1px 0;text-align:center;text-overflow:ellipsis;white-space:nowrap;color:#FFF;}body[orient="landscape"]>.toolbar>h1{margin-left:-125px;width:250px;}body>.toolbar.masthead{background:#2C3143 repeat-x;}body>.toolbar.masthead>h1{left:0;margin-left:0;width:100%;}.button{position:absolute;overflow:hidden;top:8px;right:6px;margin:0;border-width:0 5px;padding:0 3px;width:auto;height:30px;line-height:30px;font-family:inherit;font-size:12px;font-weight:bold;color:#FFF;text-shadow:rgba(0,0,0,0.6) 0 -1px 0;text-overflow:ellipsis;text-decoration:none;white-space:nowrap;background:none;-webkit-border-image:url(../iui/toolButton.png) 0 5 0 5;}.blueButton{-webkit-border-image:url(../iui/blueButton.png) 0 5 0 5;border-width:0 5px;}.leftButton{left:6px;right:auto;}#backButton{display:none;left:6px;right:auto;padding:0;max-width:55px;border-width:0 8px 0 14px;-webkit-border-image:url(../iui/backButton.png) 0 8 0 14;}.
whiteButton,.grayButton{display:block;border-width:0 12px;padding:10px;text-align:center;font-size:20px;font-weight:bold;text-decoration:inherit;color:inherit;}.whiteButton{-webkit-border-image:url(../iui/whiteButton.png) 0 12 0 12;text-shadow:rgba(255,255,255,0.7) 0 1px 0;}.grayButton{-webkit-border-image:url(../iui/grayButton.png) 0 12 0 12;color:#FFF;}body>ul>li{position:relative;margin:0;border-bottom:1px solid #E0E0E0;padding:8px 0 8px 10px;font-size:20px;font-weight:bold;list-style:none;}body>ul>li.group{position:relative;top:-1px;margin-bottom:-2px;border-top:1px solid #7d7d7d;border-bottom:1px solid #999;padding:1px 10px;background:url(../iui/listGroup.png) repeat-x;font-size:17px;font-weight:bold;text-shadow:rgba(0,0,0,0.4) 0 1px 0;color:#FFF;}body>ul>li.group:first-child{top:0;border-top:none;}body>ul>li>a{display:block;margin:-8px 0 -8px -10px;padding:8px 32px 8px 10px;text-decoration:none;color:inherit;background:url(../iui/listArrow.png) no-repeat right center;}
a[target="_replace"]{box-sizing:border-box;-webkit-box-sizing:border-box;padding-top:25px;padding-bottom:25px;font-size:18px;color:cornflowerblue;background-color:#FFF;background-image:none;}body>.dialog{top:0;width:100%;min-height:417px;z-index:2;background:rgba(0,0,0,0.8);padding:0;text-align:right;}.dialog>fieldset{box-sizing:border-box;-webkit-box-sizing:border-box;width:100%;margin:0;border:none;border-top:1px solid #6d84a2;padding:10px 6px;background:url(../iui/toolbar.png) #7388a5 repeat-x;}.dialog>fieldset>h1{margin:0 10px 0 10px;padding:0;font-size:20px;font-weight:bold;color:#FFF;text-shadow:rgba(0,0,0,0.4) 0 -1px 0;text-align:center;}.dialog>fieldset>label{position:absolute;margin:16px 0 0 6px;font-size:14px;color:#999;}input:not(input[type|=radio]):not(input[type|=checkbox]){box-sizing:border-box;-webkit-box-sizing:border-box;width:100%;margin:8px 0 0 0;padding:6px 6px 6px 44px;font-size:16px;font-weight:normal;}body>.panel{box-sizing:border-box;-moz-box-sizing:b
order-box;-webkit-box-sizing:border-box;padding:10px;background:#c8c8c8 url(../iui/pinstripes.png);}.panel>fieldset{position:relative;margin:0 0 20px 0;padding:0;background:#FFF;-webkit-border-radius:10px;-moz-border-radius:10px;border:1px solid #999;text-align:right;font-size:16px;}.row{position:relative;min-height:42px;border-bottom:1px solid #999;-webkit-border-radius:0;text-align:right;overflow:hidden;text-overflow:ellipsis;}fieldset>.row:last-child{border-bottom:none!important;}.row>input:not(input[type|=radio]):not(input[type|=checkbox]){box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;margin:0;border:none;padding:12px 10px 0 110px;height:42px;background:none;}.row>input[type|=radio],.row>input[type|=checkbox]{margin:7px 7px 0 0;height:25px;width:25px;}.row>label{position:absolute;margin:0 0 0 14px;line-height:42px;font-weight:bold;}.row>a{font-weight:bold;text-align:left;display:block;padding:8px 32px 8px 14px;text-decoration:none;color:i
nherit;background:url(../iui/listArrow.png) no-repeat right center;}.row>.error{height:25px;text-align:left;font-size:14px;padding:0 0 0 110px;color:red;}.row>span{position:absolute;padding:12px 10px 0 110px;margin:0;}.row>.toggle{position:absolute;top:6px;right:6px;width:100px;height:28px;}.toggle{border:1px solid #888;-webkit-border-radius:6px;background:#FFF url(../iui/toggle.png) repeat-x;font-size:19px;font-weight:bold;line-height:30px;}.toggle[toggled="true"]{border:1px solid #143fae;background:#194fdb url(../iui/toggleOn.png) repeat-x;}.toggleOn{display:none;position:absolute;width:60px;text-align:center;left:0;top:0;color:#FFF;text-shadow:rgba(0,0,0,0.4) 0 -1px 0;}.toggleOff{position:absolute;width:60px;text-align:center;right:0;top:0;color:#666;}.toggle[toggled="true"]>.toggleOn{display:block;}.toggle[toggled="true"]>.toggleOff{display:none;}.thumb{position:absolute;top:-1px;left:-1px;width:40px;height:28px;border:1px solid #888;-webkit-border-radius:6px;background:
#fff url(../iui/thumb.png) repeat-x;}.toggle[toggled="true"]>.thumb{left:auto;right:-1px;}.panel>h2{margin:0 0 8px 14px;font-size:inherit;font-weight:bold;color:#4d4d70;text-shadow:rgba(255,255,255,0.75) 2px 2px 0;}#preloader{display:none;background-image:url(loading.gif),url(selection.png),url(blueButton.png),url(listArrowSel.png),url(listGroup.png);}.state-color-queued{background:#EEE;}.state-color-ok{background:#CFC;}.state-color-error{background:#FCC;}.state-color-running{background:#FFC;}
\ No newline at end of file
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/blue/library.css
--- a/static/june_2007_style/blue/library.css Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/blue/library.css Mon Jul 13 13:08:52 2009 -0400
@@ -1,75 +1,1 @@
-.libraryRow {
- background-color: #d2c099;
-}
-
-.datasetHighlighted {
- background-color: #C1C9E5;
-}
-
-.libraryItemDeleted-True {
- font-style: italic;
-}
-
-div.historyItemBody {
- padding: 4px 4px 2px 4px;
-}
-
-li.folderRow,
-li.datasetRow
-{
- border-top: solid 1px #ddd;
-}
-
-li.folderRow:hover,
-li.datasetRow:hover
-{
- background-color: #C1C9E5;
-}
-
-img.expanderIcon {
- padding-right: 4px;
-}
-
-input.datasetCheckbox,
-li, ul
-{
- padding: 0;
- margin: 0;
-}
-
-.rowTitle
-{
- padding: 2px;
-}
-
-ul {
- list-style: none;
-}
-
-.libraryTitle th {
- text-align: left;
-}
-
-pre.peek
-{
- background: white;
- color: black;
- width: 100%;
- overflow: auto;
-}
-
-pre.peek th
-{
- color: white;
- background: #023858;
-}
-
-a.expandLink {
- text-decoration: none;
-}
-
-span.expandLink {
- width: 100%;
- height: 100%;
- display: block;
-}
+.libraryRow{background-color:#d2c099;}.datasetHighlighted{background-color:#C1C9E5;}.libraryItemDeleted-True{font-style:italic;}div.historyItemBody{padding:4px 4px 2px 4px;}li.folderRow,li.datasetRow{border-top:solid 1px #ddd;}li.folderRow:hover,li.datasetRow:hover{background-color:#C1C9E5;}img.expanderIcon{padding-right:4px;}input.datasetCheckbox,li,ul{padding:0;margin:0;}.rowTitle{padding:2px;}ul{list-style:none;}.libraryTitle th{text-align:left;}pre.peek{background:white;color:black;width:100%;overflow:auto;}pre.peek th{color:white;background:#023858;}a.expandLink{text-decoration:none;}span.expandLink{width:100%;height:100%;display:block;}
\ No newline at end of file
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/blue/masthead.css
--- a/static/june_2007_style/blue/masthead.css Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/blue/masthead.css Mon Jul 13 13:08:52 2009 -0400
@@ -1,62 +1,1 @@
-body
-{
- background: #2C3143 url(masthead_bg.png) bottom;
- color: #eeeeee;
- padding: 0;
- border: 0;
- margin: 3px;
- margin-right: 5px;
- margin-left: 5px;
- overflow: hidden;
-}
-
-div.pageTitle
-{
- font-size: 175%;
- font-weight: bold;
-}
-
-div.pageTitle a:link, div.pageTitle a:visited, div.pageTitle a:active, div.pageTitle a:hover
-{
- text-decoration: none;
-}
-
-a:link, a:visited, a:active
-{
- color: #eeeeee;
-}
-
-#tab-bar-bottom
-{
- z-index: -1;
- position:absolute;
- top:27px; left: 0;
- width: 100%;
- height: 100%;
- background: #222532;
-}
-
-span.link-group
-{
- margin: 0;
- padding: 0;
- display: inline;
- padding-bottom: 10px;
- margin-bottom: -10px;
-}
-
-span.link-group span
-{
- margin: 0;
- padding: 0;
- display: inline;
-}
-
-span.link-group span.active-link
-{
- background: #222532;
- padding-left: 3px; padding-right: 3px;
- margin-left: -3px; margin-right: -3px;
- padding-bottom: 10px;
- margin-bottom: -10px;
-}
\ No newline at end of file
+body{background:#2C3143 url(masthead_bg.png) bottom;color:#eee;padding:0;border:0;margin:3px;margin-right:5px;margin-left:5px;overflow:hidden;}div.pageTitle{font-size:175%;font-weight:bold;}div.pageTitle a:link,div.pageTitle a:visited,div.pageTitle a:active,div.pageTitle a:hover{text-decoration:none;}a:link,a:visited,a:active{color:#eee;}#tab-bar-bottom{z-index:-1;position:absolute;top:27px;left:0;width:100%;height:100%;background:#222532;}span.link-group{margin:0;padding:0;display:inline;padding-bottom:10px;margin-bottom:-10px;}span.link-group span{margin:0;padding:0;display:inline;}span.link-group span.active-link{background:#222532;padding-left:3px;padding-right:3px;margin-left:-3px;margin-right:-3px;padding-bottom:10px;margin-bottom:-10px;}
\ No newline at end of file
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/blue/panel_layout.css
--- a/static/june_2007_style/blue/panel_layout.css Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/blue/panel_layout.css Mon Jul 13 13:08:52 2009 -0400
@@ -1,340 +1,1 @@
-body, html
-{
- overflow: hidden;
- margin: 0;
- padding: 0;
- width: 100%;
- height: 100%;
-}
-body
-{
- font: 75% verdana, "Bitstream Vera Sans", geneva, arial, helvetica, helve, sans-serif;
- background: #eee;
-}
-#background
-{
- position: absolute;
- background: #eee;
- z-index: -1;
- top: 0;
- left: 0;
- margin: 0;
- padding: 0;
- width: 100%;
- height: 100%;
-}
-
-#messagebox
-{
- position:absolute;
- top:33px;
- left:0;
- width:100%;
- height:24px !important;
- overflow: hidden;
- border-bottom: solid #999 1px;
- font-size: 90%;
-}
-
-#left, #left-border, #center, #right-border, #right
-{
- position: absolute;
- top: 39px;
- bottom: 0px;
- overflow: hidden;
- background: #fff;
-}
-#left, #center, #right
-{
- border-top: solid #999 1px;
-}
-#left-border, #right-border
-{
- background: #eeeeee;
- border-left: solid #999 1px;
- border-right: solid #999 1px;
- padding-right: 1px;
- padding-left: 1px;
- width: 5px;
- z-index: 10000;
-}
-#left-border div, #right-border div
-{
- width: 100%;
- height: 100%;
- background-repeat: no-repeat;
- background-position: center center;
- position: absolute;
- width: 5px;
- height: 100%;
-}
-#left-border div, #right-border.hidden div
-{
- background-image: url(tiny_arrow_left.png);
- cursor: w-resize;
-}
-#left-border.hidden div, #right-border div
-{
- background-image: url(tiny_arrow_right.png);
- cursor: e-resize;
-}
-#left-border.hover div, #right-border.hover div
-{
- background-color: #AAAAEE;
-}
-#left
-{
- left: 0px;
- width: 250px;
- z-index: 200;
-}
-#left-border
-{
- left: 250px;
-}
-#center
-{
- left:259px;
- right: 259px;
- overflow: hidden;
- z-index: 1;
-}
-#right-border
-{
- right: 250px;
-}
-#right
-{
- width: 250px;
- right: 0px;
- z-index: 200;
-}
-
-.unified-panel-header {
- height: 2em;
- z-index: 1000;
- background: #cccccc;
- background-image: url(panel_header_bg.png);
- background-position: top center;
- background-repeat: repeat-x;
- border-bottom: solid #999 1px;
- margin: 0;
- padding: 0;
- padding-right: 10px;
- padding-left: 10px;
- color: #333;
- font-weight: bold;
- user-select: none;
- -moz-user-select: none;
- -webkit-user-select: none;
-}
-
-.unified-panel-header-inner {
- padding-top: 0.45em;
-}
-
-.menu-bg {
- background: #C1C9E5 url(menu_bg.png) top repeat-x;
-}
-
-div.unified-panel-body {
- position: absolute;
- top: 2em;
- bottom: 0;
- width: 100%;
- margin-top: 1px;
-}
-
-.panel-header-button {
- color: #333;
- text-decoration: none;
- display: inline-block;
- cursor: pointer;
- margin: -1px; padding: 1px;
- border: 0px;
- padding-right: 0.5em;
- padding-left: 0.5em;
- -moz-border-radius: 0.5em;
- -webkit-border-radius: 0.5em;
- border-radius: 0.5em;
- background: transparent;
-}
-
-.panel-header-button:hover {
- color: black;
- background: #aaaaaa;
-}
-
-.panel-header-button:active {
- color: white;
- background: #aaaaaa;
-}
-
-#overlay {
- position: fixed;
- top: 0; left: 0; width: 100%; height: 100%;
- z-index: 20000;
-}
-
-.dialog-box-container {
- position: relative;
- margin-top: 80px;
- margin-right: auto;
- margin-left: auto;
-}
-
-.dialog-box-wrapper {
- position: relative;
- padding: 1em;
- background-color: rgba(0,0,0,0.5);
- -moz-border-radius: 1em;
- -webkit-border-radius: 1em;
-}
-
-.dialog-box {
- border: solid #999 1px;
- background: white;
- min-width: 230px;
- z-index: 80000;
-}
-
-.dialog-box .body, .dialog-box .buttons {
- padding: 5px;
-}
-
-
-.panel-error-message, .panel-warning-message, .panel-done-message, .panel-info-message
-{
- height: 24px;
- line-height: 24px;
- color: #303030;
- padding: 0px;
- padding-left: 26px;
- background-color: #FFCCCC;
- background-image: url(error_small.png);
- background-repeat: no-repeat;
- background-position: 6px 50%;
-}
-
-.panel-warning-message
-{
- background-image: url(warn_small.png);
- background-color: #FFFFCC;
-}
-
-.panel-done-message
-{
- background-image: url(done_small.png);
- background-color: #CCFFCC;
-}
-
-.panel-info-message
-{
- background-image: url(info_small.png);
- background-color: #CCCCFF;
-}
-
-
-#masthead
-{
- position:absolute;
- top:0;
- left:0;
- width:100%;
- height:32px;
- background: #2C3143;
- color:#fff;
- border-bottom: solid #444 1px;
- z-index: 15000;
- padding: 0;
-}
-
-#masthead a
-{
- color: #eeeeee;
-}
-
-#masthead .title
-{
- padding: 3px 10px;
- font-size: 175%;
- font-weight: bold;
-}
-
-#masthead a
-{
- text-decoration: none;
-}
-
-#masthead a:hover
-{
- text-decoration: underline;
-}
-
-
-.tab-group
-{
- margin: 0;
- padding: 0 10px;
- height: 100%;
- white-space: nowrap;
- -moz-user-select: none;
- -khtml-user-select: none;
- user-select: none;
- cursor: default;
-}
-
-.tab-group .tab
-{
- background: #2C3143;
- position: relative;
- display: block;
- float: left;
- margin: 0;
- padding: 0 1em;
- height: 32px;
- line-height: 32px;
- text-align: left;
-}
-
-.tab-group .tab:hover > a
-{
- color: gold !important;
-}
-
-.tab-group .active
-{
- background: rgb(1,1,1);
-}
-
-.tab-group .tab .submenu {
- display: none;
- position: absolute;
- z-index: 16000;
- left: 0;
- top: 32px;
- padding: 1em;
- margin: -1em;
- padding-top: 0;
- margin-top: 0;
- background-color: rgba(0,0,0,0.5);
- -moz-border-radius: 0 0 1em 1em;
- -webkit-border-bottom-right-radius: 1em;
- -webkit-border-bottom-left-radius: 1em;
-}
-
-.tab-group .tab .submenu ul
-{
- display: block;
- margin: 0;
- padding: 0;
- list-style-type: none;
- background: #2C3143;
-}
-
-.tab-group .tab .submenu ul li
-{
- display: block;
- padding: 0 1em;
- white-space: nowrap;
-}
+body,html{overflow:hidden;margin:0;padding:0;width:100%;height:100%;}body{font:75% verdana,"Bitstream Vera Sans",geneva,arial,helvetica,helve,sans-serif;background:#eee;}#background{position:absolute;background:#eee;z-index:-1;top:0;left:0;margin:0;padding:0;width:100%;height:100%;}#messagebox{position:absolute;top:33px;left:0;width:100%;height:24px!important;overflow:hidden;border-bottom:solid #999 1px;font-size:90%;}#left,#left-border,#center,#right-border,#right{position:absolute;top:39px;bottom:0;overflow:hidden;background:#fff;}#left,#center,#right{border-top:solid #999 1px;}#left-border,#right-border{background:#eee;border-left:solid #999 1px;border-right:solid #999 1px;padding-right:1px;padding-left:1px;width:5px;z-index:10000;}#left-border div,#right-border div{width:100%;height:100%;background-repeat:no-repeat;background-position:center center;position:absolute;width:5px;height:100%;}#left-border div,#right-border.hidden div{background-image:url(tiny_arrow_left.png)
;cursor:w-resize;}#left-border.hidden div,#right-border div{background-image:url(tiny_arrow_right.png);cursor:e-resize;}#left-border.hover div,#right-border.hover div{background-color:#AAE;}#left{left:0;width:250px;z-index:200;}#left-border{left:250px;}#center{left:259px;right:259px;overflow:hidden;z-index:1;}#right-border{right:250px;}#right{width:250px;right:0;z-index:200;}.unified-panel-header{height:2em;z-index:1000;background:#ccc;background-image:url(panel_header_bg.png);background-position:top center;background-repeat:repeat-x;border-bottom:solid #999 1px;margin:0;padding:0;padding-right:10px;padding-left:10px;color:#333;font-weight:bold;}.unified-panel-header-inner{padding-top:.45em;}.menu-bg{background:#C1C9E5 url(menu_bg.png) top repeat-x;}div.unified-panel-body{position:absolute;top:2em;bottom:0;width:100%;margin-top:1px;}.panel-header-button{color:#333;text-decoration:none;display:inline-block;cursor:pointer;margin:-1px;padding:1px;border:0;padding-right:.5em;pad
ding-left:.5em;-moz-border-radius:.5em;-webkit-border-radius:.5em;border-radius:.5em;background:transparent;}.panel-header-button:hover{color:black;background:#aaa;}.panel-header-button:active{color:white;background:#aaa;}#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;}.dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;}.dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;}.dialog-box{border:solid #999 1px;background:white;min-width:230px;z-index:80000;}.dialog-box .body,.dialog-box .buttons{padding:5px;}.panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0;padding-left:26px;background-color:#FCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;}.panel-warning-message{background-image:url(warn_small.png);b
ackground-color:#FFC;}.panel-done-message{background-image:url(done_small.png);background-color:#CFC;}.panel-info-message{background-image:url(info_small.png);background-color:#CCF;}#masthead{position:absolute;top:0;left:0;width:100%;height:32px;background:#2C3143;color:#fff;border-bottom:solid #444 1px;z-index:15000;padding:0;}#masthead a{color:#eee;}#masthead .title{padding:3px 10px;font-size:175%;font-weight:bold;}#masthead a{text-decoration:none;}#masthead a:hover{text-decoration:underline;}.tab-group{margin:0;padding:0 10px;height:100%;white-space:nowrap;cursor:default;user-select:none;-moz-user-select:none;-webkit-user-select:none;}.tab-group .tab{background:#2C3143;position:relative;float:left;margin:0;padding:0 1em;height:32px;line-height:32px;text-align:left;}.tab-group .tab:hover>a{color:gold!important;}.tab-group .active{background:#010101;}.tab-group .tab .submenu{display:none;position:absolute;z-index:16000;left:0;top:32px;padding:1em;margin:-1em;padding-top:0;m
argin-top:0;background-color:rgba(0,0,0,0.5);-moz-border-radius:0 0 1em 1em;-webkit-border-bottom-right-radius:1em;-webkit-border-bottom-left-radius:1em;}.tab-group .tab .submenu ul{display:block;margin:0;padding:0;list-style-type:none;background:#2C3143;}.tab-group .tab .submenu ul li{display:block;padding:0 1em;white-space:nowrap;}
\ No newline at end of file
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/blue/reset.css
--- a/static/june_2007_style/blue/reset.css Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/blue/reset.css Mon Jul 13 13:08:52 2009 -0400
@@ -1,3 +1,1 @@
-/* Copyright (c) 2008, Yahoo! Inc. All rights reserved. */
-body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
-/*body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;}*/
+body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
\ No newline at end of file
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/blue/tool_menu.css
--- a/static/june_2007_style/blue/tool_menu.css Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/blue/tool_menu.css Mon Jul 13 13:08:52 2009 -0400
@@ -1,69 +1,1 @@
-body
-{
- background: white;
- color: #303030;
- background: #C1C9E5 url(menu_bg.png) top repeat-x;
- margin: 5px;
- margin-right: 10px;
- margin-left: 10px;
-}
-
-hr
-{
- border: none;
- height: 0px;
- margin-top: 0px;
-}
-
-div.toolSectionPad
-{
- margin: 0;
- padding: 0;
- height: 5px;
- font-size: 0px;
-}
-
-div.toolSectionDetailsInner
-{
- margin-left: 5px;
- margin-right: 5px;
-}
-
-div.toolSectionTitle
-{
- font-weight: bold;
-}
-
-div.toolPanelLabel
-{
- padding-top: 10px;
- padding-bottom: 5px;
- font-weight: bold;
- color: gray;
- text-transform: uppercase;
-}
-
-div.toolTitle
-{
- padding-top: 5px;
- padding-bottom: 5px;
- margin-left: 16px;
- margin-right: 10px;
- display: list-item;
- list-style: square outside;
-}
-
-div.toolSectionBody div.toolPanelLabel
-{
- padding-top: 5px;
- padding-bottom: 5px;
- margin-left: 16px;
- margin-right: 10px;
- display: list-item;
- list-style: none outside;
-}
-
-div.toolTitleNoSection
-{
- padding-bottom: 0px;
-}
+body{background:white;color:#303030;background:#C1C9E5 url(menu_bg.png) top repeat-x;margin:5px;margin-right:10px;margin-left:10px;}hr{border:none;height:0;margin-top:0;}div.toolSectionPad{margin:0;padding:0;height:5px;font-size:0;}div.toolSectionDetailsInner{margin-left:5px;margin-right:5px;}div.toolSectionTitle{font-weight:bold;}div.toolPanelLabel{padding-top:10px;padding-bottom:5px;font-weight:bold;color:gray;text-transform:uppercase;}div.toolTitle{padding-top:5px;padding-bottom:5px;margin-left:16px;margin-right:10px;display:list-item;list-style:square outside;}div.toolSectionBody div.toolPanelLabel{padding-top:5px;padding-bottom:5px;margin-left:16px;margin-right:10px;display:list-item;list-style:none outside;}div.toolTitleNoSection{padding-bottom:0;}
\ No newline at end of file
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/make_style.py
--- a/static/june_2007_style/make_style.py Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/make_style.py Mon Jul 13 13:08:52 2009 -0400
@@ -4,7 +4,7 @@
#import pkg_resources
#pkg_resources.require("Cheetah")
-import sys, string, os.path
+import sys, string, os.path, tempfile, subprocess
#from galaxy import eggs
import pkg_resources
pkg_resources.require( "Cheetah" )
@@ -73,7 +73,18 @@
for input, output in templates:
print input ,"->", output
- open( os.path.join( out_dir, output ), "w" ).write( str( Template( file=input, searchList=[context] ) ) )
+ out_fname = os.path.join( out_dir, output )
+ temp_file = tempfile.NamedTemporaryFile()
+ # Write processed template to temporary file
+ print "Processing template..."
+ temp_file.write( str( Template( file=input, searchList=[context] ) ) )
+ temp_file.flush()
+ # Compress CSS with YUI
+ print "Compressing..."
+ subprocess.call(
+ "java -jar ../../scripts/yuicompressor.jar --type css %s -o %s" % ( temp_file.name, out_fname ),
+ shell = True )
+
"""
for rule, output in images:
diff -r d202e2f4b910 -r feb7438276fb static/june_2007_style/panel_layout.css.tmpl
--- a/static/june_2007_style/panel_layout.css.tmpl Fri Jul 10 18:33:36 2009 -0400
+++ b/static/june_2007_style/panel_layout.css.tmpl Mon Jul 13 13:08:52 2009 -0400
@@ -1,3 +1,11 @@
+#set $unselectable = """
+ user-select: none;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+"""
+
+## Rules
+
body, html
{
overflow: hidden;
@@ -124,9 +132,6 @@
padding-left: 10px;
color: #333;
font-weight: bold;
- user-select: none;
- -moz-user-select: none;
- -webkit-user-select: none;
}
.unified-panel-header-inner {
@@ -281,17 +286,14 @@
padding: 0 10px;
height: 100%;
white-space: nowrap;
- -moz-user-select: none;
- -khtml-user-select: none;
- user-select: none;
cursor: default;
+ ${unselectable}
}
.tab-group .tab
{
- background: ${masthead_bg};
+ background: ${masthead_bg};
position: relative;
- display: block;
float: left;
margin: 0;
padding: 0 1em;
1
0
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/dc5068efc3e7
changeset: 2480:dc5068efc3e7
user: Nate Coraor <nate(a)bx.psu.edu>
date: Tue Jul 14 11:33:42 2009 -0400
description:
Fix job recovery when a tool has been removed while the job is running
1 file(s) affected in this change:
lib/galaxy/jobs/__init__.py
diffs (24 lines):
diff -r 3f407d489ade -r dc5068efc3e7 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py Fri May 22 14:46:17 2009 -0400
+++ b/lib/galaxy/jobs/__init__.py Tue Jul 14 11:33:42 2009 -0400
@@ -119,10 +119,17 @@
"""
model = self.app.model
for job in model.Job.filter( model.Job.c.state==model.Job.states.NEW ).all():
- log.debug( "no runner: %s is still in new state, adding to the jobs queue" %job.id )
- self.queue.put( ( job.id, job.tool_id ) )
+ if job.tool_id not in self.app.toolbox.tools_by_id:
+ log.warning( "Tool '%s' removed from tool config, unable to recover job: %s" % ( job.tool_id, job.id ) )
+ JobWrapper( job, None, self ).fail( 'This tool was disabled before the job completed. Please contact your Galaxy administrator, or' )
+ else:
+ log.debug( "no runner: %s is still in new state, adding to the jobs queue" %job.id )
+ self.queue.put( ( job.id, job.tool_id ) )
for job in model.Job.filter( (model.Job.c.state == model.Job.states.RUNNING) | (model.Job.c.state == model.Job.states.QUEUED) ).all():
- if job.job_runner_name is None:
+ if job.tool_id not in self.app.toolbox.tools_by_id:
+ log.warning( "Tool '%s' removed from tool config, unable to recover job: %s" % ( job.tool_id, job.id ) )
+ JobWrapper( job, None, self ).fail( 'This tool was disabled before the job completed. Please contact your Galaxy administrator, or' )
+ elif job.job_runner_name is None:
log.debug( "no runner: %s is still in queued state, adding to the jobs queue" %job.id )
self.queue.put( ( job.id, job.tool_id ) )
else:
1
0
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/0b5d64cde142
changeset: 2475:0b5d64cde142
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Fri Jul 10 16:15:32 2009 -0400
description:
Fix for tool frame refresh when require_login config setting is true ( resolves ticket 100 ), eliminate center instead of end of history item name in DataToolParameter if name is > 30 chars ( resolves ticket # 64 ), and a log an error instead of raising an exception in get_history() if None is returned ( better behavior ).
3 file(s) affected in this change:
lib/galaxy/tools/parameters/basic.py
lib/galaxy/web/controllers/user.py
lib/galaxy/web/framework/__init__.py
diffs (60 lines):
diff -r 615a0bcf870b -r 0b5d64cde142 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py Fri Jul 10 15:24:01 2009 -0400
+++ b/lib/galaxy/tools/parameters/basic.py Fri Jul 10 16:15:32 2009 -0400
@@ -1115,6 +1115,10 @@
# CRUCIAL: the dataset_collector function needs to be local to DataToolParameter.get_html_field()
def dataset_collector( hdas, parent_hid ):
for i, hda in enumerate( hdas ):
+ if len( hda.name ) > 30:
+ hda_name = '%s..%s' % ( hda.name[:17], hda.name[-11:] )
+ else:
+ hda_name = hda.name
if parent_hid is not None:
hid = "%s.%d" % ( parent_hid, i + 1 )
else:
@@ -1132,7 +1136,7 @@
continue
if isinstance( hda.datatype, self.formats):
selected = ( value and ( hda in value ) )
- field.add_option( "%s: %s" % ( hid, hda.name[:30] ), hda.id, selected )
+ field.add_option( "%s: %s" % ( hid, hda_name ), hda.id, selected )
else:
target_ext, converted_dataset = hda.find_conversion_destination( self.formats, converter_safe = self.converter_safe( other_values, trans ) )
if target_ext:
@@ -1141,7 +1145,7 @@
if not trans.app.security_agent.allow_action( trans.user, trans.app.security_agent.permitted_actions.DATASET_ACCESS, dataset=hda.dataset ):
continue
selected = ( value and ( hda in value ) )
- field.add_option( "%s: (as %s) %s" % ( hid, target_ext, hda.name[:30] ), hda.id, selected )
+ field.add_option( "%s: (as %s) %s" % ( hid, target_ext, hda_name ), hda.id, selected )
# Also collect children via association object
dataset_collector( hda.children, hid )
dataset_collector( history.active_datasets, None )
diff -r 615a0bcf870b -r 0b5d64cde142 lib/galaxy/web/controllers/user.py
--- a/lib/galaxy/web/controllers/user.py Fri Jul 10 15:24:01 2009 -0400
+++ b/lib/galaxy/web/controllers/user.py Fri Jul 10 16:15:32 2009 -0400
@@ -168,8 +168,8 @@
mail = os.popen("%s -t" % trans.app.config.sendmail_path, 'w')
mail.write("To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % (trans.app.config.mailing_join_addr,email) )
if mail.close():
- return trans.show_warn_message( "Now logged in as " + user.email+". However, subscribing to the mailing list has failed.", refresh_frames=['masthead', 'history'] )
- return trans.show_ok_message( "Now logged in as " + user.email, refresh_frames=['masthead', 'history'] )
+ return trans.show_warn_message( "Now logged in as " + user.email+". However, subscribing to the mailing list has failed.", refresh_frames=refresh_frames )
+ return trans.show_ok_message( "Now logged in as " + user.email, refresh_frames=refresh_frames )
return trans.show_form(
web.FormBuilder( web.url_for(), "Create account", submit_text="Create" )
.add_text( "email", "Email address", value=email, error=email_error )
diff -r 615a0bcf870b -r 0b5d64cde142 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py Fri Jul 10 15:24:01 2009 -0400
+++ b/lib/galaxy/web/framework/__init__.py Fri Jul 10 16:15:32 2009 -0400
@@ -456,7 +456,9 @@
if util.string_as_bool( create ):
history = self.new_history()
else:
- raise "get_history() returning None"
+ # Perhaps a bot is running a tool without having logged in to get a history
+ log.debug( "Error: this request returned None from get_history(): %s" % self.request.browser_url )
+ return None
return history
def set_history( self, history ):
if history and not history.deleted:
1
0
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/14fd033f08eb
changeset: 2476:14fd033f08eb
user: James Taylor <james(a)jamestaylor.org>
date: Fri Jul 10 16:21:19 2009 -0400
description:
IE compatibility fixes in workflow editor javascript (groan)
2 file(s) affected in this change:
static/scripts/galaxy.workflow_editor.canvas.js
static/scripts/packed/galaxy.workflow_editor.canvas.js
diffs (474 lines):
diff -r 0b5d64cde142 -r 14fd033f08eb static/scripts/galaxy.workflow_editor.canvas.js
--- a/static/scripts/galaxy.workflow_editor.canvas.js Fri Jul 10 16:15:32 2009 -0400
+++ b/static/scripts/galaxy.workflow_editor.canvas.js Fri Jul 10 16:21:19 2009 -0400
@@ -2,7 +2,7 @@
this.element = element;
this.connectors = [];
}
-Terminal.prototype = {
+$.extend( Terminal.prototype, {
connect: function ( connector ) {
this.connectors.push( connector );
if ( this.node ) {
@@ -25,26 +25,26 @@
c.destroy();
});
}
-}
+});
function OutputTerminal( element, datatype ) {
Terminal.call( this, element );
this.datatype = datatype;
}
-OutputTerminal.prototype = new Terminal;
+OutputTerminal.prototype = new Terminal();
function InputTerminal( element, datatypes ) {
Terminal.call( this, element );
this.datatypes = datatypes;
}
-InputTerminal.prototype = new Terminal;
+InputTerminal.prototype = new Terminal();
$.extend( InputTerminal.prototype, {
can_accept: function ( other ) {
if ( this.connectors.length < 1 ) {
- for ( t in this.datatypes ) {
+ for ( var t in this.datatypes ) {
// FIXME: No idea what to do about this case
if ( other.datatype == "input" ) { return true; }
if ( issubtype( other.datatype, this.datatypes[t] ) ) {
@@ -60,7 +60,7 @@
this.canvas = null;
this.dragging = false;
this.inner_color = "#FFFFFF";
- this.outer_color = "#D8B365"
+ this.outer_color = "#D8B365";
if ( handle1 && handle2 ) {
this.connect( handle1, handle2 );
}
@@ -90,10 +90,16 @@
G_vmlCanvasManager.initElement( this.canvas );
}
canvas_container.append( $(this.canvas) );
- if ( this.dragging ) { this.canvas.style.zIndex = "300" }
+ if ( this.dragging ) {
+ this.canvas.style.zIndex = "300";
+ }
}
- var relativeLeft = function( e ) { return $(e).offset().left - canvas_container.offset().left }
- var relativeTop = function( e ) { return $(e).offset().top - canvas_container.offset().top }
+ var relativeLeft = function( e ) {
+ return $(e).offset().left - canvas_container.offset().left;
+ };
+ var relativeTop = function( e ) {
+ return $(e).offset().top - canvas_container.offset().top;
+ };
// Find the position of each handle
var start_x = relativeLeft( this.handle1.element ) + 5;
var start_y = relativeTop( this.handle1.element ) + 5;
@@ -157,7 +163,7 @@
}).bind( "dropend", function ( e ) {
e.dragProxy.terminal.connectors[0].inner_color = "#FFFFFF";
}).bind( "drop", function( e ) {
- new Connector( e.dragTarget.terminal, e.dropTarget.terminal ).redraw();
+ ( new Connector( e.dragTarget.terminal, e.dropTarget.terminal ) ).redraw();
}).bind( "hover", function() {
// If connected, create a popup to allow disconnection
if ( terminal.connectors.length > 0 ) {
@@ -168,22 +174,24 @@
.append(
$("<div class='buttons'></div>").append(
$("<img src='../images/delete_icon.png' />").click( function() {
- $.each( terminal.connectors, function( _, x ) { x.destroy() } );
+ $.each( terminal.connectors, function( _, x ) {
+ x.destroy();
+ });
t.remove();
})))
.bind( "mouseleave", function() {
$(this).remove();
});
// Position it and show
- t.css( {
+ t.css({
top: $(this).offset().top - 2,
left: $(this).offset().left - t.width(),
- 'padding-right': $(this).width() }
- ).show();
+ 'padding-right': $(this).width()
+ }).show();
}
});
node.input_terminals[name] = terminal;
- })
+ });
},
enable_output_terminal : function( elements, name, type ) {
var node = this;
@@ -213,7 +221,7 @@
e.dragProxy.terminal.redraw();
// FIXME: global
canvas_manager.update_viewport_overlay();
- }
+ };
onmove();
$("#canvas-container").get(0).scroll_panel.test( e, onmove );
}).bind( "dragend", function ( e ) {
@@ -226,8 +234,12 @@
});
},
redraw : function () {
- $.each( this.input_terminals, function( _, t ) { t.redraw() } );
- $.each( this.output_terminals, function( _, t ) { t.redraw() } );
+ $.each( this.input_terminals, function( _, t ) {
+ t.redraw();
+ });
+ $.each( this.output_terminals, function( _, t ) {
+ t.redraw();
+ });
},
destroy : function () {
$.each( this.input_terminals, function( k, t ) {
@@ -246,7 +258,7 @@
// Keep inactive nodes stacked from most to least recently active
// by moving element to the end of parent's node list
var element = this.element.get(0);
- (function(p) { p.removeChild( element ); p.appendChild( element ) })(element.parentNode);
+ (function(p) { p.removeChild( element ); p.appendChild( element ); })(element.parentNode);
// Remove active class
$(element).removeClass( "toolForm-active" );
},
@@ -279,7 +291,7 @@
$.each( data.data_outputs, function( i, output ) {
var t = $( "<div class='terminal output-terminal'></div>" );
node.enable_output_terminal( t, output.name, output.extension );
- var label = output.name
+ var label = output.name;
if ( output.extension != 'input' ) {
label = label + " (" + output.extension + ")";
}
@@ -301,7 +313,7 @@
// Update input rows
var old_body = el.find( "div.inputs" );
var new_body = $("<div class='inputs'></div>");
- var old = old_body.find( "div.input-data-row")
+ var old = old_body.find( "div.input-data-row");
$.each( data.data_inputs, function( i, input ) {
var t = $("<div class='terminal input-terminal'></div>");
node.enable_input_terminal( t, input.name, input.extensions );
@@ -323,7 +335,7 @@
// Cleanup any leftover terminals
old_body.find( "div.input-data-row > .terminal" ).each( function() {
this.terminal.destroy();
- })
+ });
// If active, reactivate with new form_html
this.changed();
this.redraw();
@@ -344,7 +356,7 @@
function Workflow( canvas_container ) {
this.canvas_container = canvas_container;
this.id_counter = 0;
- this.nodes = {}
+ this.nodes = {};
this.name = null;
this.has_changes = false;
}
@@ -372,9 +384,9 @@
});
},
to_simple : function () {
- var nodes = {}
+ var nodes = {};
$.each( this.nodes, function ( i, node ) {
- var input_connections = {}
+ var input_connections = {};
$.each( node.input_terminals, function ( k, t ) {
input_connections[ t.name ] = null;
// There should only be 0 or 1 connectors, so this is
@@ -391,10 +403,10 @@
tool_errors : node.tool_errors,
input_connections : input_connections,
position : $(node.element).position()
- }
+ };
nodes[ node.id ] = node_data;
- })
- return { steps: nodes }
+ });
+ return { steps: nodes };
},
from_simple : function ( data ) {
wf = this;
@@ -409,7 +421,7 @@
}
node.id = step.id;
wf.nodes[ node.id ] = node;
- max_id = Math.max( max_id, parseInt( id ) )
+ max_id = Math.max( max_id, parseInt( id ) );
});
wf.id_counter = max_id + 1;
// Second pass, connections
@@ -423,7 +435,7 @@
node.input_terminals[ k ] );
c.redraw();
}
- })
+ });
});
},
clear_active_node : function() {
@@ -471,31 +483,32 @@
});
});
// Assemble order, tracking levels
- node_ids_by_level = []
+ node_ids_by_level = [];
while ( true ) {
// Everything without a predecessor
- level_parents = []
- $.each( n_pred, function( k, v ) {
- if ( v == 0 ) {
- level_parents.push( k );
+ level_parents = [];
+ for ( var pred_k in n_pred ) {
+ if ( n_pred[ pred_k ] == 0 ) {
+ level_parents.push( pred_k );
}
- });
+ }
if ( level_parents.length == 0 ) {
break;
}
- node_ids_by_level.push( level_parents )
+ node_ids_by_level.push( level_parents );
// Remove the parents from this level, and decrement the number
// of predecessors for each successor
- $.each( level_parents, function( k, v ) {
+ for ( var k in level_parents ) {
+ var v = level_parents[k];
delete n_pred[v];
- $.each( successors[v], function( sk, sv ) {
- n_pred[sv] -= 1;
- });
- });
+ for ( var sk in successors[v] ) {
+ n_pred[ sucessors[v][sk] ] -= 1;
+ }
+ }
}
if ( n_pred.length ) {
// ERROR: CYCLE! Currently we do nothing
- return
+ return;
}
// Layout each level
var all_nodes = this.nodes;
@@ -505,7 +518,7 @@
// We keep nodes in the same order in a level to give the user
// some control over ordering
ids.sort( function( a, b ) {
- return $(all_nodes[a].element).position().top - $(all_nodes[b].element).position().top
+ return $(all_nodes[a].element).position().top - $(all_nodes[b].element).position().top;
});
// Position each node
var max_width = 0;
@@ -520,7 +533,7 @@
left += max_width + h_pad;
});
// Need to redraw all connectors
- $.each( all_nodes, function( _, node ) { node.redraw() } );
+ $.each( all_nodes, function( _, node ) { node.redraw(); } );
},
bounds_for_all_nodes: function() {
var xmin = Infinity, xmax = -Infinity,
@@ -528,7 +541,7 @@
p;
$.each( this.nodes, function( id, node ) {
e = $(node.element);
- p = e.position()
+ p = e.position();
xmin = Math.min( xmin, p.left );
xmax = Math.max( xmax, p.left + e.width() );
ymin = Math.min( ymin, p.top );
@@ -559,11 +572,11 @@
left: left,
top: top,
width: width,
- height: height,
+ height: height
});
// Move elements back if needed
this.canvas_container.children().each( function() {
- var p = $(this).position()
+ var p = $(this).position();
$(this).css( "left", p.left + xmin_delta );
$(this).css( "top", p.top + ymin_delta );
});
@@ -585,26 +598,26 @@
function prebuild_node( type, title_text, tool_id ) {
var f = $("<div class='toolForm toolFormInCanvas'></div>");
var node = new Node( f );
- node.type = type
+ node.type = type;
if ( type == 'tool' ) {
node.tool_id = tool_id;
}
- var title = $("<div class='toolFormTitle unselectable'>" + title_text + "</div>" )
+ var title = $("<div class='toolFormTitle unselectable'>" + title_text + "</div>" );
f.append( title );
f.css( "left", $(window).scrollLeft() + 20 ); f.css( "top", $(window).scrollTop() + 20 );
- var b = $("<div class='toolFormBody'></div>")
+ var b = $("<div class='toolFormBody'></div>");
var tmp = "<div><img height='16' align='middle' src='../images/loading_small_white_bg.gif'/> loading tool info...</div>";
b.append( tmp );
node.form_html = tmp;
- f.append( b )
+ f.append( b );
// Fix width to computed width
// Now add floats
var buttons = $("<div class='buttons' style='float: right;'></div>");
buttons.append( $("<img src='../images/delete_icon.png' />").click( function( e ) {
node.destroy();
} ).hover(
- function() { $(this).attr( 'src', "../images/delete_icon_dark.png" ) },
- function() { $(this).attr( 'src', "../images/delete_icon.png" ) }
+ function() { $(this).attr( 'src', "../images/delete_icon_dark.png" ); },
+ function() { $(this).attr( 'src', "../images/delete_icon.png" ); }
) );
// Place inside container
f.appendTo( "#canvas-container" );
@@ -647,12 +660,12 @@
child = ext_to_type[child];
parent = ext_to_type[parent];
return ( type_to_type[child] ) && ( parent in type_to_type[child] );
-};
+}
function populate_datatype_info( data ) {
ext_to_type = data.ext_to_class_name;
type_to_type = data.class_to_classes;
-};
+}
// FIXME: merge scroll panel into CanvasManager, clean up hardcoded stuff.
@@ -663,14 +676,14 @@
test: function( e, onmove ) {
clearTimeout( this.timeout );
var x = e.pageX,
- y = e.pageY;
+ y = e.pageY,
// Panel size and position
panel = $(this.panel),
panel_pos = panel.position(),
panel_w = panel.width(),
- panel_h = panel.height()
+ panel_h = panel.height(),
// Viewport size and offset
- viewport = panel.parent();
+ viewport = panel.parent(),
viewport_w = viewport.width(),
viewport_h = viewport.height(),
viewport_offset = viewport.offset(),
@@ -747,7 +760,7 @@
top: y
});
self.update_viewport_overlay();
- }
+ };
// Dragging within canvas background
this.cc.each( function() {
this.scroll_panel = new ScrollPanel( this );
@@ -766,13 +779,13 @@
});
// Dragging for overview pane
this.ov.bind( "drag", function( e ) {
- var in_w = self.cc.width();
- var in_h = self.cc.height()
- var o_w = self.oc.width();
- var o_h = self.oc.height();
- var p = $(this).offsetParent().offset();
- var new_x_offset = e.offsetX - p.left;
- var new_y_offset = e.offsetY - p.top;
+ var in_w = self.cc.width(),
+ in_h = self.cc.height(),
+ o_w = self.oc.width(),
+ o_h = self.oc.height(),
+ p = $(this).offsetParent().offset(),
+ new_x_offset = e.offsetX - p.left,
+ new_y_offset = e.offsetY - p.top;
move( - ( new_x_offset / o_w * in_w ),
- ( new_y_offset / o_h * in_h ) );
}).bind( "dragend", function() {
@@ -794,15 +807,15 @@
},
update_viewport_overlay: function() {
- var cc = this.cc;
- var cv = this.cv;
- var oc = this.oc;
- var ov = this.ov;
- var in_w = cc.width();
- var in_h = cc.height()
- var o_w = oc.width();
- var o_h = oc.height();
- var cc_pos = cc.position()
+ var cc = this.cc,
+ cv = this.cv,
+ oc = this.oc,
+ ov = this.ov,
+ in_w = cc.width(),
+ in_h = cc.height(),
+ o_w = oc.width(),
+ o_h = oc.height(),
+ cc_pos = cc.position();
ov.css( {
left: - ( cc_pos.left / in_w * o_w ),
top: - ( cc_pos.top / in_h * o_h ),
@@ -812,11 +825,11 @@
});
},
draw_overview: function() {
- var canvas_el = $("#overview-canvas");
- var size = canvas_el.parent().parent().width()
- var c = canvas_el.get(0).getContext("2d");
- var in_w = $("#canvas-container").width();
- var in_h = $("#canvas-container").height()
+ var canvas_el = $("#overview-canvas"),
+ size = canvas_el.parent().parent().width(),
+ c = canvas_el.get(0).getContext("2d"),
+ in_w = $("#canvas-container").width(),
+ in_h = $("#canvas-container").height();
var o_h, shift_h, o_w, shift_w;
// Fit canvas into overview area
var cv_w = this.cv.width();
@@ -853,7 +866,7 @@
c.strokeStyle = "#D8B365";
c.lineWidth = 1;
$.each( workflow.nodes, function( id, node ) {
- var node_element = $(node.element);
+ var node_element = $(node.element),
position = node_element.position(),
x = position.left / in_w * o_w,
y = position.top / in_h * o_h,
@@ -864,4 +877,4 @@
});
this.update_viewport_overlay();
}
-})
\ No newline at end of file
+});
\ No newline at end of file
diff -r 0b5d64cde142 -r 14fd033f08eb static/scripts/packed/galaxy.workflow_editor.canvas.js
--- a/static/scripts/packed/galaxy.workflow_editor.canvas.js Fri Jul 10 16:15:32 2009 -0400
+++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js Fri Jul 10 16:21:19 2009 -0400
@@ -1,1 +1,1 @@
-function Terminal(a){this.element=a;this.connectors=[]}Terminal.prototype={connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}};function OutputTerminal(a,b){Terminal.call(this,a);this.datatype=b}OutputTerminal.prototype=new Terminal;function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal;$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(t in this.datatypes){if(a.datatype=="input"){return true}if(issubtype(a.datatype,this.datatypes[t])){return true}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)
}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var o=function(c){return $(c).offset().left-d.offset().left};var j=function(c){return $(c).offset().top-d.offset().top};var i=o(this.handle1.element)+5;var g=j(this.handle1.element)+5;var q=o(this.handle2.element)+5;var n=j(this.handle2.element)+5;var f=100;var l=Math.min(i,q);var a=Math.max(i,q);var k=Math.min(g,n);var v=Math.max(g,n);var b=Math.min(Math.max(Math.abs(v-k)/2,100),300);var p=l-f;var u=k-f;var r=a-l+2*f;var m=v-k+2*f;this.canvas.style.
left=p+"px";this.canvas.style.top=u+"px";this.canvas.setAttribute("width",r);this.canvas.setAttribute("height",m);i-=p;g-=u;q-=p;n-=u;var s=this.canvas.getContext("2d");s.lineCap="round";s.strokeStyle=this.outer_color;s.lineWidth=7;s.beginPath();s.moveTo(i,g);s.bezierCurveTo(i+b,g,q-b,n,q,n);s.stroke();s.strokeStyle=this.inner_color;s.lineWidth=5;s.beginPath();s.moveTo(i,g);s.bezierCurveTo(i+b,g,q-b,n,q,n);s.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){new Connector(g.dragTarget.terminal,g.dropTarget.terminal).redraw()}).bind("hover",function(){if(f.
connectors.length>0){var g=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img src='../images/delete_icon.png' />").click(function(){$.each(f.connectors,function(j,i){i.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(l){return this.terminal.can_accept(f)}}).addClass("input-terminal-active");return i}).bind("drag",
function(j){var i=function(){var l=$(j.dragProxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.dragProxy).css({left:k,top:m});j.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};i();$("#canvas-container").get(0).scroll_panel.test(j,i)}).bind("dragend",function(i){i.dragProxy.terminal.connectors[0].destroy();$(i.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.
parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var i=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);i.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.extension);var f=b.name;if(b.extension!="input"){f=f+" ("+b.extension+")"}a.append($("<d
iv class='form-row dataRow'>"+f+"</div>").append(j))});workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(l,j){var k=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(k,j.name,j.extensions);g.find("div[name="+j.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){k[0].terminal.connectors[0]=i;i.handle2=k[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+j.name+"'>"+j.label+"</div>").prepend(k))});g.replaceWith(b);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed(
);this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(b,d){var f={};$.each(d.input_terminals,function(g,i){f[i.name]=null;$.each(i.connectors,function(j,k){f[i.name]={id:k.handle1.node.id,output
_name:k.handle1.name}})});var c={id:d.id,type:d.type,tool_id:d.tool_id,tool_state:d.tool_state,tool_errors:d.tool_errors,input_connections:f,position:$(d.element).position()};a[d.id]=c});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(i,g){if(g){var j=wf.nodes[g.id];var l=new Connector();l.connect(j.output_terminals[g.output_name],c.input_terminals[i]);l.redraw()}})})},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.clear_active_node();parent.show_form_for_tool(a.form
_html,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){parent.show_form_for_tool(a.form_html,a)}},layout:function(){var a={};var b={};$.each(this.nodes,function(i,g){if(a[i]===undefined){a[i]=0}if(b[i]===undefined){b[i]=[]}});$.each(this.nodes,function(i,g){$.each(g.input_terminals,function(k,l){$.each(l.connectors,function(m,n){var j=n.handle1.node;a[g.id]+=1;b[j.id].push(g.id)})})});node_ids_by_level=[];while(true){level_parents=[];$.each(a,function(i,g){if(g==0){level_parents.push(i)}});if(level_parents.length==0){break}node_ids_by_level.push(level_parents);$.each(level_parents,function(i,g){delete a[g];$.each(b[g],function(k,j){a[j]-=1})})}if(a.length){return}var d=this.nodes;var c=80;v_pad=30;var f=c;$.each(node_ids_by_level,function(g,j){j.sort(function(m,i){return $(d[m].element).position().top-$(d[i].element).position().top});var k=0;var l=v_pad;$.each(j,function(i,o){var n=d[o];var m=$(n.element);$(m).css
({top:l,left:f});k=Math.max(k,$(m).width());l+=$(m).height()+v_pad});f+=k+c});$.each(d,function(g,i){i.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(i,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var j=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var i=fix_delta(a.ymin,100);d=Math.max(d,f.left);i=Math.max(i,f.top);var c=f.left-d;var g=f.top-i;var b=round_up(a.xmax+100,100)+d;var k=round_up(a.ymax+100,100)+i;b=Math.max(b,-c+j.width());k=Math.max(k,-g+j.height());this.canvas_container.css({left:c,top:g,width:b,height:k,});this.canvas_container.children().each(function(){var l=$(this).position();$(this).css("left",l.left+d);$(this).css("top",l.top+i)})}});func
tion fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(m,k,s){var j=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(j);g.type=m;if(m=="tool"){g.tool_id=s}var q=$("<div class='toolFormTitle unselectable'>"+k+"</div>");j.append(q);j.css("left",$(window).scrollLeft()+20);j.css("top",$(window).scrollTop()+20);var n=$("<div class='toolFormBody'></div>");var i="<div><img height='16' align='middle' src='../images/loading_small_white_bg.gif'/> loading tool info...</div>";n.append(i);g.form_html=i;j.append(n);var l=$("<div class='buttons' style='float: right;'></div>");l.append($("<img src='../images/delete_icon.png' />").click(function(b){g.destroy()}).hover(function(){$(this).attr("src","../images/delete_icon_dark.png")},function(){$(this).attr("src","../images/delete_icon.png")}));j.appendTo("#canvas-container");var d=$("#canvas-container").position(
);var c=$("#canvas-container").parent();var a=j.width();var r=j.height();j.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(r/2)});l.prependTo(q);a+=(l.width()+10);j.css("width",a);$(j).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(f,c){clearTim
eout(this.timeout);var a=f.pageX,g=f.pageY;b=$(this.panel),panel_pos=b.position(),panel_w=b.width(),panel_h=b.height();viewport=b.parent();viewport_w=viewport.width(),viewport_h=viewport.height(),viewport_offset=viewport.offset(),min_x=viewport_offset.left,min_y=viewport_offset.top,max_x=min_x+viewport.width(),max_y=min_y+viewport.height(),p_min_x=-(panel_w-(viewport_w/2)),p_min_y=-(panel_h-(viewport_h/2)),p_max_x=(viewport_w/2),p_max_y=(viewport_h/2),moved=false,close_dist=5,nudge=23;if(a-close_dist<min_x){if(panel_pos.left<p_max_x){var d=Math.min(nudge,p_max_x-panel_pos.left);b.css("left",panel_pos.left+d);moved=true}}else{if(a+close_dist>max_x){if(panel_pos.left>p_min_x){var d=Math.min(nudge,panel_pos.left-p_min_x);b.css("left",panel_pos.left-d);moved=true}}else{if(g-close_dist<min_y){if(panel_pos.top<p_max_y){var d=Math.min(nudge,p_max_y-panel_pos.top);b.css("top",panel_pos.top+d);moved=true}}else{if(g+close_dist>max_y){if(panel_pos.top>p_min_y){var d=Math.min(nudge,pane
l_pos.top-p_min_x);b.css("top",(panel_pos.top-d)+"px");moved=true}}}}}if(moved){c();var b=this;this.timeout=setTimeout(function(){b.test(f,c)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var i=$(this).offset();var f=b.cc.position();c=f.top-i.top;d=f.left-i.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("dra
g",function(l){var k=b.cc.width();var g=b.cc.height();var f=b.oc.width();var i=b.oc.height();var j=$(this).offsetParent().offset();var n=l.offsetX-j.left;var m=l.offsetY-j.top;a(-(n/f*k),-(m/i*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var j=$(this).offsetParent();var i=j.offset();var f=Math.max(j.width()-(g.offsetX-i.left),j.height()-(g.offsetY-i.top));$(this).css({width:f,height:f});b.draw_overview()})},update_viewport_overlay:function(){var b=this.cc;var f=this.cv;var a=this.oc;var c=this.ov;var d=b.width();var k=b.height();var j=a.width();var g=a.height();var i=b.position();c.css({left:-(i.left/d*j),top:-(i.top/k*g),width:(f.width()/d*j)-2,height:(f.height()/k*g)-2})},draw_overview:function(){var k=$("#overview-canvas");var n=k.parent().parent().width();var j=k.get(0).getContext("2d");var d=$("#canvas-container").width();var m=$("#canvas-container").height();var g,a,l,f;var i=this.cv.wi
dth();var b=this.cv.height();if(d<i&&m<b){l=d/i*n;f=(n-l)/2;g=m/b*n;a=(n-g)/2}else{if(d<m){a=0;g=n;l=Math.ceil(g*d/m);f=(n-l)/2}else{l=n;f=0;g=Math.ceil(l*m/d);a=(n-g)/2}}k.parent().css({left:f,top:a,width:l,height:g});k.attr("width",l);k.attr("height",g);j.fillStyle="#D2C099";j.strokeStyle="#D8B365";j.lineWidth=1;$.each(workflow.nodes,function(p,c){var o=$(c.element);position=o.position(),x=position.left/d*l,y=position.top/m*g,w=o.width()/d*l,h=o.height()/m*g;j.fillRect(x,y,w,h);j.strokeRect(x,y,w,h)});this.update_viewport_overlay()}});
\ No newline at end of file
+function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatype=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var b in this.datatypes){if(a.datatype=="input"){return true}if(issubtype(a.datatype,this.datatypes[b])){return true}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a)
{this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;
this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)).redraw()}).bind("hov
er",function(){if(f.connectors.length>0){var g=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img src='../images/delete_icon.png' />").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClass("input-terminal-active");ret
urn i}).bind("drag",function(i){var h=function(){var k=$(i.dragProxy).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dragProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b
.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.extension);var f=b.name;if(b.extension!="input"){f=f+" ("+b.extensio
n+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j))});workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0].terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(b);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destr
oy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(b,d){var f={};$.each(d.input_terminals,function(g,h){f[h.name]=null;$.each(h.connectors,function(j,k){f[h.name]={id:k.ha
ndle1.node.id,output_name:k.handle1.name}})});var c={id:d.id,type:d.type,tool_id:d.tool_id,tool_state:d.tool_state,tool_errors:d.tool_errors,input_connections:f,position:$(d.element).position()};a[d.id]=c});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.clear_active_node();parent.show_
form_for_tool(a.form_html,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){parent.show_form_for_tool(a.form_html,a)}},layout:function(){var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[sucessors[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var
q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(
this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='../images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<img src='../images/delete_icon.png' />").click(function(b){g.destroy()}).hover(function(){$(this).attr("src","../images/delete_icon_dark.png")},function(){$(this).attr("src","../images/delete_icon.png")}));i.appendTo("#canvas-container");var
d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prot
otype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;
var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b.cc.width(),g=b.cc.height(),f=b.oc.width(),h=b.oc.height(),i=$(this).offsetParent().offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left),i.height()-(g.offsetY-h.top));$(this).css({wi
dth:f,height:f});b.draw_overview()})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewp
ort_overlay()}});
\ No newline at end of file
1
0
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/249f0037dea2
changeset: 2472:249f0037dea2
user: rc
date: Fri Jul 10 13:52:20 2009 -0400
description:
Fixed form_definition foreign key so that the unittest will pass. Nothing needed for migration script
1 file(s) affected in this change:
lib/galaxy/model/mapping.py
diffs (17 lines):
diff -r b46f27137744 -r 249f0037dea2 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Fri Jul 10 11:37:28 2009 -0400
+++ b/lib/galaxy/model/mapping.py Fri Jul 10 13:52:20 2009 -0400
@@ -535,7 +535,12 @@
Column( "update_time", DateTime, default=now, onupdate=now ),
Column( "name", TrimmedString( 255 ), nullable=False ),
Column( "desc", TEXT ),
- Column( "form_definition_current_id", Integer, ForeignKey( "form_definition_current.id" ), index=True ),
+ Column( "form_definition_current_id",
+ Integer,
+ ForeignKey( "form_definition_current.id",
+ name='for_def_form_def_current_id_fk',
+ use_alter=True),
+ index=True ),
Column( "fields", JSONType()))
RequestType.table = Table('request_type', metadata,
1
0
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/f7bdfd409b7d
changeset: 2473:f7bdfd409b7d
user: rc
date: Fri Jul 10 14:50:17 2009 -0400
description:
Fixed a bug in form editing where some characters where not appearing correctly when the form is saved.
3 file(s) affected in this change:
lib/galaxy/web/controllers/admin.py
lib/galaxy/web/controllers/forms.py
lib/galaxy/web/controllers/requests.py
diffs (98 lines):
diff -r 249f0037dea2 -r f7bdfd409b7d lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py Fri Jul 10 13:52:20 2009 -0400
+++ b/lib/galaxy/web/controllers/admin.py Fri Jul 10 14:50:17 2009 -0400
@@ -2188,10 +2188,10 @@
msg=msg,
messagetype=messagetype )
def _save_request_type(self, trans, params, request_type_id):
- num_states = int( params.get( 'num_states', 0 ) )
+ num_states = int( util.restore_text( params.get( 'num_states', 0 ) ))
proceed = True
for i in range( num_states ):
- if not params.get( 'new_element_name_%i' % i, None ):
+ if not util.restore_text( params.get( 'new_element_name_%i' % i, None ) ):
proceed = False
break
if not proceed:
@@ -2212,8 +2212,8 @@
ss.delete()
ss.flush()
for i in range( num_states ):
- name = params.get( 'new_element_name_%i' % i, None )
- desc = params.get( 'new_element_description_%i' % i, None )
+ name = util.restore_text( params.get( 'new_element_name_%i' % i, None ))
+ desc = util.restore_text( params.get( 'new_element_description_%i' % i, None ))
ss = trans.app.model.SampleState(name, desc, rt.id)
ss.flush()
msg = "The new sample type named '%s' with %s state(s) has been created" % (rt.name, num_states)
diff -r 249f0037dea2 -r f7bdfd409b7d lib/galaxy/web/controllers/forms.py
--- a/lib/galaxy/web/controllers/forms.py Fri Jul 10 13:52:20 2009 -0400
+++ b/lib/galaxy/web/controllers/forms.py Fri Jul 10 14:50:17 2009 -0400
@@ -150,10 +150,10 @@
'selectlist': '' }
self.current_form['fields'].append(empty_field)
def __get_field(self, params, index):
- name = params.get( 'field_name_%i' % index, None )
- helptext = params.get( 'field_helptext_%i' % index, None )
- required = params.get( 'field_required_%i' % index, False )
- field_type = params.get( 'field_type_%i' % index, None )
+ name = util.restore_text( params.get( 'field_name_%i' % index, None ) )
+ helptext = util.restore_text( params.get( 'field_helptext_%i' % index, None ) )
+ required = util.restore_text( params.get( 'field_required_%i' % index, False ) )
+ field_type = util.restore_text( params.get( 'field_type_%i' % index, None ) )
if field_type == 'SelectField':
selectlist = self.__get_selectbox_options(params, index)
else:
@@ -172,7 +172,7 @@
ctr=0
sb_options = []
while True:
- option = params.get( 'field_'+str(index)+'_option_'+str(ctr), None )
+ option = util.restore_text( params.get( 'field_'+str(index)+'_option_'+str(ctr), None ) )
ctr = ctr+1
if option:
sb_options.append(option)
@@ -194,7 +194,7 @@
return None, 'Form name must be filled.'
# fields
for i in range( len(self.current_form['fields']) ):
- if not params.get( 'field_name_%i' % i, None ):
+ if not util.restore_text(params.get( 'field_name_%i' % i, None )):
return None, "All the field label(s) must be completed."
return True, ''
def __get_form(self, params):
diff -r 249f0037dea2 -r f7bdfd409b7d lib/galaxy/web/controllers/requests.py
--- a/lib/galaxy/web/controllers/requests.py Fri Jul 10 13:52:20 2009 -0400
+++ b/lib/galaxy/web/controllers/requests.py Fri Jul 10 14:50:17 2009 -0400
@@ -212,12 +212,12 @@
request = trans.app.model.Request.get(request_id)
form_values = trans.app.model.FormValues.get(request.form_values_id)
request_form = trans.app.model.FormDefinition.get(form_values.request_form_id)
- name = params.get('name', '')
- desc = params.get('desc', '')
- library_id = params.get('library', '')
+ name = util.restore_text(params.get('name', ''))
+ desc = util.restore_text(params.get('desc', ''))
+ library_id = util.restore_text(params.get('library', ''))
values = {}
for field in request_form.fields:
- values[field['label']] = params.get(field['label'], '')
+ values[field['label']] = util.restore_text(params.get(field['label'], ''))
if not request_id:
form_values = trans.app.model.FormValues(request_form_id, values)
form_values.flush()
@@ -348,11 +348,11 @@
sample = trans.app.model.Sample.get(sample_id)
form_data = trans.app.model.FormData.get(sample.form_data_id)
form = trans.app.model.FormDefinition.get(form_data.form_definition_id)
- name = params.get('name', '')
- desc = params.get('desc', '')
+ name = util.restore_text(params.get('name', ''))
+ desc = util.restore_text(params.get('desc', ''))
values = {}
for field in sample_form.fields:
- values[field['label']] = params.get(field['label'], '')
+ values[field['label']] = util.restore_text(params.get(field['label'], ''))
if not sample_id:
form_values = trans.app.model.FormValues(sample_form.id, values)
form_values.flush()
1
0
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/b46f27137744
changeset: 2471:b46f27137744
user: rc
date: Fri Jul 10 11:37:28 2009 -0400
description:
First pass of the new Galaxy forms components including requests which based on form definitions and samples.
40 file(s) affected in this change:
lib/galaxy/model/__init__.py
lib/galaxy/model/mapping.py
lib/galaxy/model/migrate/versions/0008_galaxy_forms.py
lib/galaxy/web/controllers/admin.py
lib/galaxy/web/controllers/forms.py
lib/galaxy/web/controllers/requests.py
lib/galaxy/web/controllers/requests_admin.py
lib/galaxy/web/form_builder.py
lib/galaxy/web/framework/__init__.py
run_functional_tests.sh
templates/admin/forms/create_form.mako
templates/admin/forms/edit_form.mako
templates/admin/forms/manage_forms.mako
templates/admin/forms/show_form_read_only.mako
templates/admin/index.mako
templates/admin/requests/add_states.mako
templates/admin/requests/create_request_type.mako
templates/admin/requests/edit_request_type.mako
templates/admin/requests/grid.mako
templates/admin/requests/manage_request_types.mako
templates/admin/requests/view_request.mako
templates/admin/samples/change_state.mako
templates/admin/samples/edit_sample.mako
templates/admin/samples/events.mako
templates/admin/samples/grid.mako
templates/admin/samples/view_sample.mako
templates/base.mako
templates/base_panels.mako
templates/requests/grid.mako
templates/requests/index.mako
templates/requests/new_request.mako
templates/requests/select_request_type.mako
templates/requests/view_request.mako
templates/sample/browse_samples.mako
templates/sample/edit_sample.mako
templates/sample/grid.mako
templates/sample/index.mako
templates/sample/new_sample.mako
templates/sample/sample_events.mako
templates/sample/view_sample.mako
diffs (truncated from 3714 to 3000 lines):
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py Thu Jul 09 15:49:26 2009 -0400
+++ b/lib/galaxy/model/__init__.py Fri Jul 10 11:37:28 2009 -0400
@@ -14,6 +14,7 @@
import galaxy.datatypes.registry
from galaxy.datatypes.metadata import MetadataCollection
from galaxy.security import RBACAgent, get_permitted_actions
+
import logging
log = logging.getLogger( __name__ )
@@ -1095,6 +1096,58 @@
raise
# Return filename inside hashed directory
return os.path.abspath( os.path.join( path, "metadata_%d.dat" % self.id ) )
+
+
+class FormDefinition( object ):
+ def __init__(self, name=None, desc=None, fields=[], current_form_id=None):
+ self.name = name
+ self.desc = desc
+ self.fields = fields
+ self.form_definition_current_id = current_form_id
+
+class FormDefinitionCurrent( object ):
+ def __init__(self, form_definition_id=None):
+ self.latest_form_id = form_definition_id
+
+class FormValues( object ):
+ def __init__(self, form_def_id=None, content=None):
+ self.form_definition_id = form_def_id
+ self.content = content
+
+class Request( object ):
+ def __init__(self, name=None, desc=None, request_type_id=None, user_id=None, form_values_id=None, library_id=None):
+ self.name = name
+ self.desc = desc
+ self.request_type_id = request_type_id
+ self.form_values_id = form_values_id
+ self.user_id = user_id
+ self.library_id = library_id
+
+class RequestType( object ):
+ def __init__(self, request_form_id=None, sample_form_id=None):
+ self.request_form_id = request_form_id
+ self.sample_form_id = sample_form_id
+
+class Sample( object ):
+ def __init__(self, name=None, desc=None, request_id=None, form_values_id=None):
+ self.name = name
+ self.desc = desc
+ self.request_id = request_id
+ self.form_values_id = form_values_id
+
+class SampleState( object ):
+ def __init__(self, name=None, desc=None, request_type_id=None):
+ self.name = name
+ self.desc = desc
+ self.request_type_id = request_type_id
+
+class SampleEvent( object ):
+ def __init__(self, sample_id=None, sample_state_id=None, comment=''):
+ self.sample_id = sample_id
+ self.sample_state_id = sample_state_id
+ self.comment = comment
+
+
## ---- Utility methods -------------------------------------------------------
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Thu Jul 09 15:49:26 2009 -0400
+++ b/lib/galaxy/model/mapping.py Fri Jul 10 11:37:28 2009 -0400
@@ -520,8 +520,114 @@
Column( "deleted", Boolean, index=True, default=False ),
Column( "purged", Boolean, index=True, default=False ) )
+
+FormDefinitionCurrent.table = Table('form_definition_current', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "latest_form_id", Integer, ForeignKey( "form_definition.id" ), index=True ),
+ Column( "deleted", Boolean, index=True, default=False ))
+
+# new table to store all the forms which is created by the admin
+FormDefinition.table = Table('form_definition', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "form_definition_current_id", Integer, ForeignKey( "form_definition_current.id" ), index=True ),
+ Column( "fields", JSONType()))
+
+RequestType.table = Table('request_type', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "request_form_id", Integer, ForeignKey( "form_definition.id" ), index=True ),
+ Column( "sample_form_id", Integer, ForeignKey( "form_definition.id" ), index=True ) )
+
+FormValues.table = Table('form_values', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "form_definition_id", Integer, ForeignKey( "form_definition.id" ), index=True ),
+ Column( "content", JSONType()) )
+
+Request.table = Table('request', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "form_values_id", Integer, ForeignKey( "form_values.id" ), index=True ),
+ Column( "request_type_id", Integer, ForeignKey( "request_type.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ),
+ Column( "library_id", Integer, ForeignKey( "library.id" ), index=True ),
+ Column( "deleted", Boolean, index=True, default=False ) )
+
+Sample.table = Table('sample', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "form_values_id", Integer, ForeignKey( "form_values.id" ), index=True ),
+ Column( "request_id", Integer, ForeignKey( "request.id" ), index=True ),
+ Column( "deleted", Boolean, index=True, default=False ) )
+
+# new table to store all the possible sample states and the sample type it
+# belongs to
+SampleState.table = Table('sample_state', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "request_type_id", Integer, ForeignKey( "request_type.id" ), index=True ) )
+
+SampleEvent.table = Table('sample_event', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "sample_id", Integer, ForeignKey( "sample.id" ), index=True ),
+ Column( "sample_state_id", Integer, ForeignKey( "sample_state.id" ), index=True ),
+ Column( "comment", TEXT ) )
+
+
+
# With the tables defined we can define the mappers and setup the
# relationships between the model objects.
+
+assign_mapper( context, Sample, Sample.table,
+ properties=dict( events=relation( SampleEvent, backref="sample",
+ order_by=desc(SampleEvent.table.c.update_time) ),
+ ) )
+
+assign_mapper( context, FormValues, FormValues.table, properties=None)
+
+assign_mapper( context, Request, Request.table, properties=None)
+
+assign_mapper( context, RequestType, RequestType.table,
+ properties=dict( states=relation( SampleState, backref="request_type",
+ order_by=desc(SampleState.table.c.update_time) ),
+ ) )
+
+assign_mapper( context, FormDefinition, FormDefinition.table, properties=None)
+
+assign_mapper( context, FormDefinitionCurrent, FormDefinitionCurrent.table,
+ properties=dict( forms=relation( FormDefinition, backref='form_definition_current',
+ cascade="all, delete-orphan",
+ primaryjoin=( FormDefinitionCurrent.table.c.id == FormDefinition.table.c.form_definition_current_id ) ),
+ latest_form=relation( FormDefinition, post_update=True,
+ primaryjoin=( FormDefinitionCurrent.table.c.latest_form_id == FormDefinition.table.c.id ) )
+ ) )
+
+assign_mapper( context, SampleEvent, SampleEvent.table, properties=None)
+
+assign_mapper( context, SampleState, SampleState.table,
+ properties=None #dict( sample=relation( Sample, backref="sample" ),
+ )# )
assign_mapper( context, ValidationError, ValidationError.table )
@@ -590,6 +696,8 @@
assign_mapper( context, User, User.table,
properties=dict( histories=relation( History, backref="user",
order_by=desc(History.table.c.update_time) ),
+ requests=relation( Request, backref="user",
+ order_by=desc(Request.table.c.update_time) ),
active_histories=relation( History, primaryjoin=( ( History.table.c.user_id == User.table.c.id ) & ( not_( History.table.c.deleted ) ) ), order_by=desc( History.table.c.update_time ) ),
galaxy_sessions=relation( GalaxySession, order_by=desc( GalaxySession.table.c.update_time ) ),
stored_workflow_menu_entries=relation( StoredWorkflowMenuEntry, backref="user",
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/model/migrate/versions/0008_galaxy_forms.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/model/migrate/versions/0008_galaxy_forms.py Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,189 @@
+from sqlalchemy import *
+from sqlalchemy.orm import *
+from sqlalchemy.exceptions import *
+from migrate import *
+from migrate.changeset import *
+
+import datetime
+now = datetime.datetime.utcnow
+
+import sys, logging
+log = logging.getLogger( __name__ )
+log.setLevel(logging.DEBUG)
+handler = logging.StreamHandler( sys.stdout )
+format = "%(name)s %(levelname)s %(asctime)s %(message)s"
+formatter = logging.Formatter( format )
+handler.setFormatter( formatter )
+log.addHandler( handler )
+
+# Need our custom types, but don't import anything else from model
+from galaxy.model.custom_types import *
+
+metadata = MetaData( migrate_engine )
+db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, transactional=False ) )
+
+
+FormDefinitionCurrent_table = Table('form_definition_current', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "latest_form_id", Integer,
+ #ForeignKey( "form_definition.id", use_alter=True, name='form_definition_current_latest_form_id_fk'),
+ index=True ),
+ Column( "deleted", Boolean, index=True, default=False ))
+FormDefinition_table = Table('form_definition', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "form_definition_current_id", Integer, ForeignKey( "form_definition_current.id" ), index=True, nullable=False ),
+ Column( "fields", JSONType()) )
+
+FormValues_table = Table('form_values', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "form_definition_id", Integer, ForeignKey( "form_definition.id" ), index=True ),
+ Column( "content", JSONType()) )
+
+RequestType_table = Table('request_type', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "request_form_id", Integer, ForeignKey( "form_definition.id" ), index=True ),
+ Column( "sample_form_id", Integer, ForeignKey( "form_definition.id" ), index=True ) )
+# request table
+Request_table = Table('request', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "form_values_id", Integer, ForeignKey( "form_values.id" ), index=True ),
+ Column( "request_type_id", Integer, ForeignKey( "request_type.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ),
+ Column( "library_id", Integer, ForeignKey( "library.id" ), index=True ),
+ Column( "deleted", Boolean, index=True, default=False ) )
+
+Sample_table = Table('sample', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "form_values_id", Integer, ForeignKey( "form_values.id" ), index=True ),
+ Column( "request_id", Integer, ForeignKey( "request.id" ), index=True ),
+ Column( "deleted", Boolean, index=True, default=False ) )
+
+SampleState_table = Table('sample_state', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "name", TrimmedString( 255 ), nullable=False ),
+ Column( "desc", TEXT ),
+ Column( "request_type_id", Integer, ForeignKey( "request_type.id" ), index=True ) )
+
+SampleEvent_table = Table('sample_event', metadata,
+ Column( "id", Integer, primary_key=True),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "sample_id", Integer, ForeignKey( "sample.id" ), index=True ),
+ Column( "sample_state_id", Integer, ForeignKey( "sample_state.id" ), index=True ),
+ Column( "comment", TEXT ) )
+
+
+
+
+def upgrade():
+ # Load existing tables
+ metadata.reflect()
+
+ # Add all of the new tables above
+# metadata.create_all()
+ try:
+ FormDefinitionCurrent_table.create()
+ except Exception, e:
+ log.debug( "Creating form_definition_current table failed: %s" % str( e ) )
+ try:
+ FormDefinition_table.create()
+ except Exception, e:
+ log.debug( "Creating form_definition table failed: %s" % str( e ) )
+ # Add 1 foreign key constraint to the form_definition_current table
+ if FormDefinitionCurrent_table and FormDefinition_table:
+ try:
+ cons = ForeignKeyConstraint( [FormDefinitionCurrent_table.c.latest_form_id],
+ [FormDefinition_table.c.id],
+ name='form_definition_current_latest_form_id_fk' )
+ # Create the constraint
+ cons.create()
+ except Exception, e:
+ log.debug( "Adding foreign key constraint 'form_definition_current_latest_form_id_fk' to table 'form_definition_current' failed: %s" % ( str( e ) ) )
+ try:
+ FormValues_table.create()
+ except Exception, e:
+ log.debug( "Creating form_values table failed: %s" % str( e ) )
+ try:
+ RequestType_table.create()
+ except Exception, e:
+ log.debug( "Creating request_type table failed: %s" % str( e ) )
+ try:
+ Request_table.create()
+ except Exception, e:
+ log.debug( "Creating request table failed: %s" % str( e ) )
+ try:
+ Sample_table.create()
+ except Exception, e:
+ log.debug( "Creating sample table failed: %s" % str( e ) )
+ try:
+ SampleState_table.create()
+ except Exception, e:
+ log.debug( "Creating sample_state table failed: %s" % str( e ) )
+ try:
+ SampleEvent_table.create()
+ except Exception, e:
+ log.debug( "Creating sample_event table failed: %s" % str( e ) )
+
+
+
+def downgrade():
+ # Load existing tables
+ metadata.reflect()
+ try:
+ FormDefinition_table.drop()
+ except Exception, e:
+ log.debug( "Dropping form_definition table failed: %s" % str( e ) )
+ try:
+ FormDefinitionCurrent_table.drop()
+ except Exception, e:
+ log.debug( "Dropping form_definition_current table failed: %s" % str( e ) )
+ try:
+ FormValues_table.drop()
+ except Exception, e:
+ log.debug( "Dropping form_values table failed: %s" % str( e ) )
+ try:
+ Request_table.drop()
+ except Exception, e:
+ log.debug( "Dropping request table failed: %s" % str( e ) )
+ try:
+ RequestType_table.drop()
+ except Exception, e:
+ log.debug( "Dropping request_type table failed: %s" % str( e ) )
+ try:
+ Sample_table.drop()
+ except Exception, e:
+ log.debug( "Dropping sample table failed: %s" % str( e ) )
+ try:
+ SampleState_table.drop()
+ except Exception, e:
+ log.debug( "Dropping sample_state table failed: %s" % str( e ) )
+ try:
+ SampleEvent_table.drop()
+ except Exception, e:
+ log.debug( "Dropping sample_event table failed: %s" % str( e ) )
+
+
+
+
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py Thu Jul 09 15:49:26 2009 -0400
+++ b/lib/galaxy/web/controllers/admin.py Fri Jul 10 11:37:28 2009 -0400
@@ -3,6 +3,7 @@
from galaxy import util, datatypes
from galaxy.web.base.controller import *
from galaxy.model.orm import *
+import sys
import logging
log = logging.getLogger( __name__ )
@@ -2097,4 +2098,123 @@
else:
last_updated[job.id] = '%s minutes' % int( delta.seconds / 60 )
return trans.fill_template( '/admin/jobs.mako', jobs = jobs, last_updated = last_updated, cutoff = cutoff, msg = msg, messagetype = messagetype )
-
+
+ def _get_all_forms(self, trans, all_versions=False):
+ '''
+ This method returns all the latest forms from the
+ form_definition_current table if all_versions is set to True. Otherwise
+ this method return all the versions of all the forms from form_definition
+ table
+ '''
+ if all_versions:
+ return trans.app.model.FormDefinition.query().all()
+ else:
+ fdc_list = trans.app.model.FormDefinitionCurrent.query().all()
+ return [fdc.latest_form for fdc in fdc_list]
+ @web.expose
+ @web.require_admin
+ def manage_request_types( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ forms = self._get_all_forms(trans, all_versions=True)
+ return trans.fill_template( '/admin/requests/manage_request_types.mako',
+ request_types=trans.app.model.RequestType.query().all(),
+ forms=forms,
+ deleted=False,
+ show_deleted=False,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ @web.require_admin
+ def request_type( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ if params.get('create', False) == 'True':
+ return trans.fill_template( '/admin/requests/create_request_type.mako',
+ forms=self._get_all_forms(trans, all_versions=False),
+ msg=msg,
+ messagetype=messagetype)
+ elif params.get('add_states', False) == 'True':
+ return trans.fill_template( '/admin/requests/add_states.mako',
+ sample_type_name=util.restore_text( params.name ),
+ desc=util.restore_text( params.description ),
+ num_states=int(util.restore_text( params.num_states )),
+ request_form_id=int(util.restore_text( params.request_form_id )),
+ sample_form_id=int(util.restore_text( params.sample_form_id )),
+ msg=msg,
+ messagetype=messagetype)
+ elif params.get('save_new', False) == 'True':
+ st, msg = self._save_request_type(trans, params, None)
+ if not st:
+ return trans.fill_template( '/admin/requests/create_request_type.mako',
+ forms=self._get_all_forms(trans, all_versions=False),
+ msg=msg,
+ messagetype='error')
+ return trans.fill_template( '/admin/requests/manage_request_types.mako',
+ request_types=trans.app.model.RequestType.query().all(),
+ forms=self._get_all_forms(trans, all_versions=True),
+ deleted=False,
+ show_deleted=False,
+ msg=msg,
+ messagetype=messagetype )
+ elif params.get('edit', False) == 'True':
+ rt = trans.app.model.RequestType.get(int(util.restore_text( params.id )))
+ ss_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == rt.id).all()
+ return trans.fill_template( '/admin/requests/edit_request_type.mako',
+ request_type=rt,
+ forms=self._get_all_forms(trans, all_versions=False),
+ states_list=ss_list,
+ deleted=False,
+ show_deleted=False,
+ msg=msg,
+ messagetype=messagetype )
+ elif params.get('save_changes', False) == 'True':
+ st = trans.app.model.SampleType.get(int(util.restore_text( params.id )))
+ st, msg = self._save_sample_type(trans, params, st.id)
+ if st:
+ msg = "The sample type '%s' has been updated with the changes." % st.name
+ messagetype = 'done'
+ else:
+ messagetype = 'error'
+ ss_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.sample_type_id == st.id).all()
+ return trans.fill_template( '/admin/samples/edit_sample_type.mako',
+ sample_type=st,
+ forms=self._get_all_forms(trans, all_versions=False),
+ states_list=ss_list,
+ deleted=False,
+ show_deleted=False,
+ msg=msg,
+ messagetype=messagetype )
+ def _save_request_type(self, trans, params, request_type_id):
+ num_states = int( params.get( 'num_states', 0 ) )
+ proceed = True
+ for i in range( num_states ):
+ if not params.get( 'new_element_name_%i' % i, None ):
+ proceed = False
+ break
+ if not proceed:
+ msg = "All the state name(s) must be completed."
+ return None, msg
+ if not request_type_id: # create a new sample type to save
+ rt = trans.app.model.RequestType()
+ else: # use the existing sample type to save changes
+ rt = trans.app.model.RequestType.get(request_type_id)
+ rt.name = util.restore_text( params.name )
+ rt.desc = util.restore_text( params.description ) or ""
+ rt.request_form_id = int(util.restore_text( params.request_form_id ))
+ rt.sample_form_id = int(util.restore_text( params.sample_form_id ))
+ rt.flush()
+ # set sample states
+ ss_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == rt.id).all()
+ for ss in ss_list:
+ ss.delete()
+ ss.flush()
+ for i in range( num_states ):
+ name = params.get( 'new_element_name_%i' % i, None )
+ desc = params.get( 'new_element_description_%i' % i, None )
+ ss = trans.app.model.SampleState(name, desc, rt.id)
+ ss.flush()
+ msg = "The new sample type named '%s' with %s state(s) has been created" % (rt.name, num_states)
+ return rt, msg
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/web/controllers/forms.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/web/controllers/forms.py Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,323 @@
+from galaxy.web.base.controller import *
+from galaxy.model.orm import *
+from galaxy.datatypes import sniff
+from galaxy import util
+import logging, os, sys
+from galaxy.web.form_builder import *
+from galaxy.tools.parameters.basic import parameter_types
+from elementtree.ElementTree import XML, Element
+from galaxy.util.odict import odict
+import copy
+
+log = logging.getLogger( __name__ )
+
+
+class Forms( BaseController ):
+ @web.expose
+ @web.require_admin
+ def index( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ return trans.fill_template( "/sample/index.mako",
+ default_action=params.get( 'default_action', None ),
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ @web.require_admin
+ def manage( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ return self._show_forms_list(trans, msg, messagetype)
+ def _show_forms_list(self, trans, msg, messagetype):
+ fdc_list = trans.app.model.FormDefinitionCurrent.query().all()
+ return trans.fill_template( '/admin/forms/manage_forms.mako',
+ fdc_list=fdc_list,
+ deleted=False,
+ show_deleted=False,
+ msg=msg,
+ messagetype=messagetype )
+ def _get_all_forms(self, trans, all_versions=False):
+ '''
+ This method returns all the latest forms from the
+ form_definition_current table if all_versions is set to True. Otherwise
+ this method return all the versions of all the forms from form_definition
+ table
+ '''
+ if all_versions:
+ return trans.app.model.FormDefinition.query().all()
+ else:
+ fdc_list = trans.app.model.FormDefinitionCurrent.query().all()
+ return [fdc.latest_form for fdc in fdc_list]
+ @web.expose
+ @web.require_admin
+ def new( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ if params.get('new', False) and not params.get('create_form', False):
+ self.current_form = {}
+ self.current_form['name'] = 'New Form'
+ self.current_form['desc'] = ''
+ self.current_form['fields'] = []
+ inputs = [ ( 'Name', TextField('name', 40,self.current_form['name'] ) ),
+ ( 'Description', TextField('description', 40, self.current_form['desc']) ) ]
+ return trans.fill_template( '/admin/forms/create_form.mako',
+ inputs=inputs,
+ msg=msg,
+ messagetype=messagetype )
+ elif params.get('create_form', False) == 'True':
+ if 'submitted' in params.new:
+ self.num_add_fields = 0
+ fd, msg = self.__save_form(trans, params)
+ self.__get_saved_form(fd)
+ return self._show_forms_list(trans, msg, messagetype)
+ @web.expose
+ @web.require_admin
+ def edit( self, trans, **kwd ):
+ '''
+ This callback method is for handling all the editing functions like:
+ remaning fields, adding/deleting fields, changing fields attributes
+ '''
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ fd = trans.app.model.FormDefinition.get(int(util.restore_text( params.form_id )))
+ # SHOW THE FORM FOR EDITING.
+ if params.get('show_form', False) == 'True':
+ self.__get_saved_form(fd)
+ # the following two dicts store the unsaved select box options
+ self.del_options = {}
+ self.add_options = {}
+ return self.__show(trans, params, fd)
+ # DELETE FIELD
+ elif params.get('remove_button', False):
+ self.__update_current_form(params)
+ index = int(params.get('remove_button', None).split(' ')[2])-1
+ self.__remove_field(index)
+ return self.__show(trans, params, fd)
+ # SAVE CHANGES
+ elif params.get('save_changes_button', False) == 'Save':
+ self.__update_current_form(params)
+ fd_new, msg = self.__save_form(trans, params, fd.form_definition_current.id)
+ if not fd_new:
+ return self.__show(trans, params, fd, msg, 'error')
+ else:
+ fd = fd_new
+ msg = "The form '%s' has been updated with the changes." % fd.name
+ return self.__show(trans, params, fd, msg)
+ #ADD A FIELD
+ elif params.get('add_field_button', False) == 'Add field':
+ self.__update_current_form(params)
+ self.__add_field()
+ # show the form again with one empty field
+ return self.__show(trans, params, fd)
+ # SHOW FORM READ ONLY
+ elif params.get('read_only', False):
+ return trans.fill_template( '/admin/forms/show_form_read_only.mako',
+ form=fd,
+ msg=msg,
+ messagetype=messagetype )
+ # REFRESH PAGE, SelectField is selected/deselected as the type of a field
+ elif params.get('refresh', False) == 'true':
+ self.__update_current_form(params)
+ return self.__show(trans, params, fd)
+ # REMOVE SelectField OPTION
+ elif params.get('select_box_options', False) == 'remove':
+ #self.__update_current_form(params)
+ index = int(params.get( 'field_index', None ))
+ option = int(params.get( 'option_index', None ))
+ del self.current_form['fields'][index]['selectlist'][option]
+ return self.__show(trans, params, fd)
+ # ADD SelectField OPTION
+ elif params.get('select_box_options', False) == 'add':
+ #self.__update_current_form(params)
+ index = int(params.get( 'field_index', None ))
+ self.current_form['fields'][index]['selectlist'].append('')
+ return self.__show(trans, params, fd)
+ def __remove_field(self, index):
+ del self.current_form['fields'][index]
+ def __add_field(self):
+ '''
+ add an empty field to the fields list
+ '''
+ empty_field = { 'label': '',
+ 'helptext': '',
+ 'visible': True,
+ 'required': False,
+ 'type': BaseField.form_field_types()[0],
+ 'selectlist': '' }
+ self.current_form['fields'].append(empty_field)
+ def __get_field(self, params, index):
+ name = params.get( 'field_name_%i' % index, None )
+ helptext = params.get( 'field_helptext_%i' % index, None )
+ required = params.get( 'field_required_%i' % index, False )
+ field_type = params.get( 'field_type_%i' % index, None )
+ if field_type == 'SelectField':
+ selectlist = self.__get_selectbox_options(params, index)
+ else:
+ selectlist = None
+ return {'label': name,
+ 'helptext': helptext,
+ 'visible': True,
+ 'required': required,
+ 'type': field_type,
+ 'selectlist': selectlist }
+ def __get_selectbox_options(self, params, index):
+ '''
+ This method gets all the options entered by the user for field when
+ the fieldtype is SelectField
+ '''
+ ctr=0
+ sb_options = []
+ while True:
+ option = params.get( 'field_'+str(index)+'_option_'+str(ctr), None )
+ ctr = ctr+1
+ if option:
+ sb_options.append(option)
+ else:
+ return sb_options
+ def __get_saved_form(self, fd):
+ self.current_form = {}
+ self.current_form['name'] = fd.name
+ self.current_form['desc'] = fd.desc
+ self.current_form['fields'] = list(copy.deepcopy(fd.fields))
+ def __validate_form(self, params):
+ '''
+ This method checks the following text inputs are filled out by the user
+ - the name of form
+ - name of all the fields
+ '''
+ # form name
+ if not util.restore_text( params.name ):
+ return None, 'Form name must be filled.'
+ # fields
+ for i in range( len(self.current_form['fields']) ):
+ if not params.get( 'field_name_%i' % i, None ):
+ return None, "All the field label(s) must be completed."
+ return True, ''
+ def __get_form(self, params):
+ name = util.restore_text( params.name )
+ desc = util.restore_text( params.description ) or ""
+ # set form fields
+ fields = []
+ for i in range( len(self.current_form['fields']) ):
+ fields.append(self.__get_field(params, i))
+ fields = fields
+ return name, desc, fields
+ def __update_current_form(self, params):
+ name, desc, fields = self.__get_form(params)
+ self.current_form = {}
+ self.current_form['name'] = name
+ self.current_form['desc'] = desc
+ self.current_form['fields'] = fields
+
+ def __save_form(self, trans, params, fdc_id=None):
+ '''
+ This method saves the current form
+ '''
+ # check the form for invalid inputs
+ flag, msg = self.__validate_form(params)
+ if not flag:
+ return None, msg
+ fd = trans.app.model.FormDefinition()
+ fd.name, fd.desc, fd.fields = self.__get_form(params)
+ if fdc_id: # save changes to the existing form
+ # change the pointer in the form_definition_current table to point
+ # to this new record
+ fdc = trans.app.model.FormDefinitionCurrent.get(fdc_id)
+ else: # create a new form
+ fdc = trans.app.model.FormDefinitionCurrent()
+ # create corresponding row in the form_definition_current table
+ fd.form_definition_current = fdc
+ fdc.latest_form = fd
+ trans.sa_session.save_or_update( fdc )
+ trans.sa_session.flush()
+ msg = "The new form named '%s' has been created. " % (fd.name)
+ request_types = trans.app.model.RequestType.query().all()
+ if not request_types:
+ msg = msg + "Now you can create requests to associate with this form."
+ return fd, msg
+
+ class FieldUI(object):
+ def __init__(self, index, field=None, field_type=None):
+ '''
+ This method returns a list of widgets which describes a field. This
+ includes label, helptext, type, & required/optional
+ '''
+ self.index = index
+ self.label = TextField('field_name_'+str(index), 40, '')
+ self.helptext = TextField('field_helptext_'+str(index), 40, '')
+ self.fieldtype = SelectField('field_type_'+str(index),
+ refresh_on_change=True,
+ refresh_on_change_values=['SelectField'])
+ self.selectbox_options = []
+ for ft in BaseField.form_field_types():
+ self.fieldtype.add_option(ft, ft)
+ self.required = SelectField('field_required_'+str(index), display='radio')
+ self.required.add_option('Required', 'true')
+ self.required.add_option('Optional', 'true', selected=True)
+ if field:
+ self.fill(field, field_type)
+ def fill(self, field, field_type=None):
+ # label
+ self.label.value = field['label']
+ # helptext
+ self.helptext.value = field['helptext']
+ # type
+ self.fieldtype = SelectField('field_type_'+str(self.index),
+ refresh_on_change=True,
+ refresh_on_change_values=['SelectField'])
+ if field_type:
+ field['type'] = unicode(field_type)
+ if field_type == 'SelectField' and not field['selectlist']:
+ field['selectlist'] = ['', '']
+ for ft in BaseField.form_field_types():
+ if ft == field['type']:
+ self.fieldtype.add_option(ft, ft, selected=True)
+ if ft == 'SelectField':
+ self.selectbox_ui(field)
+ else:
+ self.fieldtype.add_option(ft, ft)
+ # required/optional
+ if field['required']:
+ self.required = SelectField('required_'+str(self.index), display='radio')
+ self.required.add_option('Required', 'true', selected=True)
+ self.required.add_option('Optional', 'true')
+ def selectbox_ui(self, field):
+ self.selectbox_options = []
+ if field['selectlist']:
+ for ctr, option in enumerate(field['selectlist']):
+ self.selectbox_options.append(('Option '+str(ctr+1),
+ TextField('field_'+str(self.index)+'_option_'+str(ctr),
+ 40, option)))
+ def get(self):
+ return [( 'Label', self.label ),
+ ( 'Help text', self.helptext ),
+ ( 'Type', self.fieldtype, self.selectbox_options),
+ ( '', self.required)]
+ def __repr__(self):
+ return str(self.index)+'.'+self.label
+ def label(self):
+ return str(self.index)+'.'+self.label
+
+ def __show(self, trans, params, form, msg=None, messagetype='done'):
+ '''
+ This method displays the form and any of the changes made to it
+ '''
+ # name & description
+ form_details = [ ( 'Name', TextField('name', 40, self.current_form['name']) ),
+ ( 'Description', TextField('description', 40, self.current_form['desc']) ) ]
+ # fields
+ field_details = []
+ for index, field in enumerate(self.current_form['fields']):
+ field_ui = self.FieldUI(index, field)
+ field_details.append( field_ui.get() )
+ return trans.fill_template( '/admin/forms/edit_form.mako',
+ form_details=form_details,
+ field_details=field_details,
+ form=form,
+ field_types=BaseField.form_field_types(),
+ msg=msg,
+ messagetype=messagetype )
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/web/controllers/requests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/web/controllers/requests.py Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,429 @@
+from galaxy.web.base.controller import *
+from galaxy.web.framework.helpers import time_ago, iff, grids
+from galaxy.model.orm import *
+from galaxy.datatypes import sniff
+from galaxy import util
+from galaxy.util.streamball import StreamBall
+import logging, tempfile, zipfile, tarfile, os, sys
+from galaxy.web.form_builder import *
+
+log = logging.getLogger( __name__ )
+
+# States for passing messages
+SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error"
+
+class RequestsListGrid( grids.Grid ):
+ title = "Requests"
+ model_class = model.Request
+ default_sort_key = "-create_time"
+ columns = [
+ grids.GridColumn( "Name", key="name",
+ link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ),
+ attach_popup=True ),
+ grids.GridColumn( "Description", key='desc'),
+ grids.GridColumn( "Sample(s)", method='number_of_samples',
+ link=( lambda item: iff( item.deleted, None, dict( operation="samples", id=item.id ) ) ), ),
+ grids.GridColumn( "Type", key="request_type_id", method='get_request_type'),
+ grids.GridColumn( "Last update", key="update_time", format=time_ago )
+ ]
+ operations = [
+# grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ),
+ grids.GridOperation( "Samples", allow_multiple=False, condition=( lambda item: not item.deleted ) ),
+# grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ),
+# grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ),
+ ]
+ standard_filters = [
+ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
+ grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
+ #default_filter = dict( deleted=False )
+ def get_current_item( self, trans ):
+ return None
+ def get_request_type(self, trans, request):
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ return request_type.name
+ def apply_default_filter( self, trans, query ):
+ return query.filter_by( user=trans.user )
+ def number_of_samples(self, trans, request):
+ return str(len(trans.app.model.Sample.filter(trans.app.model.Sample.table.c.request_id==request.id).all()))
+
+class SamplesListGrid( grids.Grid ):
+ model_class = model.Sample
+ default_sort_key = "-create_time"
+ columns = [
+ grids.GridColumn( "Name", key="name",
+ link=( lambda item: iff( item.deleted, None, dict( operation="show_sample", id=item.id ) ) ),
+ attach_popup=True ),
+ grids.GridColumn( "Description", key='desc' ),
+ grids.GridColumn( "Status", method="get_status",
+ link=( lambda item: iff( item.deleted, None, dict( operation="events", id=item.id ) ) )),
+
+ grids.GridColumn( "Last update", key="update_time", format=time_ago )
+
+ # Valid for filtering but invisible
+ #grids.GridColumn( "Deleted", key="deleted", visible=False )
+ ]
+ operations = [
+# grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ),
+# grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ),
+# grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ),
+
+ ]
+ standard_filters = [
+ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
+ grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
+ def __init__(self, request):
+ self.request = request
+ def get_current_item( self, trans ):
+ return None
+ def apply_default_filter( self, trans, query ):
+ return query.filter_by( request_id=self.request.id )
+ def get_status(self, trans, sample):
+ all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample.id).all()
+ curr_state = trans.app.model.SampleState.get(all_states[len(all_states)-1].sample_state_id)
+ return curr_state.name
+
+class Requests( BaseController ):
+ request_grid = RequestsListGrid()
+
+ @web.expose
+ def index( self, trans ):
+ return trans.fill_template( "requests/index.mako" )
+ def get_authorized_libs(self, trans):
+ all_libraries = trans.app.model.Library.filter(trans.app.model.Library.table.c.deleted == False).order_by(trans.app.model.Library.name).all()
+ authorized_libraries = []
+ for library in all_libraries:
+ if trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_ADD, library_item=library) or trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, library_item=library) or trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, library_item=library) or trans.app.security_agent.check_folder_contents(trans.user, library) or trans.app.security_agent.show_library_item(trans.user, library):
+ authorized_libraries.append(library)
+ return authorized_libraries
+ @web.expose
+ def list( self, trans, **kwargs ):
+ '''
+ List all request made by the current user
+ '''
+ status = message = None
+ if 'operation' in kwargs:
+ operation = kwargs['operation'].lower()
+ if operation == "show_request":
+ id = trans.security.decode_id(kwargs['id'])
+ return self.show_read_only(trans, id)
+ elif operation == "samples":
+ id = trans.security.decode_id(kwargs['id'])
+ return self.show_samples(trans, id, kwargs)
+ elif operation == "show_sample":
+ id = trans.security.decode_id(kwargs['id'])
+ return self.show_sample_read_only(trans, id)
+ elif operation == "events":
+ id = trans.security.decode_id(kwargs['id'])
+ return self.show_events(trans, id)
+ # Render the list view
+ return self.request_grid( trans, status=status, message=message, template='/requests/grid.mako', **kwargs )
+ def show_samples(self, trans, id, kwargs):
+ '''
+ Shows all the samples associated with this request
+ '''
+ status = message = None
+ request = trans.app.model.Request.get(id)
+ self.samples_grid = SamplesListGrid(request)
+ return self.samples_grid( trans, status=status, message=message, template='/sample/grid.mako', **kwargs )
+ def show_read_only(self, trans, id):
+ '''
+ Shows the request details
+ '''
+ request = trans.app.model.Request.get(id)
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ request_form = trans.app.model.FormDefinition.get(request_type.request_form_id)
+ request_values = trans.app.model.FormValues.get(request.form_values_id)
+ libraries = self.get_authorized_libs(trans)
+ # list of widgets to be rendered on the request form
+ request_details = []
+ # main details
+ request_details.append(dict(label='Name',
+ value=request.name,
+ helptext=''))
+ request_details.append(dict(label='Description',
+ value=request.desc,
+ helptext=''))
+ request_details.append(dict(label='Type',
+ value=request_type.name,
+ helptext=''))
+ request_details.append(dict(label='Date created',
+ value=request.create_time,
+ helptext=''))
+ request_details.append(dict(label='Date updated',
+ value=request.create_time,
+ helptext=''))
+ request_details.append(dict(label='User',
+ value=str(trans.user.email),
+ helptext=''))
+ # library associated
+ request_details.append(dict(label='Library',
+ value=trans.app.model.Library.get(request.library_id).name,
+ helptext='Associated library where the resultant \
+ dataset will be stored'))
+ # form fields
+ for field in request_form.fields:
+ if field['required']:
+ req = 'Required'
+ else:
+ req = 'Optional'
+ request_details.append(dict(label=field['label'],
+ value=request_values.content[field['label']],
+ helptext=field['helptext']+' ('+req+')'))
+ return trans.fill_template( '/requests/view_request.mako',
+ request_form_id=request_form.id,
+ request_details=request_details,
+ request_type=request_type)
+ @web.expose
+ def new(self, trans, **kwd):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ if params.get('select_request_type', False) == 'True':
+ return trans.fill_template( '/requests/select_request_type.mako',
+ request_types=trans.app.model.RequestType.query().all(),
+ libraries=self.get_authorized_libs(trans),
+ msg=msg,
+ messagetype=messagetype )
+ elif params.get('create', False) == 'True':
+ request_type_id = int(util.restore_text( params.request_type_id ))
+ return self.__show_request_form(trans, params, request_type_id)
+ elif params.get('save', False) == 'True':
+ request = self.__save(trans, params)
+ msg = 'The new request named %s has been created' % request.name
+ request_type_id = int(util.restore_text( params.request_type_id ))
+ return trans.response.send_redirect( web.url_for( controller='requests',
+ action='list',
+ msg=msg ,
+ messagetype='done') )
+ return self.__show_request_form(trans, params, request_type_id, request=request)
+ def __save(self, trans, params, request_id=None):
+ '''
+ This method save a new request if request_id is None.
+ '''
+ if not request_id:
+ request_type_id = int(util.restore_text( params.request_type_id ))
+ request_form_id = trans.app.model.RequestType.get(request_type_id).request_form_id
+ request_form = trans.app.model.FormDefinition.get(request_form_id)
+ else:
+ request = trans.app.model.Request.get(request_id)
+ form_values = trans.app.model.FormValues.get(request.form_values_id)
+ request_form = trans.app.model.FormDefinition.get(form_values.request_form_id)
+ name = params.get('name', '')
+ desc = params.get('desc', '')
+ library_id = params.get('library', '')
+ values = {}
+ for field in request_form.fields:
+ values[field['label']] = params.get(field['label'], '')
+ if not request_id:
+ form_values = trans.app.model.FormValues(request_form_id, values)
+ form_values.flush()
+ request = trans.app.model.Request(name, desc, request_type_id,
+ trans.user.id, form_values.id,
+ library_id)
+ request.flush()
+ else:
+ form_values.content = values
+ form_values.flush()
+ return request
+ def __show_request_form(self, trans, params, request_type_id, request=None):
+ request_type = trans.app.model.RequestType.get(request_type_id)
+ request_form_id = request_type.request_form_id
+ if request:
+ form_values = trans.app.model.FormValues.get(request.form_values_id)
+ else:
+ form_values = None
+ # list of widgets to be rendered on the request form
+ widgets = []
+ widgets.append(dict(label='Name',
+ widget=TextField('name'),
+ helptext='(Required)'))
+ widgets.append(dict(label='Description',
+ widget=TextField('desc'),
+ helptext='(Optional)'))
+ widgets[0]['widget'].set_size(40)
+ widgets[1]['widget'].set_size(40)
+ # libraries selectbox
+ libraries = self.get_authorized_libs(trans)
+ lib_list = SelectField('library')
+ for lib in libraries:
+ lib_list.add_option(lib.name, lib.id)
+ widgets.append(dict(label='Library',
+ widget=lib_list,
+ helptext='Associated library where the resultant \
+ dataset will be stored'))
+ widgets = self.__create_form(trans, params, request_form_id, widgets, form_values)
+ title = 'Add a new request of type: %s' % request_type.name
+ return trans.fill_template( '/requests/new_request.mako',
+ request_form_id=request_form_id,
+ request_type=request_type,
+ widgets=widgets,
+ title=title)
+
+ def __create_form(self, trans, params, form_id, widgets=[], form_values=None):
+ form = trans.app.model.FormDefinition.get(form_id)
+ if not form_values:
+ values = {}
+ for field in form.fields:
+ if field['type'] in ['SelectField' or 'CheckBoxField']:
+ values[field['label']] = False
+ else:
+ values[field['label']] = ''
+ else:
+ values = form_values.content
+ # form fields
+ for field in form.fields:
+ fw = eval(field['type'])(field['label'])
+ if field['type'] == 'TextField':
+ fw.set_size(40)
+ fw.value = values[field['label']]
+ elif field['type'] == 'TextArea':
+ fw.set_size(3, 40)
+ fw.value = values[field['label']]
+ elif field['type'] == 'SelectField':
+ for option in field['selectlist']:
+ fw.add_option(option, option, values[field['label']])
+ elif field['type'] == 'CheckBoxField':
+ fw.checked = values[field['label']]
+
+ if field['required']:
+ req = 'Required'
+ else:
+ req = 'Optional'
+ widgets.append(dict(label=field['label'],
+ widget=fw,
+ helptext=field['helptext']+' ('+req+')'))
+ return widgets
+ @web.expose
+ def add_sample(self, trans, **kwd):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ request_id = int(util.restore_text( params.get( 'id', '' ) ))
+ return self.__show_sample_form(trans, params, request_id)
+
+ def __show_sample_form(self, trans, params, request_id, sample=None):
+ request = trans.app.model.Request.get(request_id)
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ sample_form_id = request_type.sample_form_id
+ if sample:
+ form_values = trans.app.model.FormValues.get(sample.form_values_id)
+ else:
+ form_values = None
+ # list of widgets to be rendered on the request form
+ widgets = []
+ widgets.append(dict(label='Name',
+ widget=TextField('name'),
+ helptext='(Required)'))
+ widgets.append(dict(label='Description',
+ widget=TextField('desc'),
+ helptext='(Optional)'))
+ widgets[0]['widget'].set_size(40)
+ widgets[1]['widget'].set_size(40)
+ widgets = self.__create_form(trans, params, sample_form_id, widgets, form_values)
+ title = 'Add a new sample to request: %s of type: %s' % (request.name, request_type.name)
+ return trans.fill_template( '/sample/new_sample.mako',
+ sample_form_id=sample_form_id,
+ request_id=request.id,
+ widgets=widgets,
+ title=title)
+ @web.expose
+ def samples(self, trans, **kwd):
+ params = util.Params( kwd )
+ if params.get('save', False) == 'True':
+ sample = self.__save_sample(trans, params)
+ return trans.response.send_redirect( web.url_for( controller='requests',
+ action='list',
+ operation='samples',
+ id=trans.security.encode_id(sample.request_id)) )
+ def __save_sample(self, trans, params, sample_id=None):
+ if not sample_id:
+ request = trans.app.model.Request.get(int(util.restore_text( params.request_id )))
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ sample_form = trans.app.model.FormDefinition.get(request_type.sample_form_id)
+ else:
+ sample = trans.app.model.Sample.get(sample_id)
+ form_data = trans.app.model.FormData.get(sample.form_data_id)
+ form = trans.app.model.FormDefinition.get(form_data.form_definition_id)
+ name = params.get('name', '')
+ desc = params.get('desc', '')
+ values = {}
+ for field in sample_form.fields:
+ values[field['label']] = params.get(field['label'], '')
+ if not sample_id:
+ form_values = trans.app.model.FormValues(sample_form.id, values)
+ form_values.flush()
+ sample = trans.app.model.Sample(name, desc, request.id, form_values.id)
+ sample.flush()
+ # set the initial state
+ state = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == request_type.id).first()
+ event = trans.app.model.SampleEvent(sample.id, state.id)
+ event.flush()
+ else:
+ form_data.content = values
+ form_data.flush()
+ return sample
+ def show_sample_read_only(self, trans, sample_id):
+ '''
+ Shows the sample details
+ '''
+ sample = trans.app.model.Sample.get(sample_id)
+ request = trans.app.model.Request.get(sample.request_id)
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ sample_form = trans.app.model.FormDefinition.get(request_type.sample_form_id)
+ sample_values = trans.app.model.FormValues.get(sample.form_values_id)
+ # list of widgets to be rendered on the request form
+ sample_details = []
+ # main details
+ sample_details.append(dict(label='Name',
+ value=sample.name,
+ helptext=''))
+ sample_details.append(dict(label='Description',
+ value=sample.desc,
+ helptext=''))
+ sample_details.append(dict(label='Date created',
+ value=sample.create_time,
+ helptext=''))
+ sample_details.append(dict(label='Date updated',
+ value=sample.create_time,
+ helptext=''))
+ sample_details.append(dict(label='User',
+ value=str(trans.user.email),
+ helptext=''))
+ sample_details.append(dict(label='Request',
+ value=request.name,
+ helptext='Name/ID of the request this sample belongs to.'))
+ # get the current state of the sample
+ all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample_id).all()
+ curr_state = trans.app.model.SampleState.get(all_states[len(all_states)-1].sample_state_id)
+ sample_details.append(dict(label='State',
+ value=curr_state.name,
+ helptext=curr_state.desc))
+ # form fields
+ for field in sample_form.fields:
+ if field['required']:
+ req = 'Required'
+ else:
+ req = 'Optional'
+ sample_details.append(dict(label=field['label'],
+ value=sample_values.content[field['label']],
+ helptext=field['helptext']+' ('+req+')'))
+ return trans.fill_template( '/sample/view_sample.mako',
+ sample_details=sample_details)
+ def show_events(self, trans, sample_id):
+ sample = trans.app.model.Sample.get(sample_id)
+ events_list = []
+ for event in trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample_id).all():
+ state = trans.app.model.SampleState.get(event.sample_state_id)
+ events_list.append((state.name, event.update_time, state.desc, event.comment))
+ return trans.fill_template( '/sample/sample_events.mako',
+ events_list=events_list,
+ sample_name=sample.name,
+ request=trans.app.model.Request.get(sample.request_id).name)
+
+
+
+
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/web/controllers/requests_admin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/web/controllers/requests_admin.py Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,315 @@
+from galaxy.web.base.controller import *
+from galaxy.web.framework.helpers import time_ago, iff, grids
+from galaxy.model.orm import *
+from galaxy.datatypes import sniff
+from galaxy import util
+from galaxy.util.streamball import StreamBall
+import logging, tempfile, zipfile, tarfile, os, sys
+from galaxy.web.form_builder import *
+from datetime import datetime, timedelta
+
+log = logging.getLogger( __name__ )
+
+
+# States for passing messages
+SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error"
+
+class RequestsListGrid( grids.Grid ):
+ title = "Requests"
+ model_class = model.Request
+ default_sort_key = "-create_time"
+ columns = [
+ grids.GridColumn( "Name", key="name",
+ link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ),
+ attach_popup=True ),
+ grids.GridColumn( "Description", key="desc"),
+ grids.GridColumn( "Sample(s)", method='number_of_samples',
+ link=( lambda item: iff( item.deleted, None, dict( operation="samples", id=item.id ) ) ), ),
+ grids.GridColumn( "Type", key="request_type_id", method='get_request_type'),
+ grids.GridColumn( "Last update", key="update_time", format=time_ago ),
+ grids.GridColumn( "User", key="user_id", method='get_user')
+
+ ]
+ operations = [
+# grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ),
+ grids.GridOperation( "Samples", allow_multiple=False, condition=( lambda item: not item.deleted ) ),
+# grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ),
+# grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ),
+ ]
+ standard_filters = [
+ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
+ grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
+ def get_user(self, trans, request):
+ return trans.app.model.User.get(request.user_id).email
+ def get_current_item( self, trans ):
+ return None
+ def get_request_type(self, trans, request):
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ return request_type.name
+ def apply_default_filter( self, trans, query ):
+ return query
+ def number_of_samples(self, trans, request):
+ return str(len(trans.app.model.Sample.filter(trans.app.model.Sample.table.c.request_id==request.id).all()))
+
+class SamplesListGrid( grids.Grid ):
+ model_class = model.Sample
+ default_sort_key = "-create_time"
+ columns = [
+ grids.GridColumn( "Name", key="name",
+ link=( lambda item: iff( item.deleted, None, dict( operation="show_sample", id=item.id ) ) ),
+ attach_popup=True ),
+ grids.GridColumn( "Description", key='desc' ),
+ grids.GridColumn( "Status", method="get_status",
+ link=( lambda item: iff( item.deleted, None, dict( operation="events", id=item.id ) ) )),
+
+ grids.GridColumn( "Last update", key="update_time", format=time_ago )
+
+ # Valid for filtering but invisible
+ #grids.GridColumn( "Deleted", key="deleted", visible=False )
+ ]
+ operations = [
+# grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ),
+ grids.GridOperation( "Change state", condition=( lambda item: not item.deleted ) ),
+# grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ),
+# grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ),
+
+ ]
+ standard_filters = [
+ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
+ grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
+ def __init__(self, request, user):
+ self.request = request
+ self.user = user
+ def get_current_item( self, trans ):
+ return None
+ def apply_default_filter( self, trans, query ):
+ return query.filter_by( request_id=self.request.id )
+ def get_status(self, trans, sample):
+ all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample.id).all()
+ curr_state = trans.app.model.SampleState.get(all_states[len(all_states)-1].sample_state_id)
+ return curr_state.name
+
+class Requests( BaseController ):
+ request_grid = RequestsListGrid()
+
+ @web.expose
+ @web.require_admin
+ def index( self, trans ):
+ return trans.fill_template( "/admin/requests/index.mako" )
+ def get_authorized_libs(self, trans):
+ all_libraries = trans.app.model.Library.filter(trans.app.model.Library.table.c.deleted == False).order_by(trans.app.model.Library.name).all()
+ authorized_libraries = []
+ for library in all_libraries:
+ if trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_ADD, library_item=library) or trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, library_item=library) or trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, library_item=library) or trans.app.security_agent.check_folder_contents(trans.user, library) or trans.app.security_agent.show_library_item(trans.user, library):
+ authorized_libraries.append(library)
+ return authorized_libraries
+ @web.expose
+ @web.require_admin
+ def list( self, trans, **kwargs ):
+ '''
+ List all request made by the current user
+ '''
+ status = message = None
+ if 'operation' in kwargs:
+ operation = kwargs['operation'].lower()
+ if operation == "show_request":
+ id = trans.security.decode_id(kwargs['id'])
+ return self.show_read_only(trans, id)
+ elif operation == "samples":
+ id = trans.security.decode_id(kwargs['id'])
+ return self.show_samples(trans, id, kwargs)
+ elif operation == "show_sample":
+ id = trans.security.decode_id(kwargs['id'])
+ return self.show_sample_read_only(trans, id)
+ elif operation == "change state":
+ id_list = [trans.security.decode_id(id) for id in util.listify(kwargs['id'])]
+ return self.change_state(trans, id_list)
+ elif operation == "events":
+ id = trans.security.decode_id(kwargs['id'])
+ return self.show_events(trans, id)
+ # Render the list view
+ return self.request_grid( trans, status=status, message=message, template='/admin/requests/grid.mako', **kwargs )
+ def show_samples(self, trans, id, kwargs):
+ '''
+ Shows all the samples associated with this request
+ '''
+ status = message = None
+ request = trans.app.model.Request.get(id)
+ self.samples_grid = SamplesListGrid(request, trans.app.model.User.get(request.user_id))
+ return self.samples_grid( trans, status=status, message=message, template='/admin/samples/grid.mako', **kwargs )
+ def show_read_only(self, trans, id):
+ '''
+ Shows the request details
+ '''
+ request = trans.app.model.Request.get(id)
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ request_form = trans.app.model.FormDefinition.get(request_type.request_form_id)
+ request_values = trans.app.model.FormValues.get(request.form_values_id)
+ libraries = self.get_authorized_libs(trans)
+ # list of widgets to be rendered on the request form
+ request_details = []
+ # main details
+ request_details.append(dict(label='Name',
+ value=request.name,
+ helptext=''))
+ request_details.append(dict(label='Description',
+ value=request.desc,
+ helptext=''))
+ request_details.append(dict(label='Type',
+ value=request_type.name,
+ helptext=''))
+ request_details.append(dict(label='Date created',
+ value=request.create_time,
+ helptext=''))
+ request_details.append(dict(label='Date updated',
+ value=request.create_time,
+ helptext=''))
+ request_details.append(dict(label='User',
+ value=str(trans.user.email),
+ helptext=''))
+ # library associated
+ request_details.append(dict(label='Library',
+ value=trans.app.model.Library.get(request.library_id).name,
+ helptext='Associated library where the resultant \
+ dataset will be stored'))
+ # form fields
+ for field in request_form.fields:
+ if field['required']:
+ req = 'Required'
+ else:
+ req = 'Optional'
+ request_details.append(dict(label=field['label'],
+ value=request_values.content[field['label']],
+ helptext=field['helptext']+' ('+req+')'))
+ return trans.fill_template( '/admin/requests/view_request.mako',
+ request_form_id=request_form.id,
+ request_details=request_details,
+ request_type=request_type)
+
+ @web.expose
+ @web.require_admin
+ def samples(self, trans, **kwd):
+ params = util.Params( kwd )
+ if params.get('save', False) == 'True':
+ sample = self.__save_sample(trans, params)
+ return self.show_samples(trans, sample.request_id, {})
+ def show_sample_read_only(self, trans, sample_id):
+ '''
+ Shows the sample details
+ '''
+ sample = trans.app.model.Sample.get(sample_id)
+ request = trans.app.model.Request.get(sample.request_id)
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ sample_form = trans.app.model.FormDefinition.get(request_type.sample_form_id)
+ sample_values = trans.app.model.FormValues.get(sample.form_values_id)
+ # list of widgets to be rendered on the request form
+ sample_details = []
+ # main details
+ sample_details.append(dict(label='Name',
+ value=request.name,
+ helptext=''))
+ sample_details.append(dict(label='Description',
+ value=request.desc,
+ helptext=''))
+ sample_details.append(dict(label='Date created',
+ value=sample.create_time,
+ helptext=''))
+ sample_details.append(dict(label='Date updated',
+ value=sample.create_time,
+ helptext=''))
+ sample_details.append(dict(label='User',
+ value=str(trans.user.email),
+ helptext=''))
+ sample_details.append(dict(label='Request',
+ value=request.name,
+ helptext='Name/ID of the request this sample belongs to.'))
+ # get the current state of the sample
+ all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample_id).all()
+ curr_state = trans.app.model.SampleState.get(all_states[len(all_states)-1].sample_state_id)
+ sample_details.append(dict(label='State',
+ value=curr_state.name,
+ helptext=curr_state.desc))
+ # form fields
+ for field in sample_form.fields:
+ if field['required']:
+ req = 'Required'
+ else:
+ req = 'Optional'
+ sample_details.append(dict(label=field['label'],
+ value=sample_values.content[field['label']],
+ helptext=field['helptext']+' ('+req+')'))
+ return trans.fill_template( '/admin/samples/view_sample.mako',
+ sample_details=sample_details)
+ def __get_all_states(self, trans, sample):
+ request = trans.app.model.Request.get(sample.request_id)
+ request_type = trans.app.model.RequestType.get(request.request_type_id)
+ all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample.id).all()
+ curr_state = trans.app.model.SampleState.get(all_states[len(all_states)-1].sample_state_id)
+ states_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == request_type.id)
+ return states_list
+ def __get_curr_state(self, trans, sample):
+ all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample.id).all()
+ curr_state = trans.app.model.SampleState.get(all_states[len(all_states)-1].sample_state_id)
+ return curr_state
+ def change_state(self, trans, sample_id_list):
+ sample = trans.app.model.Sample.get(sample_id_list[0])
+ states_list = self.__get_all_states(trans, sample)
+ curr_state = self.__get_curr_state(trans, sample)
+ states_input = SelectField('select_state')
+ for state in states_list:
+ if len(sample_id_list) == 1:
+ if curr_state.name == state.name:
+ states_input.add_option(state.name+' (Current)', state.name, selected=True)
+ else:
+ states_input.add_option(state.name, state.name)
+ else:
+ states_input.add_option(state.name, state.name)
+ widgets = []
+ widgets.append(('Select the new state of the sample(s) from the list of possible state(s)',
+ states_input))
+ widgets.append(('Comments', TextArea('comment')))
+ title = 'Change current state of sample: ' + sample.name
+ return trans.fill_template( '/admin/samples/change_state.mako',
+ widgets=widgets, title=title,
+ sample_id_list=util.object_to_string(sample_id_list))
+ @web.expose
+ @web.require_admin
+ def save_state(self, trans, **kwd):
+ params = util.Params( kwd )
+ sample_id_list = util.string_to_object(util.restore_text( params.sample_id_list ))
+ comments = util.restore_text( params.comment )
+ sample = trans.app.model.Sample.get(sample_id_list[0])
+ request = trans.app.model.Request.get(sample.request_id)
+ selected_state = util.restore_text( params.select_state )
+ new_state = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == request.request_type_id
+ and trans.app.model.SampleState.table.c.name == selected_state)[0]
+ for sample_id in sample_id_list:
+ event = trans.app.model.SampleEvent(sample_id, new_state.id, comments)
+ event.flush()
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='list',
+ operation='samples',
+ id=trans.security.encode_id(request.id)) )
+ @web.expose
+ @web.require_admin
+ def show_events(self, trans, sample_id):
+ sample = trans.app.model.Sample.get(sample_id)
+ request = trans.app.model.Request.get(sample.request_id)
+ events_list = []
+ for event in trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample_id).order_by(trans.app.model.SampleEvent.c.update_time.desc()).all():
+ state = trans.app.model.SampleState.get(event.sample_state_id)
+ delta = datetime.utcnow() - event.update_time
+ if delta > timedelta( minutes=60 ):
+ last_update = '%s hours' % int( delta.seconds / 60 / 60 )
+ else:
+ last_update = '%s minutes' % int( delta.seconds / 60 )
+ events_list.append((state.name, state.desc, last_update, event.comment))
+ return trans.fill_template( '/admin/samples/events.mako',
+ events_list=events_list,
+ sample_name=sample.name, user=trans.app.model.User.get(request.user_id),
+ request=request.name)
+
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/web/form_builder.py
--- a/lib/galaxy/web/form_builder.py Thu Jul 09 15:49:26 2009 -0400
+++ b/lib/galaxy/web/form_builder.py Fri Jul 10 11:37:28 2009 -0400
@@ -9,6 +9,11 @@
def get_html( self, prefix="" ):
"""Returns the html widget corresponding to the parameter"""
raise TypeError( "Abstract Method" )
+ @staticmethod
+ def form_field_types():
+ return ['TextField', 'TextArea', 'SelectField', 'CheckboxField']
+
+
class TextField(BaseField):
"""
@@ -26,6 +31,8 @@
def get_html( self, prefix="" ):
return '<input type="text" name="%s%s" size="%d" value="%s">' \
% ( prefix, self.name, self.size, self.value )
+ def set_size(self, size):
+ self.size = int( size )
class TextArea(BaseField):
"""
@@ -45,6 +52,9 @@
def get_html( self, prefix="" ):
return '<textarea name="%s%s" rows="%d" cols="%d">%s</textarea>' \
% ( prefix, self.name, self.rows, self.cols, self.value )
+ def set_size(self, rows, cols):
+ self.rows = rows
+ self.cols = cols
class CheckboxField(BaseField):
"""
@@ -215,6 +225,17 @@
rval.insert( 0, '<select name="%s%s"%s%s%s>' % ( prefix, self.name, multiple, self.refresh_on_change_text, last_selected_value ) )
rval.append( '</select>' )
return "\n".join( rval )
+ def get_selected(self):
+ '''
+ This method returns the currently selected option's text and value
+ '''
+ for text, value, selected in self.options:
+ if selected:
+ return text, value
+ if self.options:
+ return self.options[0]
+ return None
+
class DrillDownField( BaseField ):
diff -r 267db48a2371 -r b46f27137744 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py Thu Jul 09 15:49:26 2009 -0400
+++ b/lib/galaxy/web/framework/__init__.py Fri Jul 10 11:37:28 2009 -0400
@@ -607,6 +607,11 @@
if dbkey == ds.dbkey:
return ds
return None
+
+ def request_types(self):
+ if self.app.model.RequestType.query().all():
+ return True
+ return False
class FormBuilder( object ):
"""
diff -r 267db48a2371 -r b46f27137744 templates/admin/forms/create_form.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/forms/create_form.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,31 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Create a new form definition</div>
+ <div class="toolFormBody">
+ <form name="create_form" action="${h.url_for( controller='forms', action='new', create_form=True, new=False, create_fields=False )}" method="post" >
+ %for label, input in inputs:
+ <div class="form-row">
+ <label>${label}</label>
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ ${input.get_html()}
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ %endfor
+ <div class="form-row">
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="hidden" name="new" value="submitted" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <input type="submit" name="save_form" value="Save"/>
+ </form>
+ </div>
+</div>
diff -r 267db48a2371 -r b46f27137744 templates/admin/forms/edit_form.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/forms/edit_form.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,105 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<script type="text/javascript">
+$( function() {
+ $( "select[refresh_on_change='true']").change( function() {
+ var refresh = false;
+ var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' )
+ if ( refresh_on_change_values ) {
+ refresh_on_change_values = refresh_on_change_values.value.split( ',' );
+ var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' );
+ for( i= 0; i < refresh_on_change_values.length; i++ ) {
+ if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){
+ refresh = true;
+ break;
+ }
+ }
+ }
+ else {
+ refresh = true;
+ }
+ if ( refresh ){
+ $( "#edit_form" ).submit();
+ }
+ });
+});
+</script>
+
+<%def name="render_selectbox_options( index, field_attr )">
+ %if field_attr[0] == 'Type':
+ %if field_attr[1].get_selected()[0] == 'SelectField':
+ <% options = field_attr[2] %>
+ <div class="repeat-group-item">
+ <label> Options</label>
+ %for i, option in enumerate(options):
+ <b> ${i+1}</b>
+ ${option[1].get_html()}
+ ##<input type="submit" name="remove_option_${index}" value="Remove option ${i+1}"/><br>
+ <a class="action-button" href="${h.url_for( controller='forms', action='edit', form_id=form.id, select_box_options='remove', field_index=index, option_index=i )}">Remove</a><br>
+ %endfor
+ </div>
+ <div class="form-row">
+ <a class="action-button" href="${h.url_for( controller='forms', action='edit', form_id=form.id, select_box_options='add', field_index=index )}">Add</a>
+ </div>
+ ##<div class="form-row">
+ ## <input type="submit" name="add_option_field_${index}" value="Add option"/>
+ ##</div>
+ %endif
+ %endif
+</%def>
+
+
+<%def name="render_field( index, field )">
+ <div class="repeat-group-item">
+ <div class="form-row">
+ <label>Field ${1+index}</label>
+ </div>
+ %for field_attr in field:
+ <div class="form-row">
+ <label>${field_attr[0]}</label>
+ ${field_attr[1].get_html()}
+ ${render_selectbox_options( index, field_attr )}
+ </div>
+ %endfor
+ <div class="form-row">
+ <input type="submit" name="remove_button" value="Remove field ${index+1}"/>
+ </div>
+ </div>
+</%def>
+
+<div class="toolForm">
+ <div class="toolFormTitle">Edit form definition '${form.name}'</div>
+ <form id="edit_form" name="edit_form" action="${h.url_for( controller='forms', action='edit', form_id=form.id, num_fields=len(form.fields) )}" method="post" >
+ %for label, input in form_details:
+ <div class="form-row">
+ <label>${label}</label>
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ ${input.get_html()}
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ %endfor
+ <div class="toolFormTitle">Sample fields (${len(form.fields)})</div>
+ %for ctr, field in enumerate(field_details):
+ ${render_field( ctr, field )}
+ %endfor
+ <div class="form-row">
+ <input type="submit" name="add_field_button" value="Add field"/>
+ </div>
+ <div class="form-row">
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="hidden" name="refresh" value="true" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <input type="submit" name="save_changes_button" value="Save"/>
+ </form>
+ </div>
+</div>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/forms/manage_forms.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/forms/manage_forms.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,73 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+<%def name="title()">Manage Form Definitions</%def>
+
+## Render a row
+<%def name="render_row( form, ctr )">
+ %if ctr % 2 == 1:
+ <tr class="odd_row">
+ %else:
+ <tr>
+ %endif
+ <td>
+ <b><a href="${h.url_for( controller='forms', action='edit', form_id=form.id, read_only=True )}">${form.name}</a></b>
+ <a id="form-${form.id}-popup" class="popup-arrow" style="display: none;">▼</a>
+ <div popupmenu="form-${form.id}-popup">
+ <a class="action-button" href="${h.url_for( action='edit', form_id=form.id, show_form=True )}">Edit form definition</a>
+ </div>
+ </td>
+ <td><i>${form.desc}</i></td>
+ </tr>
+</%def>
+
+
+<h2>
+ %if deleted:
+ Deleted
+ %endif
+ Forms
+</h2>
+
+
+
+<ul class="manage-table-actions">
+ %if not deleted:
+ <li>
+ <a class="action-button" href="${h.url_for( controller='forms', action='new', new=True )}">
+ <img src="${h.url_for('/static/images/silk/add.png')}" />
+ <span>Define a new form</span></a>
+ </li>
+ %endif
+</ul>
+
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+%if not fdc_list:
+ %if deleted:
+ There are no deleted forms
+ %else:
+ There are no forms.
+ %endif
+%else:
+ <table class="grid">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ %for ctr, fdc in enumerate( fdc_list ):
+ <tr>
+ ${render_row( fdc.latest_form, ctr )}
+ </tr>
+ %endfor
+ </tbody>
+ </table>
+%endif
diff -r 267db48a2371 -r b46f27137744 templates/admin/forms/show_form_read_only.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/forms/show_form_read_only.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,67 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">${form.name} - <i>${form.desc}</i></div>
+ <form name="library" action="${h.url_for( controller='forms', action='manage' )}" method="post" >
+ <table class = "grid">
+ <tbody>
+ %for index, field in enumerate(form.fields):
+ <tr>
+ <td>
+ <div class="form-row">
+ <label>${1+index}. Label</label>
+ <a>${field['label']}</a>
+ %if field['type'] == 'SelectField':
+ <a id="${field['label']}-popup" class="popup-arrow" style="display: none;">▼</a>
+ %for option in field['selectlist']:
+ <div popupmenu="${field['label']}-type-popup">
+ <a class="action-button" href="" >${option}</a>
+ </div>
+ %endfor
+ %endif
+ </div>
+ </td>
+ <td>
+ <div class="form-row">
+ <label>Help text </label>
+ %if not field['helptext']:
+ <a><i>No helptext</i></a>
+ %else:
+ <a>${field['helptext']}</a>
+ %endif
+ </div>
+ </td>
+ <td>
+ <div class="form-row">
+ <label>Type:</label>
+ <a>${field['type']}</a>
+ %if field['type'] == 'SelectField':
+ <a id="fieldtype-popup" class="popup-arrow" style="display: none;">▼</a>
+ %for option in field['selectlist']:
+ <div popupmenu="type-popup">
+ <a class="action-button" href="" >${option}</a>
+ </div>
+ %endfor
+ %endif
+ </div>
+ </td>
+ <td>
+ <div class="form-row">
+ <label>Required?</label>
+ <a>${field['required']}</a>
+ </div>
+ </td>
+ </tr>
+ %endfor
+ </tbody>
+ </table>
+ ##<input type="submit" name="save_changes_button" value="Back"/>
+ </form>
+ </div>
+</div>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/index.mako
--- a/templates/admin/index.mako Thu Jul 09 15:49:26 2009 -0400
+++ b/templates/admin/index.mako Fri Jul 10 11:37:28 2009 -0400
@@ -103,13 +103,35 @@
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='jobs' )}" target="galaxy_main">Manage jobs</a></div>
</div>
</div>
+ <div class="toolSectionPad"></div>
+ <div class="toolSectionTitle">
+ <span>Forms</span>
+ </div>
+ <div class="toolSectionBody">
+ <div class="toolSectionBg">
+ <div class="toolTitle"><a href="${h.url_for( controller='forms', action='manage' )}" target="galaxy_main">Manage forms</a></div>
+ </div>
+ </div>
+ <div class="toolSectionPad"></div>
+ <div class="toolSectionTitle">
+ <span>Requests</span>
+ </div>
+ <div class="toolSectionBody">
+ <div class="toolSectionBg">
+ <div class="toolTitle"><a href="${h.url_for( controller='admin', action='manage_request_types' )}" target="galaxy_main">Manage request types</a></div>
+ <div class="toolTitle"><a href="${h.url_for( controller='requests_admin', action='list')}" target="galaxy_main">Manage requests</a></div>
+ </div>
+ </div>
</div>
</div>
</div>
+ ##<iframe name="galaxy_admin" src="${h.url_for( controller='admin', action='index' )}" frameborder="0" style="position: absolute; margin: 0; border: 0 none; height: 100%; width: 100%;"> </iframe>
</%def>
<%def name="center_panel()">
-
- <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${h.url_for( action='center' )}"> </iframe>
+ <%
+ center_url = h.url_for( action='center' )
+ %>
+ <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${center_url}"> </iframe>
</%def>
diff -r 267db48a2371 -r b46f27137744 templates/admin/requests/add_states.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/requests/add_states.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,26 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Create ${num_states} states for the '${sample_type_name}' sample type</div>
+ <form name="new_form_fields" action="${h.url_for( controller='admin', action='request_type', save_new=True, create=False, edit=False, name=sample_type_name, description=desc, num_states=num_states, request_form_id=request_form_id, sample_form_id=sample_form_id)}" method="post" >
+ <div class="toolFormBody">
+ %for element_count in range( num_states ):
+ <div class="form-row">
+ <label>${1+element_count}) State name:</label>
+ <input type="text" name="new_element_name_${element_count}" value="" size="40"/>
+ <label>State help text (optional):</label>
+ <input type="text" name="new_element_description_${element_count}" value="" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ %endfor
+ </div>
+ <div class="toolFormBody">
+ <input type="submit" name="save_new_sample_type" value="Save"/>
+ </div>
+ </form>
+</div>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/requests/create_request_type.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/requests/create_request_type.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,66 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Create a new request type</div>
+ %if not forms:
+ Create a form definition first to create a new request type.
+ %else:
+ <div class="toolFormBody">
+ <form name="create_request_type" action="${h.url_for( controller='admin', action='request_type', add_states=True, create=False, edit=False )}" method="post" >
+ <div class="form-row">
+ <label>Name:</label>
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="text" name="name" value="New Request Type" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>Description:</label>
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="text" name="description" value="" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>
+ Request Form definition:
+ </label>
+ <select name="request_form_id">
+ %for form in forms:
+ <option value="${form.id}">${form.name}</option>
+ %endfor
+ </select>
+ </div>
+ <div class="form-row">
+ <label>
+ Sample Form definition:
+ </label>
+ <select name="sample_form_id">
+ %for form in forms:
+ <option value="${form.id}">${form.name}</option>
+ %endfor
+ </select>
+ </div>
+ <div class="form-row">
+ <label>Number of sample states:</label>
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="text" size="3" name="num_states" value="1"/>
+ </div>
+ </div>
+ <div class="form-row">
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="hidden" name="new" value="submitted" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <input type="submit" name="create_library_button" value="Define states"/>
+ </form>
+ </div>
+ %endif
+</div>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/requests/edit_request_type.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/requests/edit_request_type.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,78 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<% num_states=len(states_list) %>
+
+<div class="toolForm">
+ <div class="toolFormTitle">Edit the request type</div>
+ <div class="toolFormBody">
+ <form name="library" action="${h.url_for( controller='admin', action='request_type', save_changes=True, create=False, id=request_type.id, num_states=num_states )}" method="post" >
+ <div class="form-row">
+ <label>Name:</label>
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="text" name="name" value="${request_type.name}" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>Description:</label>
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="text" name="description" value="${request_type.desc}" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>
+ Request Form definition:
+ </label>
+ <select name="form_id">
+ %for form in forms:
+ %if form.id == request_type.request_form_id:
+ <option value="${form.id}" selected>${form.name}</option>
+ %else:
+ <option value="${form.id}">${form.name}</option>
+ %endif
+ %endfor
+ </select>
+ </div>
+ <div class="form-row">
+ <label>
+ Sample Form definition:
+ </label>
+ <select name="form_id">
+ %for form in forms:
+ %if form.id == request_type.sample_form_id:
+ <option value="${form.id}" selected>${form.name}</option>
+ %else:
+ <option value="${form.id}">${form.name}</option>
+ %endif
+ %endfor
+ </select>
+ </div>
+ <div class="toolFormBody">
+ %for element_count, state in enumerate(states_list):
+ <div class="form-row">
+ <label>${1+element_count}) State name:</label>
+ <input type="text" name="new_element_name_${element_count}" value="${state.name}" size="40"/>
+ <label>State help text (optional):</label>
+ <input type="text" name="new_element_description_${element_count}" value="${state.desc}" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ %endfor
+ </div>
+ <div class="form-row">
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="hidden" name="new" value="submitted" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+
+ <input type="submit" name="edit_request_type_button" value="Save"/>
+ </form>
+ </div>
+</div>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/requests/grid.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/requests/grid.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,205 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<%def name="title()">Browse Requests</%def>
+
+%if message:
+ <p>
+ <div class="${message_type}message transient-message">${message}</div>
+ <div style="clear: both"></div>
+ </p>
+%endif
+
+<%def name="javascripts()">
+ ${parent.javascripts()}
+ <script type="text/javascript">
+ ## TODO: generalize and move into galaxy.base.js
+ $(document).ready(function() {
+ $(".grid").each( function() {
+ var grid = this;
+ var checkboxes = $(this).find("input.grid-row-select-checkbox");
+ var update = $(this).find( "span.grid-selected-count" );
+ $(checkboxes).each( function() {
+ $(this).change( function() {
+ var n = $(checkboxes).filter("[checked]").size();
+ update.text( n );
+ });
+ })
+ });
+ });
+ ## Can this be moved into base.mako?
+ %if refresh_frames:
+ %if 'masthead' in refresh_frames:
+ ## Refresh masthead == user changes (backward compatibility)
+ if ( parent.user_changed ) {
+ %if trans.user:
+ parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
+ %else:
+ parent.user_changed( null, false );
+ %endif
+ }
+ %endif
+ %if 'history' in refresh_frames:
+ if ( parent.frames && parent.frames.galaxy_history ) {
+ parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history')}";
+ if ( parent.force_right_panel ) {
+ parent.force_right_panel( 'show' );
+ }
+ }
+ %endif
+ %if 'tools' in refresh_frames:
+ if ( parent.frames && parent.frames.galaxy_tools ) {
+ parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}";
+ if ( parent.force_left_panel ) {
+ parent.force_left_panel( 'show' );
+ }
+ }
+ %endif
+ %endif
+ </script>
+</%def>
+
+<%def name="stylesheets()">
+ <link href="${h.url_for('/static/style/base.css')}" rel="stylesheet" type="text/css" />
+ <style>
+ ## Not generic to all grids -- move to base?
+ .count-box {
+ min-width: 1.1em;
+ padding: 5px;
+ border-width: 1px;
+ border-style: solid;
+ text-align: center;
+ display: inline-block;
+ }
+ </style>
+</%def>
+
+<div class="grid-header">
+ <h2>${grid.title}</h2>
+ %if len(query.all()):
+ <h3>All Users</h3>
+ %endif
+## %if len(query.all()):
+## <span class="title">Filter:</span>
+## %for i, filter in enumerate( grid.standard_filters ):
+## %if i > 0:
+## <span>|</span>
+## %endif
+## <span class="filter"><a href="${url( filter.get_url_args() )}">${filter.label}</a></span>
+## %endfor
+## %endif
+</div>
+
+
+%if not len(query.all()):
+ There are no request(s).
+%else:
+<form name="history_actions" action="${url()}" method="post" >
+ <table class="grid">
+ <thead>
+ <tr>
+ <th></th>
+ %for column in grid.columns:
+ %if column.visible:
+ <%
+ href = ""
+ extra = ""
+ if column.sortable:
+ if sort_key == column.key:
+ if sort_order == "asc":
+ href = url( sort=( "-" + column.key ) )
+ extra = "↓"
+ else:
+ href = url( sort=( column.key ) )
+ extra = "↑"
+ else:
+ href = url( sort=column.key )
+ %>
+ <th\
+ %if column.ncells > 1:
+ colspan="${column.ncells}"
+ %endif
+ >
+ %if href:
+ <a href="${href}">${column.label}</a>
+ %else:
+ ${column.label}
+ %endif
+ <span>${extra}</span>
+ </th>
+ %endif
+ %endfor
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ %for i, item in enumerate( query ):
+ <tr \
+ %if current_item == item:
+ class="current" \
+ %endif
+ >
+ ## Item selection column
+ <td style="width: 1.5em;">
+ <input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" />
+ </td>
+ ## Data columns
+ %for column in grid.columns:
+ %if column.visible:
+ <%
+ # Link
+ if column.link and column.link( item ):
+ href = url( **column.link( item ) )
+ else:
+ href = None
+ # Value (coerced to list so we can loop)
+ value = column.get_value( trans, grid, item )
+ if column.ncells == 1:
+ value = [ value ]
+ %>
+ %for cellnum, v in enumerate( value ):
+ <%
+ # Attach popup menu?
+ if column.attach_popup and cellnum == 0:
+ extra = '<a id="grid-%d-popup" class="popup-arrow" style="display: none;">▼</a>' % i
+ else:
+ extra = ""
+ %>
+ %if href:
+ <td><a href="${href}">${v}</a> ${extra}</td>
+ %else:
+ <td >${v}${extra}</td>
+ %endif
+ </td>
+ %endfor
+ %endif
+ %endfor
+ ## Actions column
+ <td>
+ <div popupmenu="grid-${i}-popup">
+ %for operation in grid.operations:
+ %if operation.allowed( item ):
+ <a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a>
+ %endif
+ %endfor
+ </div>
+ </td>
+ </tr>
+ %endfor
+ </tbody>
+## <tfoot>
+## <tr>
+## <td></td>
+## <td colspan="100">
+## For <span class="grid-selected-count"></span> selected requests:
+## %for operation in grid.operations:
+## %if operation.allow_multiple:
+## <input type="submit" name="operation" value="${operation.label}" class="action-button">
+## %endif
+## %endfor
+## </td>
+## </tr>
+## </tfoot>
+ </table>
+</form>
+%endif
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/requests/manage_request_types.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/requests/manage_request_types.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,60 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<%def name="title()">request Types</%def>
+
+<h2>
+ %if deleted:
+ Deleted
+ %endif
+ Request Types
+</h2>
+
+<ul class="manage-table-actions">
+ <li>
+ <a class="action-button" href="${h.url_for( controller='admin', action='request_type', create=True )}"><span>Create a new request type</span></a>
+ </li>
+</ul>
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+%if not request_types:
+ %if deleted:
+ There are no deleted request types
+ %else:
+ There are no request types.
+ %endif
+%else:
+ <table class="grid">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ <th>Request Form</th>
+ <th>Sample Form</th>
+ </tr>
+ </thead>
+ <tbody>
+ %for request_type in request_types:
+ <tr>
+ <td><b><a href="${h.url_for( controller='admin', action='request_type', edit='True', id=request_type.id)}">${request_type.name}</a></b></td>
+ <td><i>${request_type.desc}</i></td>
+ <% for form in forms:
+ if form.id == request_type.request_form_id:
+ form_name = form.name
+ break
+ %>
+ <td><a href="${h.url_for( controller='forms', action='edit', form_id=request_type.request_form_id, read_only=True)}">${form_name}</a></td>
+ <% for form in forms:
+ if form.id == request_type.sample_form_id:
+ form_name = form.name
+ break
+ %>
+ <td><a href="${h.url_for( controller='forms', action='edit', form_id=request_type.sample_form_id, read_only=True)}">${form_name}</a></td>
+ </tr>
+ %endfor
+ </tbody>
+ </table>
+%endif
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/requests/view_request.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/requests/view_request.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,20 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Request Details: '${request_details[0]['value']}'</div>
+ %for index, rd in enumerate(request_details):
+ <div class="form-row">
+ <label>${rd['label']}</label>
+ ##<i>${rd['helptext']}</i>
+ ${rd['value']}
+ </div>
+ <div style="clear: both"></div>
+ %endfor
+ </div>
+</div>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/samples/change_state.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/samples/change_state.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,30 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+<div class="toolForm">
+ <div class="toolFormTitle">${title}</div>
+ <div class="toolFormBody">
+ <form name="event" action="${h.url_for( controller='requests_admin', action='save_state', new=True, sample_id_list=sample_id_list)}" method="post" >
+ %for w in widgets:
+ <div class="form-row">
+ <label>
+ ${w[0]}
+ </label>
+ ${w[1].get_html()}
+ %if w[0] == 'Comments':
+ <div class="toolParamHelp" style="clear: both;">
+ Optional
+ </div>
+ %endif
+ </div>
+ %endfor
+ <div class="form-row">
+ <input type="submit" name="add_event" value="Save"/>
+ </div>
+ </form>
+ </div>
+</div>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/samples/edit_sample.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/samples/edit_sample.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,83 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Edit sample named: ${values.content['Name']}</div>
+ <div class="toolFormBody">
+ <form name="sample" action="${h.url_for( controller='sample', action='do', save_changes=True, sample_id=sample.id )}" method="post" >
+ <div class="form-row">
+ <label>
+ Library:
+ </label>
+ <select name="library_id">
+ %for library in libraries:
+ <option value="${library.id}">${library.name}</option>
+ %endfor
+ </select>
+ </div>
+ %for i, field in enumerate(form.fields):
+ <div class="form-row">
+ <label>${field['label']}</label>
+ %if field['type'] == 'TextField':
+ <input type="text" name="${field['label']}" value="${values.content[field['label']]}" size="40"/>
+ %elif field['type'] == 'TextArea':
+ <textarea name="${field['label']}" rows="3" cols="35">${values.content[field['label']]}</textarea>
+ %elif field['type'] == 'CheckBox':
+ %if values.content[field['label']] == "true":
+ <input type="checkbox" name="${field['label']}" value="true" checked>
+ %else:
+ <input type="checkbox" name="${field['label']}" value="true">
+ %endif
+ %elif field['type'] == 'SelectBox':
+ <select name="${field['label']}">
+ %for ft in field['selectlist']:
+ %if ft == values.content[field['label']]:
+ <option value="${ft}" selected>${ft}</option>
+ %else:
+ <option value="${ft}">${ft}</option>
+ %endif
+ %endfor
+ </select>
+ %endif
+ <div class="toolParamHelp" style="clear: both;">
+ ${field['helptext']}
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ %endfor
+ <div class="form-row">
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="hidden" name="new" value="submitted" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <input type="submit" name="create_library_button" value="Save"/>
+ </div>
+ </form>
+ </div>
+</div>
+<div class="toolForm">
+ <div class="toolFormBody">
+ <form name="event" action="${h.url_for( controller='admin', action='event', new=True, sample_id=sample.id)}" method="post" >
+ <div class="form-row">
+ <label>
+ Change sample state to:
+ </label>
+ <select name="state_id">
+ %for state in states:
+ <option value="${state.id}">${state.name}</option>
+ %endfor
+ </select>
+ </div>
+ <div class="form-row">
+ <input type="submit" name="add_event" value="Save"/>
+ </div>
+ </form>
+ </div>
+</div>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/samples/events.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/samples/events.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,33 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<%def name="title()">Events for Sample ${sample_name}</%def>
+
+<h2>Events for Sample "${sample_name}" of Request: ${request}</h2>
+<h3>User: ${user.email}</h3>
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+
+<table class="grid">
+ <thead>
+ <tr>
+ <th>State</th>
+ <th>Description</th>
+ <th>Last Update</th>
+ <th>Comments</th>
+ </tr>
+ </thead>
+ <tbody>
+ %for state, desc, updated, comments in events_list:
+ <tr class="libraryRow libraryOrFolderRow" id="libraryRow">
+ <td><b><a>${state}</a></b></td>
+ <td><a>${desc}</a></td>
+ <td><a>${updated}</a></td>
+ <td><a>${comments}</a></td>
+ </tr>
+ %endfor
+ </tbody>
+</table>
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/admin/samples/grid.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/samples/grid.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,203 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<%def name="title()">Browse Samples</%def>
+
+%if message:
+ <p>
+ <div class="${message_type}message transient-message">${message}</div>
+ <div style="clear: both"></div>
+ </p>
+%endif
+
+<%def name="javascripts()">
+ ${parent.javascripts()}
+ <script type="text/javascript">
+ ## TODO: generalize and move into galaxy.base.js
+ $(document).ready(function() {
+ $(".grid").each( function() {
+ var grid = this;
+ var checkboxes = $(this).find("input.grid-row-select-checkbox");
+ var update = $(this).find( "span.grid-selected-count" );
+ $(checkboxes).each( function() {
+ $(this).change( function() {
+ var n = $(checkboxes).filter("[checked]").size();
+ update.text( n );
+ });
+ })
+ });
+ });
+ ## Can this be moved into base.mako?
+ %if refresh_frames:
+ %if 'masthead' in refresh_frames:
+ ## Refresh masthead == user changes (backward compatibility)
+ if ( parent.user_changed ) {
+ %if trans.user:
+ parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
+ %else:
+ parent.user_changed( null, false );
+ %endif
+ }
+ %endif
+ %if 'history' in refresh_frames:
+ if ( parent.frames && parent.frames.galaxy_history ) {
+ parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history')}";
+ if ( parent.force_right_panel ) {
+ parent.force_right_panel( 'show' );
+ }
+ }
+ %endif
+ %if 'tools' in refresh_frames:
+ if ( parent.frames && parent.frames.galaxy_tools ) {
+ parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}";
+ if ( parent.force_left_panel ) {
+ parent.force_left_panel( 'show' );
+ }
+ }
+ %endif
+ %endif
+ </script>
+</%def>
+
+<%def name="stylesheets()">
+ <link href="${h.url_for('/static/style/base.css')}" rel="stylesheet" type="text/css" />
+ <style>
+ ## Not generic to all grids -- move to base?
+ .count-box {
+ min-width: 1.1em;
+ padding: 5px;
+ border-width: 1px;
+ border-style: solid;
+ text-align: center;
+ display: inline-block;
+ }
+ </style>
+</%def>
+
+<div class="grid-header">
+ <h2>Samples associated with request: ${grid.request.name}</h2>
+ <h3>User: ${grid.user.email}</h3>
+## %if len(query.all()):
+## <span class="title">Filter:</span>
+## %for i, filter in enumerate( grid.standard_filters ):
+## %if i > 0:
+## <span>|</span>
+## %endif
+## <span class="filter"><a href="${url( filter.get_url_args() )}">${filter.label}</a></span>
+## %endfor
+## %endif
+</div>
+
+%if not len(query.all()):
+ There are no sample(s).
+%else:
+<form name="history_actions" action="${url()}" method="post" >
+ <table class="grid">
+ <thead>
+ <tr>
+ <th></th>
+ %for column in grid.columns:
+ %if column.visible:
+ <%
+ href = ""
+ extra = ""
+ if column.sortable:
+ if sort_key == column.key:
+ if sort_order == "asc":
+ href = url( sort=( "-" + column.key ) )
+ extra = "↓"
+ else:
+ href = url( sort=( column.key ) )
+ extra = "↑"
+ else:
+ href = url( sort=column.key )
+ %>
+ <th\
+ %if column.ncells > 1:
+ colspan="${column.ncells}"
+ %endif
+ >
+ %if href:
+ <a href="${href}">${column.label}</a>
+ %else:
+ ${column.label}
+ %endif
+ <span>${extra}</span>
+ </th>
+ %endif
+ %endfor
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ %for i, item in enumerate( query ):
+ <tr \
+ %if current_item == item:
+ class="current" \
+ %endif
+ >
+ ## Item selection column
+ <td style="width: 1.5em;">
+ <input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" />
+ </td>
+ ## Data columns
+ %for column in grid.columns:
+ %if column.visible:
+ <%
+ # Link
+ if column.link and column.link( item ):
+ href = url( **column.link( item ) )
+ else:
+ href = None
+ # Value (coerced to list so we can loop)
+ value = column.get_value( trans, grid, item )
+ if column.ncells == 1:
+ value = [ value ]
+ %>
+ %for cellnum, v in enumerate( value ):
+ <%
+ # Attach popup menu?
+ if column.attach_popup and cellnum == 0:
+ extra = '<a id="grid-%d-popup" class="popup-arrow" style="display: none;">▼</a>' % i
+ else:
+ extra = ""
+ %>
+ %if href:
+ <td><a href="${href}">${v}</a> ${extra}</td>
+ %else:
+ <td >${v}${extra}</td>
+ %endif
+ </td>
+ %endfor
+ %endif
+ %endfor
+ ## Actions column
+ <td>
+ <div popupmenu="grid-${i}-popup">
+ %for operation in grid.operations:
+ %if operation.allowed( item ):
+ <a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a>
+ %endif
+ %endfor
+ </div>
+ </td>
+ </tr>
+ %endfor
+ </tbody>
+ <tfoot>
+ <tr>
+ <td></td>
+ <td colspan="100">
+ For <span class="grid-selected-count"></span> selected requests:
+ %for operation in grid.operations:
+ %if operation.allow_multiple:
+ <input type="submit" name="operation" value="${operation.label}" class="action-button">
+ %endif
+ %endfor
+ </td>
+ </tr>
+ </tfoot>
+ </table>
+</form>
+
+%endif
diff -r 267db48a2371 -r b46f27137744 templates/admin/samples/view_sample.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/samples/view_sample.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,19 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Sample Details: '${sample_details[0]['value']}'</div>
+ %for index, rd in enumerate(sample_details):
+ <div class="form-row">
+ <label>${rd['label']}</label>
+ ${rd['value']}
+ </div>
+ <div style="clear: both"></div>
+ %endfor
+ </div>
+</div>
diff -r 267db48a2371 -r b46f27137744 templates/base.mako
--- a/templates/base.mako Thu Jul 09 15:49:26 2009 -0400
+++ b/templates/base.mako Fri Jul 10 11:37:28 2009 -0400
@@ -29,4 +29,33 @@
## <![endif]-->
<script type="text/javascript" src="${h.url_for('/static/scripts/jquery.js')}"></script>
<script type="text/javascript" src="${h.url_for('/static/scripts/galaxy.base.js')}"></script>
+
+
</%def>
+
+<script type="text/javascript">
+$( function() {
+ $( "select[refresh_on_change='true']").change( function() {
+ var refresh = false;
+ var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' )
+ if ( refresh_on_change_values ) {
+ refresh_on_change_values = refresh_on_change_values.value.split( ',' );
+ var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' );
+ for( i= 0; i < refresh_on_change_values.length; i++ ) {
+ if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){
+ refresh = true;
+ break;
+ }
+ }
+ }
+ else {
+ refresh = true;
+ }
+ if ( refresh ){
+ $( ':file' ).each( function() {
+ var file_value = $( this )[0].value;
+ } );
+ $( "#edit_form" ).submit();
+ }
+ });
+});
\ No newline at end of file
diff -r 267db48a2371 -r b46f27137744 templates/base_panels.mako
--- a/templates/base_panels.mako Thu Jul 09 15:49:26 2009 -0400
+++ b/templates/base_panels.mako Fri Jul 10 11:37:28 2009 -0400
@@ -153,6 +153,8 @@
${tab( "workflow", "Workflow", h.url_for( controller='workflow', action='index' ))}
${tab( "libraries", "Libraries", h.url_for( controller='library', action='index' ))}
+
+ ${tab( "requests", "Requests", h.url_for( controller='requests', action='index' ), visible = (trans.user and trans.request_types)) }
%if app.config.get_bool( 'enable_tracks', False ):
<span class="tab">
diff -r 267db48a2371 -r b46f27137744 templates/requests/grid.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/requests/grid.mako Fri Jul 10 11:37:28 2009 -0400
@@ -0,0 +1,210 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<%def name="title()">Browse Samples</%def>
+
+%if message:
+ <p>
+ <div class="${message_type}message transient-message">${message}</div>
+ <div style="clear: both"></div>
+ </p>
+%endif
+
+<%def name="javascripts()">
+ ${parent.javascripts()}
+ <script type="text/javascript">
+ ## TODO: generalize and move into galaxy.base.js
+ $(document).ready(function() {
+ $(".grid").each( function() {
+ var grid = this;
+ var checkboxes = $(this).find("input.grid-row-select-checkbox");
+ var update = $(this).find( "span.grid-selected-count" );
+ $(checkboxes).each( function() {
+ $(this).change( function() {
+ var n = $(checkboxes).filter("[checked]").size();
+ update.text( n );
+ });
+ })
+ });
+ });
+ ## Can this be moved into base.mako?
+ %if refresh_frames:
+ %if 'masthead' in refresh_frames:
+ ## Refresh masthead == user changes (backward compatibility)
+ if ( parent.user_changed ) {
+ %if trans.user:
+ parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
+ %else:
+ parent.user_changed( null, false );
+ %endif
+ }
+ %endif
+ %if 'history' in refresh_frames:
+ if ( parent.frames && parent.frames.galaxy_history ) {
+ parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history')}";
+ if ( parent.force_right_panel ) {
+ parent.force_right_panel( 'show' );
+ }
+ }
+ %endif
+ %if 'tools' in refresh_frames:
+ if ( parent.frames && parent.frames.galaxy_tools ) {
+ parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}";
+ if ( parent.force_left_panel ) {
+ parent.force_left_panel( 'show' );
+ }
+ }
+ %endif
+ %endif
+ </script>
+</%def>
+
+<%def name="stylesheets()">
1
0
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/615a0bcf870b
changeset: 2474:615a0bcf870b
user: rc
date: Fri Jul 10 15:24:01 2009 -0400
description:
Fixed another bug in saving special characters in forms
1 file(s) affected in this change:
lib/galaxy/web/controllers/forms.py
diffs (25 lines):
diff -r f7bdfd409b7d -r 615a0bcf870b lib/galaxy/web/controllers/forms.py
--- a/lib/galaxy/web/controllers/forms.py Fri Jul 10 14:50:17 2009 -0400
+++ b/lib/galaxy/web/controllers/forms.py Fri Jul 10 15:24:01 2009 -0400
@@ -152,7 +152,7 @@
def __get_field(self, params, index):
name = util.restore_text( params.get( 'field_name_%i' % index, None ) )
helptext = util.restore_text( params.get( 'field_helptext_%i' % index, None ) )
- required = util.restore_text( params.get( 'field_required_%i' % index, False ) )
+ required = params.get( 'field_required_%i' % index, False )
field_type = util.restore_text( params.get( 'field_type_%i' % index, None ) )
if field_type == 'SelectField':
selectlist = self.__get_selectbox_options(params, index)
@@ -172,10 +172,10 @@
ctr=0
sb_options = []
while True:
- option = util.restore_text( params.get( 'field_'+str(index)+'_option_'+str(ctr), None ) )
+ option = params.get( 'field_'+str(index)+'_option_'+str(ctr), None )
ctr = ctr+1
if option:
- sb_options.append(option)
+ sb_options.append(util.restore_text(option))
else:
return sb_options
def __get_saved_form(self, fd):
1
0
15 Jul '09
details: http://www.bx.psu.edu/hg/galaxy/rev/267db48a2371
changeset: 2470:267db48a2371
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Thu Jul 09 15:49:26 2009 -0400
description:
Some history sharing cleanup and a fix for job error reports.
5 file(s) affected in this change:
lib/galaxy/web/controllers/dataset.py
lib/galaxy/web/controllers/history.py
templates/history/list_shared.mako
templates/history/share.mako
test/functional/test_history_functions.py
diffs (364 lines):
diff -r 073c9a0b2467 -r 267db48a2371 lib/galaxy/web/controllers/dataset.py
--- a/lib/galaxy/web/controllers/dataset.py Wed Jul 08 17:01:49 2009 -0400
+++ b/lib/galaxy/web/controllers/dataset.py Thu Jul 09 15:49:26 2009 -0400
@@ -17,7 +17,7 @@
------------------------
This error report was sent from the Galaxy instance hosted on the server
-"${remote_hostname}"
+"${host}"
-----------------------------------------------------------------------------
This is in reference to output dataset ${dataset_id}.
-----------------------------------------------------------------------------
@@ -65,10 +65,10 @@
dataset = model.HistoryDatasetAssociation.get( id )
job = dataset.creating_job_associations[0].job
# Get the name of the server hosting the Galaxy instance from which this report originated
- remote_hostname = trans.request.remote_hostname
+ host = trans.request.host
# Build the email message
msg = MIMEText( string.Template( error_report_template )
- .safe_substitute( remote_hostname=remote_hostname,
+ .safe_substitute( host=host,
dataset_id=dataset.id,
email=email,
message=message,
diff -r 073c9a0b2467 -r 267db48a2371 lib/galaxy/web/controllers/history.py
--- a/lib/galaxy/web/controllers/history.py Wed Jul 08 17:01:49 2009 -0400
+++ b/lib/galaxy/web/controllers/history.py Thu Jul 09 15:49:26 2009 -0400
@@ -310,8 +310,9 @@
email=email,
send_to_err=send_to_err )
if params.get( 'share_button', False ):
- can_change, cannot_change, no_change_needed, send_to_err = \
- self._populate_restricted( trans, user, histories, send_to_users, None, send_to_err )
+ # The user has not yet made a choice about how to share, so dictionaries will be built for display
+ can_change, cannot_change, no_change_needed, unique_no_change_needed, send_to_err = \
+ self._populate_restricted( trans, user, histories, send_to_users, None, send_to_err, unique=True )
if can_change or cannot_change:
return trans.fill_template( "/history/share.mako",
histories=histories,
@@ -319,7 +320,7 @@
send_to_err=send_to_err,
can_change=can_change,
cannot_change=cannot_change,
- no_change_needed=no_change_needed )
+ no_change_needed=unique_no_change_needed )
if no_change_needed:
return self._share_histories( trans, user, send_to_err, histories=no_change_needed )
elif not send_to_err:
@@ -335,7 +336,8 @@
user = trans.get_user()
histories, send_to_users, send_to_err = self._get_histories_and_users( trans, user, id, email )
send_to_err = ''
- can_change, cannot_change, no_change_needed, send_to_err = \
+ # The user has made a choice, so dictionaries will be built for sharing
+ can_change, cannot_change, no_change_needed, unique_no_change_needed, send_to_err = \
self._populate_restricted( trans, user, histories, send_to_users, action, send_to_err )
# Now that we've populated the can_change, cannot_change, and no_change_needed dictionaries,
# we'll populate the histories_for_sharing dictionary from each of them.
@@ -408,13 +410,13 @@
send_to_err += "%s is not a valid Galaxy user. " % email_address
return histories, send_to_users, send_to_err
def _populate( self, trans, histories_for_sharing, other, send_to_err ):
- # this method will populate the histories_for_sharing dictionary with the users and
+ # This method will populate the histories_for_sharing dictionary with the users and
# histories in other, eliminating histories that have already been shared with the
# associated user. No security checking on datasets is performed.
# If not empty, the histories_for_sharing dictionary looks like:
# { userA: [ historyX, historyY ], userB: [ historyY ] }
# other looks like:
- # ## { userA: {historyX : [hda, hda], historyY : [hda]}, userB: {historyY : [hda]} }
+ # { userA: {historyX : [hda, hda], historyY : [hda]}, userB: {historyY : [hda]} }
for send_to_user, history_dict in other.items():
for history in history_dict:
# Make sure the current history has not already been shared with the current send_to_user
@@ -430,20 +432,22 @@
elif history not in histories_for_sharing[ send_to_user ]:
histories_for_sharing[ send_to_user ].append( history )
return histories_for_sharing, send_to_err
- def _populate_restricted( self, trans, user, histories, send_to_users, action, send_to_err ):
+ def _populate_restricted( self, trans, user, histories, send_to_users, action, send_to_err, unique=False ):
# The user may be attempting to share histories whose datasets cannot all be accessed by other users.
# If this is the case, the user sharing the histories can:
# 1) action=='public': choose to make the datasets public if he is permitted to do so
# 2) action=='private': automatically create a new "sharing role" allowing protected
# datasets to be accessed only by the desired users
- # 3) action=='share_anyway': share only what can be shared when no permissions are changed
- # 4) action=='no_share': Do not share anything
- # In addition, the user may be sharing a history with a user with which the history was already shared
- # and it will not be shared twice.
- # This method will populate the can_change, cannot_change and no_change_needed dictionaries.
+ # This method will populate the can_change, cannot_change and no_change_needed dictionaries, which
+ # are used for either displaying to the user, letting them make 1 of the choices above, or sharing
+ # after the user has made a choice. They will be used for display if 'unique' is True, and will look
+ # like: {historyX : [hda, hda], historyY : [hda] }
+ # For sharing, they will look like:
+ # { userA: {historyX : [hda, hda], historyY : [hda]}, userB: {historyY : [hda]} }
can_change = {}
cannot_change = {}
no_change_needed = {}
+ unique_no_change_needed = {}
for history in histories:
for send_to_user in send_to_users:
# Make sure the current history has not already been shared with the current send_to_user
@@ -456,7 +460,15 @@
# Only deal with datasets that have not been purged
for hda in history.activatable_datasets:
if trans.app.security_agent.dataset_is_public( hda.dataset ):
- # Build the dict that will show the user what doesn't need to be changed
+ # The no_change_needed dictionary is a special case. If both of can_change
+ # and cannot_change are empty, no_change_needed will used for sharing. Otherwise
+ # unique_no_change_needed will be used for displaying, so we need to populate both.
+ # Build the dictionaries for display, containing unique histories only
+ if history not in unique_no_change_needed:
+ unique_no_change_needed[ history ] = [ hda ]
+ else:
+ unique_no_change_needed[ history ].append( hda )
+ # Build the dictionaries for sharing
if send_to_user not in no_change_needed:
no_change_needed[ send_to_user ] = {}
if history not in no_change_needed[ send_to_user ]:
@@ -473,28 +485,40 @@
# The current user has authority to change permissions on the current dataset because
# they have permission to manage permissions on the dataset and the dataset is not associated
# with a library.
- if send_to_user not in can_change:
- # Build the set of histories / datasets on which the current user has authority
- # to "manage permissions".
- can_change[ send_to_user ] = {}
- if history not in can_change[ send_to_user ]:
- can_change[ send_to_user ][ history ] = [ hda ]
+ if unique:
+ # Build the dictionaries for display, containing unique histories only
+ if history not in can_change:
+ can_change[ history ] = [ hda ]
+ else:
+ can_change[ history ].append( hda )
else:
- can_change[ send_to_user ][ history ].append( hda )
+ # Build the dictionaries for sharing
+ if send_to_user not in can_change:
+ can_change[ send_to_user ] = {}
+ if history not in can_change[ send_to_user ]:
+ can_change[ send_to_user ][ history ] = [ hda ]
+ else:
+ can_change[ send_to_user ][ history ].append( hda )
else:
if action in [ "private", "public" ]:
- # Don't change stuff that the user doesn't have permission to change
+ # The user has made a choice, so 'unique' doesn't apply. Don't change stuff
+ # that the user doesn't have permission to change
continue
- #elif send_to_user not in cannot_change:
- if send_to_user not in cannot_change:
- # Build the set of histories / datasets on which the current user does
- # not have authority to "manage permissions".
- cannot_change[ send_to_user ] = {}
- if history not in cannot_change[ send_to_user ]:
- cannot_change[ send_to_user ][ history ] = [ hda ]
+ if unique:
+ # Build the dictionaries for display, containing unique histories only
+ if history not in cannot_change:
+ cannot_change[ history ] = [ hda ]
+ else:
+ cannot_change[ history ].append( hda )
else:
- cannot_change[ send_to_user ][ history ].append( hda )
- return can_change, cannot_change, no_change_needed, send_to_err
+ # Build the dictionaries for sharing
+ if send_to_user not in cannot_change:
+ cannot_change[ send_to_user ] = {}
+ if history not in cannot_change[ send_to_user ]:
+ cannot_change[ send_to_user ][ history ] = [ hda ]
+ else:
+ cannot_change[ send_to_user ][ history ].append( hda )
+ return can_change, cannot_change, no_change_needed, unique_no_change_needed, send_to_err
def _share_histories( self, trans, user, send_to_err, histories={} ):
# histories looks like: { userA: [ historyX, historyY ], userB: [ historyY ] }
msg = ""
@@ -605,6 +629,7 @@
if clone_choice == 'activatable':
new_history = history.copy( name=name, target_user=user, activatable=True )
elif clone_choice == 'active':
+ name += " (active items only)"
new_history = history.copy( name=name, target_user=user )
# Render the list view
return trans.show_ok_message( 'Clone with name "%s" is now included in your list of stored histories.' % new_history.name )
diff -r 073c9a0b2467 -r 267db48a2371 templates/history/list_shared.mako
--- a/templates/history/list_shared.mako Wed Jul 08 17:01:49 2009 -0400
+++ b/templates/history/list_shared.mako Thu Jul 09 15:49:26 2009 -0400
@@ -18,7 +18,7 @@
${history.name}
<a id="shared-${i}-popup" class="popup-arrow" style="display: none;">▼</a>
<div popupmenu="shared-${i}-popup">
- <a class="action-button" href="${h.url_for( controller='history', action='clone', id=trans.security.encode_id( history.id ), clone_choice='activatable' )}">Clone</a>
+ <a class="action-button" href="${h.url_for( controller='history', action='clone', id=trans.security.encode_id( history.id ) )}">Clone</a>
</div>
</td>
<td>${history.user.email}</td>
diff -r 073c9a0b2467 -r 267db48a2371 templates/history/share.mako
--- a/templates/history/share.mako Wed Jul 08 17:01:49 2009 -0400
+++ b/templates/history/share.mako Thu Jul 09 15:49:26 2009 -0400
@@ -64,35 +64,14 @@
<input type="hidden" name="id" value="${trans.security.encode_id( history.id )}">
%endfor
%if no_change_needed:
+ ## no_change_needed looks like: {historyX : [hda, hda], historyY : [hda] }
<div style="clear: both"></div>
<div class="form-row">
<div class="donemessage">
The following datasets can be shared with ${email} with no changes
</div>
- </div>
- ## no_change_needed looks like:
- ## { userA: {historyX : [hda, hda], historyY : [hda]}, userB: {historyY : [hda]} }
- <%
- # TODO: move generation of these unique dictionaries to the history controller
- # Build the list of unique histories and datasets
- unique_stuff = {}
- %>
- %for user, history_dict in no_change_needed.items():
- %for history, hdas in history_dict.items():
- <%
- if history in unique_stuff:
- for hda in hdas:
- if hda not in unique_stuff[ history ]:
- unique_stuff[ history ].append( hda )
- else:
- unique_stuff[ history ] = []
- for hda in hdas:
- if hda not in unique_stuff[ history ]:
- unique_stuff[ history ].append( hda )
- %>
- %endfor
- %endfor
- %for history, hdas in unique_stuff.items():
+ </div>
+ %for history, hdas in no_change_needed.items():
<div class="form-row">
<label>History</label>
${history.name}
@@ -104,40 +83,22 @@
%for hda in hdas:
<div class="form-row">
${hda.name}
+ %if hda.deleted:
+ (deleted)
+ %endif
</div>
%endfor
%endfor
%endif
%if can_change:
+ ## can_change looks like: {historyX : [hda, hda], historyY : [hda] }
<div style="clear: both"></div>
<div class="form-row">
<div class="warningmessage">
The following datasets can be shared with ${email} by updating their permissions
</div>
</div>
- ## can_change looks like:
- ## { userA: {historyX : [hda, hda], historyY : [hda]}, userB: {historyY : [hda]} }
- <%
- # TODO: move generation of these unique dictionaries to the history controller
- # Build the list of unique histories and datasets
- unique_stuff = {}
- %>
- %for user, history_dict in can_change.items():
- %for history, hdas in history_dict.items():
- <%
- if history in unique_stuff:
- for hda in hdas:
- if hda not in unique_stuff[ history ]:
- unique_stuff[ history ].append( hda )
- else:
- unique_stuff[ history ] = []
- for hda in hdas:
- if hda not in unique_stuff[ history ]:
- unique_stuff[ history ].append( hda )
- %>
- %endfor
- %endfor
- %for history, hdas in unique_stuff.items():
+ %for history, hdas in can_change.items():
<div class="form-row">
<label>History</label>
${history.name}
@@ -149,11 +110,15 @@
%for hda in hdas:
<div class="form-row">
${hda.name}
+ %if hda.deleted:
+ (deleted)
+ %endif
</div>
%endfor
%endfor
%endif
%if cannot_change:
+ ## cannot_change looks like: {historyX : [hda, hda], historyY : [hda] }
<div style="clear: both"></div>
<div class="form-row">
<div class="errormessage">
@@ -161,29 +126,7 @@
change the permissions on them
</div>
</div>
- ## cannot_change looks like:
- ## { userA: {historyX : [hda, hda], historyY : [hda]}, userB: {historyY : [hda]} }
- <%
- # TODO: move generation of these unique dictionaries to the history controller
- # Build the list of unique histories and datasets
- unique_stuff = {}
- %>
- %for user, history_dict in can_change.items():
- %for history, hdas in history_dict.items():
- <%
- if history in unique_stuff:
- for hda in hdas:
- if hda not in unique_stuff[ history ]:
- unique_stuff[ history ].append( hda )
- else:
- unique_stuff[ history ] = []
- for hda in hdas:
- if hda not in unique_stuff[ history ]:
- unique_stuff[ history ].append( hda )
- %>
- %endfor
- %endfor
- %for history, hdas in unique_stuff.items():
+ %for history, hdas in cannot_change.items():
<div class="form-row">
<label>History</label>
${history.name}
@@ -195,10 +138,17 @@
%for hda in hdas:
<div class="form-row">
${hda.name}
+ %if hda.deleted:
+ (deleted)
+ %endif
</div>
%endfor
%endfor
%endif
+ <div class="toolFormTitle"></div>
+ <div class="form-row">
+ Deleted items can be eliminated by the users with which you are sharing the history.
+ </div>
<div class="form-row">
<label>How would you like to proceed?</label>
</div>
diff -r 073c9a0b2467 -r 267db48a2371 test/functional/test_history_functions.py
--- a/test/functional/test_history_functions.py Wed Jul 08 17:01:49 2009 -0400
+++ b/test/functional/test_history_functions.py Thu Jul 09 15:49:26 2009 -0400
@@ -253,7 +253,7 @@
# Check list of histories to make sure shared history3 was cloned
self.view_stored_active_histories( check_str="Clone of '%s'" % history3.name )
# Switch to the cloned history to make sure activatable datasets were cloned
- self.switch_history( id=self.security.encode_id( history3_clone3.id ), name=history3_clone3.name )
+ self.switch_history( id=self.security.encode_id( history3_clone3.id ) )
# Make sure the deleted datasets are NOT included in the cloned history
try:
self.check_history_for_string( 'This dataset has been deleted.', show_deleted=True )
1
0