galaxy-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 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
- 15302 discussions
galaxy-dist commit 6838e10e5912: Fix for TextToolParameter.get_html_field when provided value is an empty string but default value specified in tool is non-empty string. Fixes issue with rerun button where if a user had input an empty string, the form displayed when rerun would have the default value from the tool and not the actual previously specified value.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Daniel Blankenberg <dan(a)bx.psu.edu>
# Date 1288818754 14400
# Node ID 6838e10e5912cec46060bda189841edba305ac1d
# Parent 16bd91a548887fb0be24b981c2d66fb7ef7b1922
Fix for TextToolParameter.get_html_field when provided value is an empty string but default value specified in tool is non-empty string. Fixes issue with rerun button where if a user had input an empty string, the form displayed when rerun would have the default value from the tool and not the actual previously specified value.
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -165,10 +165,11 @@ class TextToolParameter( ToolParameter )
self.value = elem.get( 'value' )
self.area = string_as_bool( elem.get( 'area', False ) )
def get_html_field( self, trans=None, value=None, other_values={} ):
+ if value is None: value = self.value
if self.area:
- return form_builder.TextArea( self.name, self.size, value or self.value )
+ return form_builder.TextArea( self.name, self.size, value )
else:
- return form_builder.TextField( self.name, self.size, value or self.value )
+ return form_builder.TextField( self.name, self.size, value )
def get_initial_value( self, trans, context ):
return self.value
1
0
galaxy-dist commit f372ea5a6014: Fix interpreter for the FASTX Barcode Splitter.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1288902351 14400
# Node ID f372ea5a601443a9b9cd1d3f7e04ddc24db5b57a
# Parent cdf8d61425cce011f98b1f24bd9fe19dc59b10ab
Fix interpreter for the FASTX Barcode Splitter.
--- a/tools/fastx_toolkit/fastx_barcode_splitter.xml
+++ b/tools/fastx_toolkit/fastx_barcode_splitter.xml
@@ -1,7 +1,7 @@
<tool id="cshl_fastx_barcode_splitter" name="Barcode Splitter"><description></description><requirements><requirement type="package">fastx_toolkit</requirement></requirements>
- <command interpreter="sh">fastx_barcode_splitter_galaxy_wrapper.sh $BARCODE $input "$input.name" "$output.files_path" --mismatches $mismatches --partial $partial $EOL > $output </command>
+ <command interpreter="bash">fastx_barcode_splitter_galaxy_wrapper.sh $BARCODE $input "$input.name" "$output.files_path" --mismatches $mismatches --partial $partial $EOL > $output </command><inputs><param format="txt" name="BARCODE" type="data" label="Barcodes to use" />
1
0
galaxy-dist commit 9d68027b0109: Add options to Tophat wrapper for specifying own splice junctions.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1288805582 14400
# Node ID 9d68027b01096e2b32101234878d11946c03d08c
# Parent 49f0e8441a4da6b1ec03250448ab84854f07aa77
Add options to Tophat wrapper for specifying own splice junctions.
--- a/tools/ngs_rna/tophat_wrapper.py
+++ b/tools/ngs_rna/tophat_wrapper.py
@@ -29,6 +29,24 @@ def __main__():
help='The maximum intron length. When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read.' )
parser.add_option( '-F', '--junction_filter', dest='junction_filter', help='Filter out junctions supported by too few alignments (number of reads divided by average depth of coverage)' )
parser.add_option( '-g', '--max_multihits', dest='max_multihits', help='Maximum number of alignments to be allowed' )
+ parser.add_option( '', '--seg-mismatches', dest='seg_mismatches', help='Number of mismatches allowed in each segment alignment for reads mapped independently' )
+ parser.add_option( '', '--seg-length', dest='seg_length', help='Minimum length of read segments' )
+
+ # Options for supplying own junctions
+ parser.add_option( '-G', '--GTF', dest='gene_model_annotations', help='Supply TopHat with a list of gene model annotations. \
+ TopHat will use the exon records in this file to build \
+ a set of known splice junctions for each gene, and will \
+ attempt to align reads to these junctions even if they \
+ would not normally be covered by the initial mapping.')
+ parser.add_option( '-j', '--raw-juncs', dest='raw_juncs', help='Supply TopHat with a list of raw junctions. Junctions are \
+ specified one per line, in a tab-delimited format. Records \
+ look like: <chrom><left><right><+/-> left and right are \
+ zero-based coordinates, and specify the last character of the \
+ left sequenced to be spliced to the first character of the right \
+ sequence, inclusive.')
+ parser.add_option( '', '--no-novel-juncs', action="store_true", dest='no_novel_juncs', help="Only look for junctions indicated in the \
+ supplied GFF file. (ignored without -G)")
+ # Types of search.
parser.add_option( '', '--microexon-search', action="store_true", dest='microexon_search', help='With this option, the pipeline will attempt to find alignments incident to microexons. Works only for reads 50bp or longer.')
parser.add_option( '', '--closure-search', action="store_true", dest='closure_search', help='Enables the mate pair closure-based search for junctions. Closure-based search should only be used when the expected inner distance between mates is small (<= 50bp)')
parser.add_option( '', '--no-closure-search', action="store_false", dest='closure_search' )
@@ -41,8 +59,6 @@ def __main__():
parser.add_option( '', '--max-closure-intron', dest='max_closure_intron', help='Maximum intron length that may be found during closure search' )
parser.add_option( '', '--min-coverage-intron', dest='min_coverage_intron', help='Minimum intron length that may be found during coverage search' )
parser.add_option( '', '--max-coverage-intron', dest='max_coverage_intron', help='Maximum intron length that may be found during coverage search' )
- parser.add_option( '', '--seg-mismatches', dest='seg_mismatches', help='Number of mismatches allowed in each segment alignment for reads mapped independently' )
- parser.add_option( '', '--seg-length', dest='seg_length', help='Minimum length of read segments' )
# Wrapper options.
parser.add_option( '-1', '--input1', dest='input1', help='The (forward or single-end) reads file in Sanger FASTQ format' )
@@ -107,6 +123,15 @@ def __main__():
if float( options.junction_filter ) != 0.0:
opts += ' -F %s' % options.junction_filter
opts += ' -g %s' % options.max_multihits
+ # Custom junctions options.
+ if options.gene_model_annotations:
+ opts += ' -G %s' % options.gene_model_annotations
+ if options.raw_juncs:
+ opts += ' -j %s' % options.raw_juncs
+ if options.no_novel_juncs:
+ opts += ' --no-novel-juncs'
+
+ # Search type options.
if options.coverage_search:
opts += ' --coverage-search --min-coverage-intron %s --max-coverage-intron %s' % ( options.min_coverage_intron, options.max_coverage_intron )
else:
--- a/tools/ngs_rna/tophat_wrapper.xml
+++ b/tools/ngs_rna/tophat_wrapper.xml
@@ -45,6 +45,21 @@
--max-segment-intron $singlePaired.sParams.max_segment_intron
--seg-mismatches=$singlePaired.sParams.seg_mismatches
--seg-length=$singlePaired.sParams.seg_length
+
+ ## Supplying junctions parameters.
+ #if $singlePaired.sParams.own_junctions.use_junctions == "Yes":
+ #if $singlePaired.sParams.own_junctions.gene_model_ann.use_annotations == "Yes":
+ -G $singlePaired.sParams.own_junctions.gene_model_ann.gene_annotation_model
+ #end if
+ #if $singlePaired.sParams.own_junctions.raw_juncs.use_juncs == "Yes":
+ -j $singlePaired.sParams.own_junctions.raw_juncs.raw_juncs
+ #end if
+ ## TODO: No idea why a string cast is necessary, but it is:
+ #if str($singlePaired.sParams.own_junctions.no_novel_juncs) == "Yes":
+ --no-novel-juncs
+ #end if
+ #end if
+
#if $singlePaired.sParams.closure_search.use_search == "Yes":
--closure-search
--min-closure-exon $singlePaired.sParams.closure_search.min_closure_exon
@@ -60,8 +75,8 @@
#else:
--no-coverage-search
#end if
- ## No idea why the type conversion is necessary, but it seems to be.
- #if str ($singlePaired.sParams.microexon_search) == "Yes":
+ ## TODO: No idea why the type conversion is necessary, but it seems to be.
+ #if str($singlePaired.sParams.microexon_search) == "Yes":
--microexon-search
#end if
#end if
@@ -81,6 +96,21 @@
--max-segment-intron $singlePaired.pParams.max_segment_intron
--seg-mismatches=$singlePaired.pParams.seg_mismatches
--seg-length=$singlePaired.pParams.seg_length
+
+ ## Supplying junctions parameters.
+ #if $singlePaired.pParams.own_junctions.use_junctions == "Yes":
+ #if $singlePaired.pParams.own_junctions.gene_model_ann.use_annotations == "Yes":
+ -G $singlePaired.pParams.own_junctions.gene_model_ann.gene_annotation_model
+ #end if
+ #if $singlePaired.pParams.own_junctions.raw_juncs.use_juncs == "Yes":
+ -j $singlePaired.pParams.own_junctions.raw_juncs.raw_juncs
+ #end if
+ ## TODO: No idea why type cast is necessary, but it is:
+ #if str($singlePaired.pParams.own_junctions.no_novel_juncs) == "Yes":
+ --no-novel-juncs
+ #end if
+ #end if
+
#if $singlePaired.pParams.closure_search.use_search == "Yes":
--closure-search
--min-closure-exon $singlePaired.pParams.closure_search.min_closure_exon
@@ -96,7 +126,7 @@
#else:
--no-coverage-search
#end if
- ## No idea why the type conversion is necessary, but it seems to be.
+ ## TODO: No idea why the type conversion is necessary, but it seems to be.
#if str ($singlePaired.pParams.microexon_search) == "Yes":
--microexon-search
#end if
@@ -146,6 +176,42 @@
<param name="max_segment_intron" type="integer" value="500000" label="Maximum intron length that may be found during split-segment (default) search" /><param name="seg_mismatches" type="integer" value="2" label="Number of mismatches allowed in each segment alignment for reads mapped independently" /><param name="seg_length" type="integer" value="25" label="Minimum length of read segments" />
+
+ <!-- Options for supplying own junctions. -->
+ <conditional name="own_junctions">
+ <param name="use_junctions" type="select" label="Use Own Junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <conditional name="gene_model_ann">
+ <param name="use_annotations" type="select" label="Use Gene Annotation Model">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="No" />
+ <when value="Yes">
+ <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/>
+ </when>
+ </conditional>
+ <conditional name="raw_juncs">
+ <param name="use_juncs" type="select" label="Use Raw Junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="No" />
+ <when value="Yes">
+ <param format="interval" name="raw_juncs" type="data" label="Raw Junctions" help="Supply TopHat with a list of raw junctions. Junctions are specified one per line, in a tab-delimited format. Records look like: [chrom] [left] [right] [+/-] left and right are zero-based coordinates, and specify the last character of the left sequenced to be spliced to the first character of the right sequence, inclusive."/>
+ </when>
+ </conditional>
+ <param name="no_novel_juncs" type="select" label="Only look for supplied junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ </when>
+ <when value="No" />
+ </conditional><!-- /own_junctions -->
+
<!-- Closure search. --><conditional name="closure_search"><param name="use_search" type="select" label="Use Closure Search">
@@ -201,6 +267,41 @@
<param name="max_segment_intron" type="integer" value="500000" label="Maximum intron length that may be found during split-segment (default) search" /><param name="seg_mismatches" type="integer" value="2" label="Number of mismatches allowed in each segment alignment for reads mapped independently" /><param name="seg_length" type="integer" value="25" label="Minimum length of read segments" />
+ <!-- Options for supplying own junctions. -->
+ <conditional name="own_junctions">
+ <param name="use_junctions" type="select" label="Use Own Junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <conditional name="gene_model_ann">
+ <param name="use_annotations" type="select" label="Use Gene Annotation Model">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="No" />
+ <when value="Yes">
+ <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/>
+ </when>
+ </conditional>
+ <conditional name="raw_juncs">
+ <param name="use_juncs" type="select" label="Use Raw Junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="No" />
+ <when value="Yes">
+ <param format="interval" name="raw_juncs" type="data" label="Raw Junctions" help="Supply TopHat with a list of raw junctions. Junctions are specified one per line, in a tab-delimited format. Records look like: [chrom] [left] [right] [+/-] left and right are zero-based coordinates, and specify the last character of the left sequenced to be spliced to the first character of the right sequence, inclusive."/>
+ </when>
+ </conditional>
+ <param name="no_novel_juncs" type="select" label="Only look for supplied junctions">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ </when>
+ <when value="No" />
+ </conditional><!-- /own_junctions -->
+
<!-- Closure search. --><conditional name="closure_search"><param name="use_search" type="select" label="Use Closure Search">
@@ -385,8 +486,11 @@ This is a list of implemented Tophat opt
-F/--min-isoform-fraction 0.0-1.0 TopHat filters out junctions supported by too few alignments. Suppose a junction spanning two exons, is supported by S reads. Let the average depth of coverage of
exon A be D, and assume that it is higher than B. If S / D is less than the minimum isoform fraction, the junction is not reported. A value of zero disables the
filter. The default is 0.15.
- -g/--max-multihits INT Instructs TopHat to allow up to this many alignments to the reference for a given read, and suppresses all alignments for reads with more than this many
+ -g/--max-multihits INT Instructs TopHat to allow up to this many alignments to the reference for a given read, and suppresses all alignments for reads with more than this many
alignments. The default is 40.
+ -G/--GTF [GTF 2.2 file] Supply TopHat with a list of gene model annotations. TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping.
+ -j/--raw-juncs [juncs file] Supply TopHat with a list of raw junctions. Junctions are specified one per line, in a tab-delimited format. Records look like: [chrom] [left] [right] [+/-], left and right are zero-based coordinates, and specify the last character of the left sequenced to be spliced to the first character of the right sequence, inclusive.
+ -no-novel-juncs Only look for junctions indicated in the supplied GFF file. (ignored without -G)
--no-closure-search Disables the mate pair closure-based search for junctions. Currently, has no effect - closure search is off by default.
--closure-search Enables the mate pair closure-based search for junctions. Closure-based search should only be used when the expected inner distance between mates is small (about or less than 50bp)
--no-coverage-search Disables the coverage based search for junctions.
1
0
galaxy-dist commit cdf8d61425cc: Fix typo when running a workflow that contains an updated tool.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Daniel Blankenberg <dan(a)bx.psu.edu>
# Date 1288898016 14400
# Node ID cdf8d61425cce011f98b1f24bd9fe19dc59b10ab
# Parent bc690ccf23396e1c7e29e8ee801996ac3e3d3409
Fix typo when running a workflow that contains an updated tool.
--- a/templates/workflow/run.mako
+++ b/templates/workflow/run.mako
@@ -123,7 +123,7 @@ from galaxy.jobs.actions.post import Act
%if has_upgrade_messages:
<div class="warningmessage">
- Problems were encourered when loading this workflow, likely due to tool
+ Problems were encountered when loading this workflow, likely due to tool
version changes. Missing parameter values have been replaced with default.
Please review the parameter values below.
</div>
1
0
galaxy-dist commit cf8bef68e8be: Correction to docstring for Tool.build_param_dict() -- from peter@maubp.freeserve.co.uk
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1288810958 14400
# Node ID cf8bef68e8befb8b6631578b71ff69f701fc0d4d
# Parent b1ec8342053f3cdcd0a081ff28f077a76bd188cc
Correction to docstring for Tool.build_param_dict() -- from peter(a)maubp.freeserve.co.uk
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1333,7 +1333,7 @@ class Tool:
line. Each value is wrapped in a `InputValueWrapper`, which allows
all the attributes of the value to be used in the template, *but*
when the __str__ method is called it actually calls the
- `to_param_dict_value` method of the associated input.
+ `to_param_dict_string` method of the associated input.
"""
param_dict = dict()
# All parameters go into the param_dict
1
0
galaxy-dist commit 16bd91a54888: Must be logged in to use api keys. Fix small typo in error messages
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1288813870 14400
# Node ID 16bd91a548887fb0be24b981c2d66fb7ef7b1922
# Parent cf8bef68e8befb8b6631578b71ff69f701fc0d4d
Must be logged in to use api keys. Fix small typo in error messages
--- a/lib/galaxy/web/controllers/user.py
+++ b/lib/galaxy/web/controllers/user.py
@@ -984,6 +984,7 @@ class User( BaseController, UsesFormDefi
message=message,
lines_skipped=lines_skipped )
@web.expose
+ @web.require_login()
def api_keys( self, trans, **kwd ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -84,7 +84,7 @@ def require_login( verb="perform this ac
return func( self, trans, *args, **kwargs )
else:
return trans.show_error_message(
- 'You must be <a target="_top" href="%s">logged in</a> to %s</div>.'
+ 'You must be <a target="_top" href="%s">logged in</a> to %s.'
% ( url_for( controller='user', action='login', webapp=webapp ), verb ), use_panels=use_panels )
return decorator
return argcatcher
1
0
galaxy-dist commit 27c152bb441a: More sample tracking bug fixes - tweaked permissions on displaying buttons, and fixed exceptions thrown when ddata transfer congid file is incorrect.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1288730067 14400
# Node ID 27c152bb441a0136720dbbc0c7cb293e581b8f5f
# Parent 6497a8cfd12e477e9c92dd183c4abb81d469ba51
More sample tracking bug fixes - tweaked permissions on displaying buttons, and fixed exceptions thrown when ddata transfer congid file is incorrect.
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -541,7 +541,7 @@ class RequestsAdmin( BaseController, Use
return sample.request.name + '_' + sample.name + '_' + name
if opt == options.EXPERIMENT_NAME:
return sample.request.name + '_' + name
- def __setup_datatx_user( self, trans, library, folder ):
+ def __setup_datatx_user( self, trans, sample ):
"""
Sets up the datatx user:
- Checks if the user exists, if not creates them.
@@ -550,9 +550,25 @@ class RequestsAdmin( BaseController, Use
"""
# Retrieve the upload user login information from the config file
config = ConfigParser.ConfigParser()
- config.read( 'transfer_datasets.ini' )
- email = config.get( "data_transfer_user_login_info", "email" )
- password = config.get( "data_transfer_user_login_info", "password" )
+ ok = True
+ try:
+ config.read( 'transfer_datasets.ini' )
+ except Exception, e:
+ message = "Error attempting to read config file named 'transfer_datasets.ini'. Make sure this file is correct."
+ ok = False
+ try:
+ email = config.get( "data_transfer_user_login_info", "email" )
+ password = config.get( "data_transfer_user_login_info", "password" )
+ except Exception, e:
+ message = "The 'data_transfer_user_login_info' section is missing from the 'transfer_datasets.ini'. Make sure this file is correct."
+ ok = False
+ if not ok:
+ status = 'error'
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='manage_datasets',
+ sample_id=trans.security.encode_id( sample.id ),
+ status=status,
+ message=message ) )
# check if the user already exists
datatx_user = trans.sa_session.query( trans.model.User ) \
.filter( trans.model.User.table.c.email==email ) \
@@ -570,14 +586,14 @@ class RequestsAdmin( BaseController, Use
datatx_user_private_role = trans.app.security_agent.get_private_user_role( datatx_user )
# Make sure this user has LIBRARY_ADD permissions on the target library and folder.
# If not, give them permission.
- if not trans.app.security_agent.can_add_library_item( datatx_user_roles, library ):
+ if not trans.app.security_agent.can_add_library_item( datatx_user_roles, sample.library ):
lp = trans.model.LibraryPermissions( trans.app.security_agent.permitted_actions.LIBRARY_ADD.action,
- library,
+ sample.library,
datatx_user_private_role )
trans.sa_session.add( lp )
- if not trans.app.security_agent.can_add_library_item( datatx_user_roles, folder ):
+ if not trans.app.security_agent.can_add_library_item( datatx_user_roles, sample.folder ):
lfp = trans.model.LibraryFolderPermissions( trans.app.security_agent.permitted_actions.LIBRARY_ADD.action,
- folder,
+ sample.folder,
datatx_user_private_role )
trans.sa_session.add( lfp )
trans.sa_session.flush()
@@ -646,7 +662,7 @@ class RequestsAdmin( BaseController, Use
message=message) )
def __start_datatx( self, trans, sample, selected_sample_datasets ):
- datatx_user = self.__setup_datatx_user( trans, sample.library, sample.folder )
+ datatx_user = self.__setup_datatx_user( trans, sample )
# Validate sequencer information
datatx_info = sample.request.type.datatx_info
if not datatx_info['host'] or not datatx_info['username'] or not datatx_info['password']:
@@ -660,7 +676,7 @@ class RequestsAdmin( BaseController, Use
action='manage_datasets',
sample_id=trans.security.encode_id( sample.id ),
status=status,
- message=message) )
+ message=message ) )
@web.expose
def update_sample_dataset_status(self, trans, cntrller, sample_dataset_ids, new_status, error_msg=None ):
# check if the new status is a valid transfer status
--- a/templates/requests/common/common.mako
+++ b/templates/requests/common/common.mako
@@ -120,20 +120,25 @@
if sample:
trans.sa_session.refresh( sample.request )
is_complete = sample.request.is_complete
+ is_rejected = request.is_rejected
is_submitted = sample.request.is_submitted
is_unsubmitted = sample.request.is_unsubmitted
+ display_checkboxes = editing_samples and ( is_complete or is_rejected or is_submitted )
+ display_bar_code = request.samples and ( is_complete or is_rejected or is_submitted )
+ display_datasets = request.samples and ( is_complete or is_rejected or is_submitted )
else:
is_complete = False
is_submitted = False
is_unsubmitted = False
+ display_checkboxes = False
%><%
- if is_submitted and editing_samples and trans.security.encode_id( sample.id ) in encoded_selected_sample_ids:
+ if display_checkboxes and trans.security.encode_id( sample.id ) in encoded_selected_sample_ids:
checked_str = "checked"
else:
checked_str = ""
%>
- %if is_submitted and editing_samples:
+ %if display_checkboxes:
<td><input type="checkbox" name=select_sample_${sample.id} id="sample_checkbox" value="true" ${checked_str}/><input type="hidden" name=select_sample_${sample.id} id="sample_checkbox" value="true"/></td>
%endif
<td valign="top">
@@ -142,12 +147,14 @@
<i>${' (required)' }</i></div></td>
- %if sample and is_submitted or is_complete:
- %if is_admin:
- <td valign="top"><input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/></td>
- %else:
- ${current_sample['barcode']}
- %endif
+ %if display_bar_code:
+ <td valign="top">
+ %if is_admin:
+ <input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/>
+ %else:
+ ${current_sample['barcode']}
+ %endif
+ </td>
%endif
%if sample:
%if is_unsubmitted:
@@ -160,7 +167,7 @@
%endif
<td valign="top">${current_sample['library_select_field'].get_html()}</td><td valign="top">${current_sample['folder_select_field'].get_html()}</td>
- %if is_submitted or is_complete:
+ %if display_datasets:
<%
if sample:
label = str( len( sample.datasets ) )
@@ -182,11 +189,15 @@
trans.sa_session.refresh( request )
is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
is_complete = request.is_complete
+ is_rejected = request.is_rejected
is_submitted = request.is_submitted
is_unsubmitted = request.is_unsubmitted
can_add_samples = request.is_unsubmitted
can_delete_samples = request.samples and not is_complete
can_edit_samples = request.samples and ( is_admin or not is_complete )
+ display_checkboxes = editing_samples and ( is_complete or is_rejected or is_submitted )
+ display_bar_code = request.samples and ( is_complete or is_rejected or is_submitted )
+ display_datasets = request.samples and ( is_complete or is_rejected or is_submitted )
%>
${grid_header}
%if render_buttons and ( can_add_samples or can_edit_samples ):
@@ -202,22 +213,22 @@
<table class="grid"><thead><tr>
- %if is_submitted and editing_samples:
+ %if display_checkboxes:
<th><input type="checkbox" id="checkAll" name=select_all_samples_checkbox value="true" onclick='checkAllFields(1);'/><input type="hidden" name=select_all_samples_checkbox value="true"/></th>
%endif
<th>Name</th>
- %if is_submitted or is_complete:
+ %if display_bar_code:
<th>Barcode</th>
%endif
<th>State</th><th>Data Library</th><th>Folder</th>
- %if is_submitted or is_complete:
+ %if display_datasets:
<th>Datasets Selected</th><th>Datasets Transferred</th>
%endif
<th>
- %if editing_samples:
+ %if can_delete_samples:
Delete
%endif
</th>
@@ -245,7 +256,7 @@
except:
sample = None
%>
- %if not is_complete and editing_samples:
+ %if editing_samples:
<tr>${render_editable_sample_row( is_admin, sample, current_sample_index, current_sample, encoded_selected_sample_ids )}</tr>
%elif sample:
<tr>
1
0
galaxy-dist commit 569483091092: Keep the sample's bar code incormation when editn the sample row in the non-admin user view.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1288731289 14400
# Node ID 56948309109207f932a113e464409432c7a38df7
# Parent 27c152bb441a0136720dbbc0c7cb293e581b8f5f
Keep the sample's bar code incormation when editn the sample row in the non-admin user view.
--- a/templates/requests/common/common.mako
+++ b/templates/requests/common/common.mako
@@ -153,6 +153,7 @@
<input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/>
%else:
${current_sample['barcode']}
+ <input type="hidden" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}"/>
%endif
</td>
%endif
@@ -261,7 +262,7 @@
%elif sample:
<tr><td>${current_sample_name}</td>
- %if is_submitted or is_complete:
+ %if display_bar_code:
<td>${current_sample_barcode}</td>
%endif
%if is_unsubmitted:
1
0
galaxy-dist commit 6497a8cfd12e: More miscellaneous bug fixes in Sample Tracking, all due to the recent UI changes. Changes the name of the test_forms_and_requests.py functional test script to be test_sample_tracking.py to more clearly reeflect what's being tested.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1288723785 14400
# Node ID 6497a8cfd12e477e9c92dd183c4abb81d469ba51
# Parent b7ac22fab1588a565a07acc4972564c2b9198489
More miscellaneous bug fixes in Sample Tracking, all due to the recent UI changes. Changes the name of the test_forms_and_requests.py functional test script to be test_sample_tracking.py to more clearly reeflect what's being tested.
--- a/templates/requests/common/edit_samples.mako
+++ b/templates/requests/common/edit_samples.mako
@@ -12,58 +12,6 @@
<%def name="javascripts()">
${parent.javascripts()}
${common_javascripts()}
- ${local_javascripts()}
-</%def>
-
-<%def name="local_javascripts()">
- <script type="text/javascript">
- // Looks for changes in sample states using an async request. Keeps
- // calling itself (via setTimeout) until all samples are in a terminal
- // state.
- var updater = function ( sample_states ) {
- // Check if there are any items left to track
- var empty = true;
- for ( i in sample_states ) {
- empty = false;
- break;
- }
- if ( ! empty ) {
- setTimeout( function() { updater_callback( sample_states ) }, 1000 );
- }
- };
-
- var updater_callback = function ( sample_states ) {
- // Build request data
- var ids = []
- var states = []
- $.each( sample_states, function ( id, state ) {
- ids.push( id );
- states.push( state );
- });
- // Make ajax call
- $.ajax( {
- type: "POST",
- url: "${h.url_for( controller='requests_common', action='sample_state_updates' )}",
- dataType: "json",
- data: { ids: ids.join( "," ), states: states.join( "," ) },
- success : function ( data ) {
- $.each( data, function( id, val ) {
- // Replace HTML
- var cell1 = $("#sampleState-" + id);
- cell1.html( val.html_state );
- var cell2 = $("#sampleDatasets-" + id);
- cell2.html( val.html_datasets );
- sample_states[ parseInt( id ) ] = val.state;
- });
- updater( sample_states );
- },
- error: function() {
- // Just retry, like the old method, should try to be smarter
- updater( sample_states );
- }
- });
- };
- </script></%def><%
@@ -73,7 +21,8 @@
is_complete = request.is_complete
is_unsubmitted = request.is_unsubmitted
can_add_samples = is_unsubmitted
- can_edit_or_delete_samples = request.samples and not is_complete
+ can_delete_samples = request.samples and not is_complete
+ can_edit_samples = request.samples and ( is_admin or not is_complete )
can_edit_request = ( is_admin and not request.is_complete ) or request.is_unsubmitted
can_reject_or_transfer = is_admin and request.is_submitted
can_submit = request.samples and is_unsubmitted
@@ -82,7 +31,7 @@
<br/><br/><ul class="manage-table-actions">
- %if not editing_samples and can_edit_or_delete_samples:
+ %if not editing_samples and can_edit_samples:
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='edit_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ), editing_samples='True' )}">Edit samples</a></li>
%endif
%if editing_samples and can_add_samples:
@@ -131,13 +80,13 @@
grid_header = '<h3>Add Samples to Request "%s"</h3>' % request.name
%>
${render_samples_grid( cntrller, request, current_samples, action='edit_samples', editing_samples=editing_samples, encoded_selected_sample_ids=encoded_selected_sample_ids, render_buttons=False, grid_header=grid_header )}
- %if editing_samples and len( sample_operation_select_field.options ) > 1 and not ( is_unsubmitted or is_complete ):
+ %if editing_samples and len( sample_operation_select_field.options ) > 1 and not is_unsubmitted:
<div class="form-row" style="background-color:#FAFAFA;">
For selected samples:
${sample_operation_select_field.get_html()}
</div><% sample_operation_selected_value = sample_operation_select_field.get_selected( return_value=True ) %>
- %if sample_operation_selected_value != 'none' and encoded_selected_sample_ids:
+ %if ( is_admin or not is_complete ) and sample_operation_selected_value != 'none' and encoded_selected_sample_ids:
<div class="form-row" style="background-color:#FAFAFA;">
%if sample_operation_selected_value == trans.model.Sample.bulk_operations.CHANGE_STATE:
## sample_operation_selected_value == 'Change state'
@@ -150,7 +99,7 @@
Optional
</div></div>
- %elif sample_operation_selected_value == trans.app.model.Sample.bulk_operations.SELECT_LIBRARY:
+ %elif not is_complete and sample_operation_selected_value == trans.app.model.Sample.bulk_operations.SELECT_LIBRARY:
<% libraries_selected_value = libraries_select_field.get_selected( return_value=True ) %><div class="form-row"><label>Select data library:</label>
@@ -210,12 +159,12 @@
Click the <b>Save</b> button when you have finished editing the samples
</div>
%endif
- ##%if request.samples and request.is_submitted:
- ## <script type="text/javascript">
- ## // Updater
- ## updater( {${ ",".join( [ '"%s" : "%s"' % ( s.id, s.state.name ) for s in request.samples ] ) }});
- ## </script>
- ##%endif
+ %if request.samples and request.is_submitted:
+ <script type="text/javascript">
+ // Updater
+ updater( {${ ",".join( [ '"%s" : "%s"' % ( s.id, s.state.name ) for s in request.samples ] ) }});
+ </script>
+ %endif
</form></div>
%if is_unsubmitted and not editing_samples:
--- a/test/functional/test_forms_and_requests.py
+++ /dev/null
@@ -1,436 +0,0 @@
-import galaxy.model
-from galaxy.model.orm import *
-from base.twilltestcase import *
-from base.test_db_util import *
-
-sample_states = [ ( 'New', 'Sample entered into the system' ),
- ( 'Received', 'Sample tube received' ),
- ( 'Done', 'Sequence run complete' ) ]
-address_dict = dict( short_desc="Office",
- name="James Bond",
- institution="MI6" ,
- address="MI6 Headquarters",
- city="London",
- state="London",
- postal_code="007",
- country="United Kingdom",
- phone="007-007-0007" )
-
-class TestFormsAndRequests( TwillTestCase ):
- def test_000_initiate_users( self ):
- """Ensuring all required user accounts exist"""
- self.logout()
- self.login( email='test1(a)bx.psu.edu', username='regular-user1' )
- global regular_user1
- regular_user1 = get_user( 'test1(a)bx.psu.edu' )
- assert regular_user1 is not None, 'Problem retrieving user with email "test1(a)bx.psu.edu" from the database'
- global regular_user1_private_role
- regular_user1_private_role = get_private_role( regular_user1 )
- self.logout()
- self.login( email='test2(a)bx.psu.edu', username='regular-user2' )
- global regular_user2
- regular_user2 = get_user( 'test2(a)bx.psu.edu' )
- assert regular_user2 is not None, 'Problem retrieving user with email "test2(a)bx.psu.edu" from the database'
- global regular_user2_private_role
- regular_user2_private_role = get_private_role( regular_user2 )
- self.logout()
- self.login( email='test3(a)bx.psu.edu', username='regular-user3' )
- global regular_user3
- regular_user3 = get_user( 'test3(a)bx.psu.edu' )
- assert regular_user3 is not None, 'Problem retrieving user with email "test3(a)bx.psu.edu" from the database'
- global regular_user3_private_role
- regular_user3_private_role = get_private_role( regular_user3 )
- self.logout()
- self.login( email='test(a)bx.psu.edu', username='admin-user' )
- global admin_user
- admin_user = get_user( 'test(a)bx.psu.edu' )
- assert admin_user is not None, 'Problem retrieving user with email "test(a)bx.psu.edu" from the database'
- global admin_user_private_role
- admin_user_private_role = get_private_role( admin_user )
- def test_005_create_required_groups_and_roles( self ):
- """Testing creating all required groups and roles for this script"""
- # Logged in as admin_user
- # Create role_one
- name = 'Role One'
- description = "This is Role One's description"
- user_ids = [ str( admin_user.id ), str( regular_user1.id ), str( regular_user3.id ) ]
- self.create_role( name=name,
- description=description,
- in_user_ids=user_ids,
- in_group_ids=[],
- create_group_for_role='no',
- private_role=admin_user.email )
- # Get the role object for later tests
- global role_one
- role_one = get_role_by_name( name )
- # Create group_one
- name = 'Group One'
- self.create_group( name=name, in_user_ids=[ str( regular_user1.id ) ], in_role_ids=[ str( role_one.id ) ] )
- # Get the group object for later tests
- global group_one
- group_one = get_group_by_name( name )
- assert group_one is not None, 'Problem retrieving group named "Group One" from the database'
- # NOTE: To get this to work with twill, all select lists on the ~/admin/role page must contain at least
- # 1 option value or twill throws an exception, which is: ParseError: OPTION outside of SELECT
- # Due to this bug in twill, we create the role, we bypass the page and visit the URL in the
- # associate_users_and_groups_with_role() method.
- #
- #create role_two
- name = 'Role Two'
- description = 'This is Role Two'
- user_ids = [ str( admin_user.id ) ]
- group_ids = [ str( group_one.id ) ]
- private_role = admin_user.email
- self.create_role( name=name,
- description=description,
- in_user_ids=user_ids,
- in_group_ids=group_ids,
- private_role=private_role )
- # Get the role object for later tests
- global role_two
- role_two = get_role_by_name( name )
- assert role_two is not None, 'Problem retrieving role named "Role Two" from the database'
- def test_010_create_request_form( self ):
- """Testing creating a request form definition, editing the name and description and adding fields"""
- # Logged in as admin_user
- # Create a form definition
- tmp_name = "Temp form"
- tmp_desc = "Temp form description"
- form_type = galaxy.model.FormDefinition.types.REQUEST
- self.create_form( name=tmp_name,
- desc=tmp_desc,
- form_type=form_type,
- num_fields=0,
- strings_displayed=[ 'Create a new form definition' ],
- strings_displayed_after_submit=[ tmp_name, tmp_desc, form_type ] )
- tmp_form = get_form( tmp_name )
- # Edit the name and description of the form definition, and add 3 fields.
- new_name = "Request Form"
- new_desc = "Request Form description"
- global test_field_name1
- test_field_name1 = 'Test field name one'
- global test_field_name2
- test_field_name2 = 'Test field name two'
- global test_field_name3
- test_field_name3 = 'Test field name three'
- field_dicts = [ dict( name=test_field_name1,
- desc='Test field description one',
- type='SelectField',
- required='optional',
- selectlist=[ 'option1', 'option2' ] ),
- dict( name=test_field_name2,
- desc='Test field description two',
- type='AddressField',
- required='optional' ),
- dict( name=test_field_name3,
- desc='Test field description three',
- type='TextField',
- required='required' ) ]
- self.edit_form( id=self.security.encode_id( tmp_form.current.id ),
- new_form_name=new_name,
- new_form_desc=new_desc,
- field_dicts=field_dicts,
- field_index=len( tmp_form.fields ),
- strings_displayed=[ 'Edit form definition "%s"' % tmp_name ],
- strings_displayed_after_submit=[ "The form '%s' has been updated with the changes." % new_name ] )
- # Get the form_definition object for later tests
- global form_one
- form_one = get_form( new_name )
- assert form_one is not None, 'Problem retrieving form named "%s" from the database' % new_name
- assert len( form_one.fields ) == len( tmp_form.fields ) + len( field_dicts )
- def test_015_create_sample_form( self ):
- """Testing creating sample form definition"""
- name = "Sample Form"
- desc = "This is Form Two's description"
- form_type = galaxy.model.FormDefinition.types.SAMPLE
- form_layout_name = 'Layout Grid One'
- self.create_form( name=name,
- desc=desc,
- form_type=form_type,
- form_layout_name=form_layout_name,
- strings_displayed=[ 'Create a new form definition' ],
- strings_displayed_after_submit=[ "The form '%s' has been updated with the changes." % name ] )
- global form_two
- form_two = get_form( name )
- assert form_two is not None, "Error retrieving form %s from db" % name
- def test_020_create_request_type( self ):
- """Testing creating a request_type"""
- request_form = get_form( form_one.name )
- sample_form = get_form( form_two.name )
- name = 'Test Requestype'
- self.create_request_type( name,
- "test sequencer configuration",
- self.security.encode_id( request_form.id ),
- self.security.encode_id( sample_form.id ),
- sample_states,
- strings_displayed=[ 'Create a new sequencer configuration' ],
- strings_displayed_after_submit=[ "Sequencer configuration (%s) has been created" % name ] )
- global request_type1
- request_type1 = get_request_type_by_name( name )
- assert request_type1 is not None, 'Problem retrieving sequencer configuration named "%s" from the database' % name
- # Set permissions
- permissions_in = [ k for k, v in galaxy.model.RequestType.permitted_actions.items() ]
- permissions_out = []
- # Role one members are: admin_user, regular_user1, regular_user3. Each of these users will be permitted for
- # REQUEST_TYPE_ACCESS on this request_type
- self.request_type_permissions( self.security.encode_id( request_type1.id ),
- request_type1.name,
- str( role_one.id ),
- permissions_in,
- permissions_out )
- # Make sure the request_type1 is not accessible by regular_user2 since regular_user2 does not have Role1.
- self.logout()
- self.login( email=regular_user2.email )
- self.visit_url( '%s/requests_common/create_request?cntrller=requests&request_type=True' % self.url )
- try:
- self.check_page_for_string( 'There are no sequencer configurations created for a new request.' )
- raise AssertionError, 'The request_type %s is accessible by %s when it should be restricted' % ( request_type1.name, regular_user2.email )
- except:
- pass
- self.logout()
- self.login( email=admin_user.email )
- def test_025_create_request( self ):
- """Testing creating a sequence run request"""
- # logged in as admin_user
- # Create a user_address
- self.logout()
- self.login( email=regular_user1.email )
- self.add_user_address( regular_user1.id, address_dict )
- global user_address1
- user_address1 = get_user_address( regular_user1, address_dict[ 'short_desc' ] )
- # Set field values - the tuples in the field_values list include the field_value, and True if refresh_on_change
- # is required for that field.
- field_value_tuples = [ ( 'option1', False ), ( str( user_address1.id ), True ), ( 'field three value', False ) ]
- # Create the request
- name = 'Request One'
- desc = 'Request One Description'
- self.create_request( cntrller='requests',
- request_type_id=self.security.encode_id( request_type1.id ),
- name=name,
- desc=desc,
- field_value_tuples=field_value_tuples,
- strings_displayed=[ 'Create a new sequencing request',
- test_field_name1,
- test_field_name2,
- test_field_name3 ],
- strings_displayed_after_submit=[ name, desc ] )
- global request_one
- request_one = get_request_by_name( name )
- # Make sure the request's state is now set to NEW
- assert request_one.state is not request_one.states.NEW, "The state of the request '%s' should be set to '%s'" \
- % ( request_one.name, request_one.states.NEW )
- # Sample fields - the tuple represents a sample name and a list of sample form field values
- sample_value_tuples = [ ( 'Sample One', [ 'S1 Field 0 Value' ] ),
- ( 'Sample Two', [ 'S2 Field 0 Value' ] ) ]
- strings_displayed_after_submit = [ 'Unsubmitted' ]
- for sample_name, field_values in sample_value_tuples:
- strings_displayed_after_submit.append( sample_name )
- # Add samples to the request
- self.add_samples( cntrller='requests',
- request_id=self.security.encode_id( request_one.id ),
- request_name=request_one.name,
- sample_value_tuples=sample_value_tuples,
- strings_displayed=[ 'There are no samples.' ],
- strings_displayed_after_submit=strings_displayed_after_submit )
- def test_030_edit_basic_request_info( self ):
- """Testing editing the basic information of a sequence run request"""
- # logged in as regular_user1
- fields = [ 'option2', str( user_address1.id ), 'field three value (edited)' ]
- new_name=request_one.name + ' (Renamed)'
- new_desc=request_one.desc + ' (Re-described)'
- self.edit_basic_request_info( request_id=self.security.encode_id( request_one.id ),
- cntrller='requests',
- name=request_one.name,
- new_name=new_name,
- new_desc=new_desc,
- new_fields=fields,
- strings_displayed=[ 'Edit sequencing request "%s"' % request_one.name ],
- strings_displayed_after_submit=[ new_name, new_desc ] )
- refresh( request_one )
- # check if the request is showing in the 'new' filter
- self.check_request_grid( cntrller='requests',
- state=request_one.states.NEW,
- strings_displayed=[ request_one.name ] )
- def test_035_submit_request( self ):
- """Testing editing a sequence run request"""
- # logged in as regular_user1
- self.submit_request( cntrller='requests',
- request_id=self.security.encode_id( request_one.id ),
- request_name=request_one.name,
- strings_displayed_after_submit=[ 'The request has been submitted.' ] )
- refresh( request_one )
- # Make sure the request is showing in the 'submitted' filter
- self.check_request_grid( cntrller='requests',
- state=request_one.states.SUBMITTED,
- strings_displayed=[ request_one.name ] )
- # Make sure the request's state is now set to 'submitted'
- assert request_one.state is not request_one.states.SUBMITTED, "The state of the request '%s' should be set to '%s'" \
- % ( request_one.name, request_one.states.SUBMITTED )
- def test_040_request_lifecycle( self ):
- """Testing request life-cycle as it goes through all the states"""
- # logged in as regular_user1
- self.logout()
- self.login( email=admin_user.email )
- self.check_request_grid( cntrller='requests_admin',
- state=request_one.states.SUBMITTED,
- strings_displayed=[ request_one.name ] )
- self.visit_url( "%s/requests_common/view_request?cntrller=requests&id=%s" % ( self.url, self.security.encode_id( request_one.id ) ) )
- # TODO: add some string for checking on the page above...
- # Set bar codes for the samples
- bar_codes = [ '1234567890', '0987654321' ]
- strings_displayed_after_submit=[ 'Changes made to the samples have been saved.' ]
- for bar_code in bar_codes:
- strings_displayed_after_submit.append( bar_code )
- self.add_bar_codes( request_id=self.security.encode_id( request_one.id ),
- request_name=request_one.name,
- bar_codes=bar_codes,
- samples=request_one.samples,
- strings_displayed_after_submit=strings_displayed_after_submit )
- # Change the states of all the samples of this request to ultimately be COMPLETE
- self.change_sample_state( request_id=self.security.encode_id( request_one.id ),
- request_name=request_one.name,
- sample_names=[ sample.name for sample in request_one.samples ],
- sample_ids=[ sample.id for sample in request_one.samples ],
- new_sample_state_id=request_type1.states[1].id,
- new_state_name=request_type1.states[1].name )
- self.change_sample_state( request_id=self.security.encode_id( request_one.id ),
- request_name=request_one.name,
- sample_names=[ sample.name for sample in request_one.samples ],
- sample_ids=[ sample.id for sample in request_one.samples ],
- new_sample_state_id=request_type1.states[2].id,
- new_state_name=request_type1.states[2].name )
- refresh( request_one )
- self.logout()
- self.login( email=regular_user1.email )
- # check if the request's state is now set to 'complete'
- self.check_request_grid( cntrller='requests',
- state='Complete',
- strings_displayed=[ request_one.name ] )
- assert request_one.state is not request_one.states.COMPLETE, "The state of the request '%s' should be set to '%s'" \
- % ( request_one.name, request_one.states.COMPLETE )
-
- def test_045_admin_create_request_on_behalf_of_regular_user( self ):
- """Testing creating and submitting a request as an admin on behalf of a regular user"""
- # Logged in as regular_user1
- self.logout()
- self.login( email=admin_user.email )
- # Create the request
- name = "RequestTwo"
- desc = 'Request Two Description'
- # Set field values - the tuples in the field_values list include the field_value, and True if refresh_on_change
- # is required for that field.
- field_value_tuples = [ ( 'option2', False ), ( str( user_address1.id ), True ), ( 'field_2_value', False ) ]
- self.create_request( cntrller='requests_admin',
- request_type_id=self.security.encode_id( request_type1.id ),
- other_users_id=self.security.encode_id( regular_user1.id ),
- name=name,
- desc=desc,
- field_value_tuples=field_value_tuples,
- strings_displayed=[ 'Create a new sequencing request',
- test_field_name1,
- test_field_name2,
- test_field_name3 ],
- strings_displayed_after_submit=[ "The request has been created." ] )
- global request_two
- request_two = get_request_by_name( name )
- # Make sure the request is showing in the 'new' filter
- self.check_request_grid( cntrller='requests_admin',
- state=request_two.states.NEW,
- strings_displayed=[ request_two.name ] )
- # Make sure the request's state is now set to 'new'
- assert request_two.state is not request_two.states.NEW, "The state of the request '%s' should be set to '%s'" \
- % ( request_two.name, request_two.states.NEW )
- # Sample fields - the tuple represents a sample name and a list of sample form field values
- sample_value_tuples = [ ( 'Sample One', [ 'S1 Field 0 Value' ] ),
- ( 'Sample Two', [ 'S2 Field 0 Value' ] ) ]
- strings_displayed_after_submit = [ 'Unsubmitted' ]
- for sample_name, field_values in sample_value_tuples:
- strings_displayed_after_submit.append( sample_name )
- # Add samples to the request
- self.add_samples( cntrller='requests_admin',
- request_id=self.security.encode_id( request_two.id ),
- request_name=request_two.name,
- sample_value_tuples=sample_value_tuples,
- strings_displayed=[ 'There are no samples.' ],
- strings_displayed_after_submit=strings_displayed_after_submit )
- # Submit the request
- self.submit_request( cntrller='requests_admin',
- request_id=self.security.encode_id( request_two.id ),
- request_name=request_two.name,
- strings_displayed_after_submit=[ 'The request has been submitted.' ] )
- refresh( request_two )
- # Make sure the request is showing in the 'submitted' filter
- self.check_request_grid( cntrller='requests_admin',
- state=request_two.states.SUBMITTED,
- strings_displayed=[ request_two.name ] )
- # Make sure the request's state is now set to 'submitted'
- assert request_two.state is not request_two.states.SUBMITTED, "The state of the request '%s' should be set to '%s'" \
- % ( request_two.name, request_two.states.SUBMITTED )
- # Make sure both requests are showing in the 'All' filter
- self.check_request_grid( cntrller='requests_admin',
- state='All',
- strings_displayed=[ request_one.name, request_two.name ] )
- def test_050_reject_request( self ):
- """Testing rejecting a request"""
- # Logged in as admin_user
- self.reject_request( request_id=self.security.encode_id( request_two.id ),
- request_name=request_two.name,
- comment="Rejection test comment",
- strings_displayed=[ 'Reject Sequencing Request "%s"' % request_two.name ],
- strings_displayed_after_submit=[ 'Request (%s) has been rejected.' % request_two.name ] )
- refresh( request_two )
- # Make sure the request is showing in the 'rejected' filter
- self.check_request_grid( cntrller='requests_admin',
- state=request_two.states.REJECTED,
- strings_displayed=[ request_two.name ] )
- # Make sure the request's state is now set to REJECTED
- assert request_two.state is not request_two.states.REJECTED, "The state of the request '%s' should be set to '%s'" \
- % ( request_two.name, request_two.states.REJECTED )
- def test_055_reset_data_for_later_test_runs( self ):
- """Reseting data to enable later test runs to pass"""
- """
- # Logged in as admin_user
- ##################
- # Delete request_type permissions
- ##################
- for request_type in [ request_type1 ]:
- delete_request_type_permissions( request_type.id )
- ##################
- # Mark all request_types deleted
- ##################
- for request_type in [ request_type1 ]:
- mark_obj_deleted( request_type )
- ##################
- # Mark all requests deleted
- ##################
- for request in [ request_one, request_two ]:
- mark_obj_deleted( request )
- ##################
- # Mark all forms deleted
- ##################
- for form in [ form_one, form_two ]:
- self.mark_form_deleted( self.security.encode_id( form.current.id ) )
- ##################
- # Mark all user_addresses deleted
- ##################
- for user_address in [ user_address1 ]:
- mark_obj_deleted( user_address )
- ##################
- # Delete all non-private roles
- ##################
- for role in [ role_one, role_two ]:
- self.mark_role_deleted( self.security.encode_id( role.id ), role.name )
- self.purge_role( self.security.encode_id( role.id ), role.name )
- # Manually delete the role from the database
- refresh( role )
- delete( role )
- ##################
- # Delete all groups
- ##################
- for group in [ group_one ]:
- self.mark_group_deleted( self.security.encode_id( group.id ), group.name )
- self.purge_group( self.security.encode_id( group.id ), group.name )
- # Manually delete the group from the database
- refresh( group )
- delete( group )
- """
--- a/lib/galaxy/web/controllers/requests_common.py
+++ b/lib/galaxy/web/controllers/requests_common.py
@@ -1047,10 +1047,15 @@ class RequestsCommon( BaseController, Us
action='update_request_state',
request_id=trans.security.encode_id( request.id ) ) )
elif sample_operation == 'Select data library and folder':
+ # TODO: fix the code so that the sample_operation_select_field does not use
+ # sample_0_library_id as it's name. it should use something like sample_operation_library_id
+ # and sample_operation-folder_id because the name sample_0_library_id should belong to the
+ # first sample since all other form field values are named like this. The library and folder
+ # are skewed to be named +1 resulting in the forced use of id_index everywhere...
library_id = params.get( 'sample_0_library_id', 'none' )
folder_id = params.get( 'sample_0_folder_id', 'none' )
library, folder = self.__get_library_and_folder( trans, library_id, folder_id )
- self.__update_samples( trans, request, samples, **kwd )
+ self.__update_samples( trans, cntrller, request, samples, **kwd )
# Samples will not have an associated SampleState until the request is submitted, at which
# time all samples of the request will be set to the first SampleState configured for the
# request's RequestType defined by the admin.
@@ -1092,7 +1097,7 @@ class RequestsCommon( BaseController, Us
editing_samples=editing_samples,
status=status,
message=message ) )
- def __update_samples( self, trans, request, sample_widgets, **kwd ):
+ def __update_samples( self, trans, cntrller, request, sample_widgets, **kwd ):
# Determine if the values in kwd require updating the request's samples. The list of
# sample_widgets must have the same number of objects as request.samples, but some of
# the objects can be None. Those that are not None correspond to samples selected by
--- /dev/null
+++ b/test/functional/test_sample_tracking.py
@@ -0,0 +1,434 @@
+import galaxy.model
+from galaxy.model.orm import *
+from base.twilltestcase import *
+from base.test_db_util import *
+
+sample_states = [ ( 'New', 'Sample entered into the system' ),
+ ( 'Received', 'Sample tube received' ),
+ ( 'Done', 'Sequence run complete' ) ]
+address_dict = dict( short_desc="Office",
+ name="James Bond",
+ institution="MI6" ,
+ address="MI6 Headquarters",
+ city="London",
+ state="London",
+ postal_code="007",
+ country="United Kingdom",
+ phone="007-007-0007" )
+
+class TestFormsAndRequests( TwillTestCase ):
+ def test_000_initiate_users( self ):
+ """Ensuring all required user accounts exist"""
+ self.logout()
+ self.login( email='test1(a)bx.psu.edu', username='regular-user1' )
+ global regular_user1
+ regular_user1 = get_user( 'test1(a)bx.psu.edu' )
+ assert regular_user1 is not None, 'Problem retrieving user with email "test1(a)bx.psu.edu" from the database'
+ global regular_user1_private_role
+ regular_user1_private_role = get_private_role( regular_user1 )
+ self.logout()
+ self.login( email='test2(a)bx.psu.edu', username='regular-user2' )
+ global regular_user2
+ regular_user2 = get_user( 'test2(a)bx.psu.edu' )
+ assert regular_user2 is not None, 'Problem retrieving user with email "test2(a)bx.psu.edu" from the database'
+ global regular_user2_private_role
+ regular_user2_private_role = get_private_role( regular_user2 )
+ self.logout()
+ self.login( email='test3(a)bx.psu.edu', username='regular-user3' )
+ global regular_user3
+ regular_user3 = get_user( 'test3(a)bx.psu.edu' )
+ assert regular_user3 is not None, 'Problem retrieving user with email "test3(a)bx.psu.edu" from the database'
+ global regular_user3_private_role
+ regular_user3_private_role = get_private_role( regular_user3 )
+ self.logout()
+ self.login( email='test(a)bx.psu.edu', username='admin-user' )
+ global admin_user
+ admin_user = get_user( 'test(a)bx.psu.edu' )
+ assert admin_user is not None, 'Problem retrieving user with email "test(a)bx.psu.edu" from the database'
+ global admin_user_private_role
+ admin_user_private_role = get_private_role( admin_user )
+ def test_005_create_required_groups_and_roles( self ):
+ """Testing creating all required groups and roles for this script"""
+ # Logged in as admin_user
+ # Create role_one
+ name = 'Role One'
+ description = "This is Role One's description"
+ user_ids = [ str( admin_user.id ), str( regular_user1.id ), str( regular_user3.id ) ]
+ self.create_role( name=name,
+ description=description,
+ in_user_ids=user_ids,
+ in_group_ids=[],
+ create_group_for_role='no',
+ private_role=admin_user.email )
+ # Get the role object for later tests
+ global role_one
+ role_one = get_role_by_name( name )
+ # Create group_one
+ name = 'Group One'
+ self.create_group( name=name, in_user_ids=[ str( regular_user1.id ) ], in_role_ids=[ str( role_one.id ) ] )
+ # Get the group object for later tests
+ global group_one
+ group_one = get_group_by_name( name )
+ assert group_one is not None, 'Problem retrieving group named "Group One" from the database'
+ # NOTE: To get this to work with twill, all select lists on the ~/admin/role page must contain at least
+ # 1 option value or twill throws an exception, which is: ParseError: OPTION outside of SELECT
+ # Due to this bug in twill, we create the role, we bypass the page and visit the URL in the
+ # associate_users_and_groups_with_role() method.
+ #
+ #create role_two
+ name = 'Role Two'
+ description = 'This is Role Two'
+ user_ids = [ str( admin_user.id ) ]
+ group_ids = [ str( group_one.id ) ]
+ private_role = admin_user.email
+ self.create_role( name=name,
+ description=description,
+ in_user_ids=user_ids,
+ in_group_ids=group_ids,
+ private_role=private_role )
+ # Get the role object for later tests
+ global role_two
+ role_two = get_role_by_name( name )
+ assert role_two is not None, 'Problem retrieving role named "Role Two" from the database'
+ def test_010_create_request_form( self ):
+ """Testing creating a request form definition, editing the name and description and adding fields"""
+ # Logged in as admin_user
+ # Create a form definition
+ tmp_name = "Temp form"
+ tmp_desc = "Temp form description"
+ form_type = galaxy.model.FormDefinition.types.REQUEST
+ self.create_form( name=tmp_name,
+ desc=tmp_desc,
+ form_type=form_type,
+ num_fields=0,
+ strings_displayed=[ 'Create a new form definition' ],
+ strings_displayed_after_submit=[ tmp_name, tmp_desc, form_type ] )
+ tmp_form = get_form( tmp_name )
+ # Edit the name and description of the form definition, and add 3 fields.
+ new_name = "Request Form"
+ new_desc = "Request Form description"
+ global test_field_name1
+ test_field_name1 = 'Test field name one'
+ global test_field_name2
+ test_field_name2 = 'Test field name two'
+ global test_field_name3
+ test_field_name3 = 'Test field name three'
+ field_dicts = [ dict( name=test_field_name1,
+ desc='Test field description one',
+ type='SelectField',
+ required='optional',
+ selectlist=[ 'option1', 'option2' ] ),
+ dict( name=test_field_name2,
+ desc='Test field description two',
+ type='AddressField',
+ required='optional' ),
+ dict( name=test_field_name3,
+ desc='Test field description three',
+ type='TextField',
+ required='required' ) ]
+ self.edit_form( id=self.security.encode_id( tmp_form.current.id ),
+ new_form_name=new_name,
+ new_form_desc=new_desc,
+ field_dicts=field_dicts,
+ field_index=len( tmp_form.fields ),
+ strings_displayed=[ 'Edit form definition "%s"' % tmp_name ],
+ strings_displayed_after_submit=[ "The form '%s' has been updated with the changes." % new_name ] )
+ # Get the form_definition object for later tests
+ global form_one
+ form_one = get_form( new_name )
+ assert form_one is not None, 'Problem retrieving form named "%s" from the database' % new_name
+ assert len( form_one.fields ) == len( tmp_form.fields ) + len( field_dicts )
+ def test_015_create_sample_form( self ):
+ """Testing creating sample form definition"""
+ name = "Sample Form"
+ desc = "This is Form Two's description"
+ form_type = galaxy.model.FormDefinition.types.SAMPLE
+ form_layout_name = 'Layout Grid One'
+ self.create_form( name=name,
+ desc=desc,
+ form_type=form_type,
+ form_layout_name=form_layout_name,
+ strings_displayed=[ 'Create a new form definition' ],
+ strings_displayed_after_submit=[ "The form '%s' has been updated with the changes." % name ] )
+ global form_two
+ form_two = get_form( name )
+ assert form_two is not None, "Error retrieving form %s from db" % name
+ def test_020_create_request_type( self ):
+ """Testing creating a request_type"""
+ request_form = get_form( form_one.name )
+ sample_form = get_form( form_two.name )
+ name = 'Test Requestype'
+ self.create_request_type( name,
+ "test sequencer configuration",
+ self.security.encode_id( request_form.id ),
+ self.security.encode_id( sample_form.id ),
+ sample_states,
+ strings_displayed=[ 'Create a new sequencer configuration' ],
+ strings_displayed_after_submit=[ "Sequencer configuration (%s) has been created" % name ] )
+ global request_type1
+ request_type1 = get_request_type_by_name( name )
+ assert request_type1 is not None, 'Problem retrieving sequencer configuration named "%s" from the database' % name
+ # Set permissions
+ permissions_in = [ k for k, v in galaxy.model.RequestType.permitted_actions.items() ]
+ permissions_out = []
+ # Role one members are: admin_user, regular_user1, regular_user3. Each of these users will be permitted for
+ # REQUEST_TYPE_ACCESS on this request_type
+ self.request_type_permissions( self.security.encode_id( request_type1.id ),
+ request_type1.name,
+ str( role_one.id ),
+ permissions_in,
+ permissions_out )
+ # Make sure the request_type1 is not accessible by regular_user2 since regular_user2 does not have Role1.
+ self.logout()
+ self.login( email=regular_user2.email )
+ self.visit_url( '%s/requests_common/create_request?cntrller=requests&request_type=True' % self.url )
+ try:
+ self.check_page_for_string( 'There are no sequencer configurations created for a new request.' )
+ raise AssertionError, 'The request_type %s is accessible by %s when it should be restricted' % ( request_type1.name, regular_user2.email )
+ except:
+ pass
+ self.logout()
+ self.login( email=admin_user.email )
+ def test_025_create_request( self ):
+ """Testing creating a sequence run request"""
+ # logged in as admin_user
+ # Create a user_address
+ self.logout()
+ self.login( email=regular_user1.email )
+ self.add_user_address( regular_user1.id, address_dict )
+ global user_address1
+ user_address1 = get_user_address( regular_user1, address_dict[ 'short_desc' ] )
+ # Set field values - the tuples in the field_values list include the field_value, and True if refresh_on_change
+ # is required for that field.
+ field_value_tuples = [ ( 'option1', False ), ( str( user_address1.id ), True ), ( 'field three value', False ) ]
+ # Create the request
+ name = 'Request One'
+ desc = 'Request One Description'
+ self.create_request( cntrller='requests',
+ request_type_id=self.security.encode_id( request_type1.id ),
+ name=name,
+ desc=desc,
+ field_value_tuples=field_value_tuples,
+ strings_displayed=[ 'Create a new sequencing request',
+ test_field_name1,
+ test_field_name2,
+ test_field_name3 ],
+ strings_displayed_after_submit=[ name, desc ] )
+ global request_one
+ request_one = get_request_by_name( name )
+ # Make sure the request's state is now set to NEW
+ assert request_one.state is not request_one.states.NEW, "The state of the request '%s' should be set to '%s'" \
+ % ( request_one.name, request_one.states.NEW )
+ # Sample fields - the tuple represents a sample name and a list of sample form field values
+ sample_value_tuples = [ ( 'Sample One', [ 'S1 Field 0 Value' ] ),
+ ( 'Sample Two', [ 'S2 Field 0 Value' ] ) ]
+ strings_displayed_after_submit = [ 'Unsubmitted' ]
+ for sample_name, field_values in sample_value_tuples:
+ strings_displayed_after_submit.append( sample_name )
+ # Add samples to the request
+ self.add_samples( cntrller='requests',
+ request_id=self.security.encode_id( request_one.id ),
+ request_name=request_one.name,
+ sample_value_tuples=sample_value_tuples,
+ strings_displayed=[ 'There are no samples.' ],
+ strings_displayed_after_submit=strings_displayed_after_submit )
+ def test_030_edit_basic_request_info( self ):
+ """Testing editing the basic information of a sequence run request"""
+ # logged in as regular_user1
+ fields = [ 'option2', str( user_address1.id ), 'field three value (edited)' ]
+ new_name=request_one.name + ' (Renamed)'
+ new_desc=request_one.desc + ' (Re-described)'
+ self.edit_basic_request_info( request_id=self.security.encode_id( request_one.id ),
+ cntrller='requests',
+ name=request_one.name,
+ new_name=new_name,
+ new_desc=new_desc,
+ new_fields=fields,
+ strings_displayed=[ 'Edit sequencing request "%s"' % request_one.name ],
+ strings_displayed_after_submit=[ new_name, new_desc ] )
+ refresh( request_one )
+ # check if the request is showing in the 'new' filter
+ self.check_request_grid( cntrller='requests',
+ state=request_one.states.NEW,
+ strings_displayed=[ request_one.name ] )
+ def test_035_submit_request( self ):
+ """Testing editing a sequence run request"""
+ # logged in as regular_user1
+ self.submit_request( cntrller='requests',
+ request_id=self.security.encode_id( request_one.id ),
+ request_name=request_one.name,
+ strings_displayed_after_submit=[ 'The request has been submitted.' ] )
+ refresh( request_one )
+ # Make sure the request is showing in the 'submitted' filter
+ self.check_request_grid( cntrller='requests',
+ state=request_one.states.SUBMITTED,
+ strings_displayed=[ request_one.name ] )
+ # Make sure the request's state is now set to 'submitted'
+ assert request_one.state is not request_one.states.SUBMITTED, "The state of the request '%s' should be set to '%s'" \
+ % ( request_one.name, request_one.states.SUBMITTED )
+ def test_040_request_lifecycle( self ):
+ """Testing request life-cycle as it goes through all the states"""
+ # logged in as regular_user1
+ self.logout()
+ self.login( email=admin_user.email )
+ self.check_request_grid( cntrller='requests_admin',
+ state=request_one.states.SUBMITTED,
+ strings_displayed=[ request_one.name ] )
+ self.visit_url( "%s/requests_common/view_request?cntrller=requests&id=%s" % ( self.url, self.security.encode_id( request_one.id ) ) )
+ # TODO: add some string for checking on the page above...
+ # Set bar codes for the samples
+ bar_codes = [ '1234567890', '0987654321' ]
+ strings_displayed_after_submit=[ 'Changes made to the samples have been saved.' ]
+ for bar_code in bar_codes:
+ strings_displayed_after_submit.append( bar_code )
+ self.add_bar_codes( request_id=self.security.encode_id( request_one.id ),
+ request_name=request_one.name,
+ bar_codes=bar_codes,
+ samples=request_one.samples,
+ strings_displayed_after_submit=strings_displayed_after_submit )
+ # Change the states of all the samples of this request to ultimately be COMPLETE
+ self.change_sample_state( request_id=self.security.encode_id( request_one.id ),
+ request_name=request_one.name,
+ sample_names=[ sample.name for sample in request_one.samples ],
+ sample_ids=[ sample.id for sample in request_one.samples ],
+ new_sample_state_id=request_type1.states[1].id,
+ new_state_name=request_type1.states[1].name )
+ self.change_sample_state( request_id=self.security.encode_id( request_one.id ),
+ request_name=request_one.name,
+ sample_names=[ sample.name for sample in request_one.samples ],
+ sample_ids=[ sample.id for sample in request_one.samples ],
+ new_sample_state_id=request_type1.states[2].id,
+ new_state_name=request_type1.states[2].name )
+ refresh( request_one )
+ self.logout()
+ self.login( email=regular_user1.email )
+ # check if the request's state is now set to 'complete'
+ self.check_request_grid( cntrller='requests',
+ state='Complete',
+ strings_displayed=[ request_one.name ] )
+ assert request_one.state is not request_one.states.COMPLETE, "The state of the request '%s' should be set to '%s'" \
+ % ( request_one.name, request_one.states.COMPLETE )
+
+ def test_045_admin_create_request_on_behalf_of_regular_user( self ):
+ """Testing creating and submitting a request as an admin on behalf of a regular user"""
+ # Logged in as regular_user1
+ self.logout()
+ self.login( email=admin_user.email )
+ # Create the request
+ name = "RequestTwo"
+ desc = 'Request Two Description'
+ # Set field values - the tuples in the field_values list include the field_value, and True if refresh_on_change
+ # is required for that field.
+ field_value_tuples = [ ( 'option2', False ), ( str( user_address1.id ), True ), ( 'field_2_value', False ) ]
+ self.create_request( cntrller='requests_admin',
+ request_type_id=self.security.encode_id( request_type1.id ),
+ other_users_id=self.security.encode_id( regular_user1.id ),
+ name=name,
+ desc=desc,
+ field_value_tuples=field_value_tuples,
+ strings_displayed=[ 'Create a new sequencing request',
+ test_field_name1,
+ test_field_name2,
+ test_field_name3 ],
+ strings_displayed_after_submit=[ "The request has been created." ] )
+ global request_two
+ request_two = get_request_by_name( name )
+ # Make sure the request is showing in the 'new' filter
+ self.check_request_grid( cntrller='requests_admin',
+ state=request_two.states.NEW,
+ strings_displayed=[ request_two.name ] )
+ # Make sure the request's state is now set to 'new'
+ assert request_two.state is not request_two.states.NEW, "The state of the request '%s' should be set to '%s'" \
+ % ( request_two.name, request_two.states.NEW )
+ # Sample fields - the tuple represents a sample name and a list of sample form field values
+ sample_value_tuples = [ ( 'Sample One', [ 'S1 Field 0 Value' ] ),
+ ( 'Sample Two', [ 'S2 Field 0 Value' ] ) ]
+ strings_displayed_after_submit = [ 'Unsubmitted' ]
+ for sample_name, field_values in sample_value_tuples:
+ strings_displayed_after_submit.append( sample_name )
+ # Add samples to the request
+ self.add_samples( cntrller='requests_admin',
+ request_id=self.security.encode_id( request_two.id ),
+ request_name=request_two.name,
+ sample_value_tuples=sample_value_tuples,
+ strings_displayed=[ 'There are no samples.' ],
+ strings_displayed_after_submit=strings_displayed_after_submit )
+ # Submit the request
+ self.submit_request( cntrller='requests_admin',
+ request_id=self.security.encode_id( request_two.id ),
+ request_name=request_two.name,
+ strings_displayed_after_submit=[ 'The request has been submitted.' ] )
+ refresh( request_two )
+ # Make sure the request is showing in the 'submitted' filter
+ self.check_request_grid( cntrller='requests_admin',
+ state=request_two.states.SUBMITTED,
+ strings_displayed=[ request_two.name ] )
+ # Make sure the request's state is now set to 'submitted'
+ assert request_two.state is not request_two.states.SUBMITTED, "The state of the request '%s' should be set to '%s'" \
+ % ( request_two.name, request_two.states.SUBMITTED )
+ # Make sure both requests are showing in the 'All' filter
+ self.check_request_grid( cntrller='requests_admin',
+ state='All',
+ strings_displayed=[ request_one.name, request_two.name ] )
+ def test_050_reject_request( self ):
+ """Testing rejecting a request"""
+ # Logged in as admin_user
+ self.reject_request( request_id=self.security.encode_id( request_two.id ),
+ request_name=request_two.name,
+ comment="Rejection test comment",
+ strings_displayed=[ 'Reject Sequencing Request "%s"' % request_two.name ],
+ strings_displayed_after_submit=[ 'Request (%s) has been rejected.' % request_two.name ] )
+ refresh( request_two )
+ # Make sure the request is showing in the 'rejected' filter
+ self.check_request_grid( cntrller='requests_admin',
+ state=request_two.states.REJECTED,
+ strings_displayed=[ request_two.name ] )
+ # Make sure the request's state is now set to REJECTED
+ assert request_two.state is not request_two.states.REJECTED, "The state of the request '%s' should be set to '%s'" \
+ % ( request_two.name, request_two.states.REJECTED )
+ def test_055_reset_data_for_later_test_runs( self ):
+ """Reseting data to enable later test runs to pass"""
+ # Logged in as admin_user
+ ##################
+ # Delete request_type permissions
+ ##################
+ for request_type in [ request_type1 ]:
+ delete_request_type_permissions( request_type.id )
+ ##################
+ # Mark all request_types deleted
+ ##################
+ for request_type in [ request_type1 ]:
+ mark_obj_deleted( request_type )
+ ##################
+ # Mark all requests deleted
+ ##################
+ for request in [ request_one, request_two ]:
+ mark_obj_deleted( request )
+ ##################
+ # Mark all forms deleted
+ ##################
+ for form in [ form_one, form_two ]:
+ self.mark_form_deleted( self.security.encode_id( form.current.id ) )
+ ##################
+ # Mark all user_addresses deleted
+ ##################
+ for user_address in [ user_address1 ]:
+ mark_obj_deleted( user_address )
+ ##################
+ # Delete all non-private roles
+ ##################
+ for role in [ role_one, role_two ]:
+ self.mark_role_deleted( self.security.encode_id( role.id ), role.name )
+ self.purge_role( self.security.encode_id( role.id ), role.name )
+ # Manually delete the role from the database
+ refresh( role )
+ delete( role )
+ ##################
+ # Delete all groups
+ ##################
+ for group in [ group_one ]:
+ self.mark_group_deleted( self.security.encode_id( group.id ), group.name )
+ self.purge_group( self.security.encode_id( group.id ), group.name )
+ # Manually delete the group from the database
+ refresh( group )
+ delete( group )
--- a/templates/requests/common/common.mako
+++ b/templates/requests/common/common.mako
@@ -65,12 +65,60 @@
}
}
}
+
+ // Looks for changes in sample states using an async request. Keeps
+ // calling itself (via setTimeout) until all samples are in a terminal
+ // state.
+ var updater = function ( sample_states ) {
+ // Check if there are any items left to track
+ var empty = true;
+ for ( i in sample_states ) {
+ empty = false;
+ break;
+ }
+ if ( ! empty ) {
+ setTimeout( function() { updater_callback( sample_states ) }, 1000 );
+ }
+ };
+
+ var updater_callback = function ( sample_states ) {
+ // Build request data
+ var ids = []
+ var states = []
+ $.each( sample_states, function ( id, state ) {
+ ids.push( id );
+ states.push( state );
+ });
+ // Make ajax call
+ $.ajax( {
+ type: "POST",
+ url: "${h.url_for( controller='requests_common', action='sample_state_updates' )}",
+ dataType: "json",
+ data: { ids: ids.join( "," ), states: states.join( "," ) },
+ success : function ( data ) {
+ $.each( data, function( id, val ) {
+ // Replace HTML
+ var cell1 = $("#sampleState-" + id);
+ cell1.html( val.html_state );
+ var cell2 = $("#sampleDatasets-" + id);
+ cell2.html( val.html_datasets );
+ sample_states[ parseInt( id ) ] = val.state;
+ });
+ updater( sample_states );
+ },
+ error: function() {
+ // Just retry, like the old method, should try to be smarter
+ updater( sample_states );
+ }
+ });
+ };
</script></%def><%def name="render_editable_sample_row( is_admin, sample, current_sample_index, current_sample, encoded_selected_sample_ids )"><%
if sample:
+ trans.sa_session.refresh( sample.request )
is_complete = sample.request.is_complete
is_submitted = sample.request.is_submitted
is_unsubmitted = sample.request.is_unsubmitted
@@ -80,12 +128,12 @@
is_unsubmitted = False
%><%
- if is_admin and is_submitted and editing_samples and trans.security.encode_id( sample.id ) in encoded_selected_sample_ids:
+ if is_submitted and editing_samples and trans.security.encode_id( sample.id ) in encoded_selected_sample_ids:
checked_str = "checked"
else:
checked_str = ""
%>
- %if is_admin and is_submitted and editing_samples:
+ %if is_submitted and editing_samples:
<td><input type="checkbox" name=select_sample_${sample.id} id="sample_checkbox" value="true" ${checked_str}/><input type="hidden" name=select_sample_${sample.id} id="sample_checkbox" value="true"/></td>
%endif
<td valign="top">
@@ -95,7 +143,11 @@
</div></td>
%if sample and is_submitted or is_complete:
- <td valign="top"><input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/></td>
+ %if is_admin:
+ <td valign="top"><input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/></td>
+ %else:
+ ${current_sample['barcode']}
+ %endif
%endif
%if sample:
%if is_unsubmitted:
@@ -118,7 +170,7 @@
<td valign="top"><a href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${label}</a></td><td valign="top"><a href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${label}</a></td>
%endif
- %if sample and ( is_admin or is_unsubmitted ):
+ %if sample and ( is_admin or is_unsubmitted ) and not is_complete:
## Delete button
<td valign="top"><a class="action-button" href="${h.url_for( controller='requests_common', action='delete_sample', cntrller=cntrller, request_id=trans.security.encode_id( request.id ), sample_id=current_sample_index )}"><img src="${h.url_for('/static/images/delete_icon.png')}" style="cursor:pointer;"/></a></td>
%endif
@@ -127,20 +179,22 @@
<%def name="render_samples_grid( cntrller, request, current_samples, action, editing_samples=False, encoded_selected_sample_ids=[], render_buttons=False, grid_header='<h3>Samples</h3>' )">
## Displays the "Samples" grid
<%
+ trans.sa_session.refresh( request )
is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
is_complete = request.is_complete
is_submitted = request.is_submitted
is_unsubmitted = request.is_unsubmitted
can_add_samples = request.is_unsubmitted
- can_edit_or_delete_samples = request.samples and not is_complete
+ can_delete_samples = request.samples and not is_complete
+ can_edit_samples = request.samples and ( is_admin or not is_complete )
%>
${grid_header}
- %if render_buttons and ( can_add_samples or can_edit_or_delete_samples ):
+ %if render_buttons and ( can_add_samples or can_edit_samples ):
<ul class="manage-table-actions">
%if can_add_samples:
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='add_sample', cntrller=cntrller, request_id=trans.security.encode_id( request.id ), add_sample_button='Add sample' )}">Add sample</a></li>
%endif
- %if can_edit_or_delete_samples:
+ %if can_edit_samples:
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='edit_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ), editing_samples='True' )}">Edit samples</a></li>
%endif
</ul>
@@ -148,7 +202,7 @@
<table class="grid"><thead><tr>
- %if is_admin and is_submitted and editing_samples:
+ %if is_submitted and editing_samples:
<th><input type="checkbox" id="checkAll" name=select_all_samples_checkbox value="true" onclick='checkAllFields(1);'/><input type="hidden" name=select_all_samples_checkbox value="true"/></th>
%endif
<th>Name</th>
@@ -191,7 +245,7 @@
except:
sample = None
%>
- %if editing_samples:
+ %if not is_complete and editing_samples:
<tr>${render_editable_sample_row( is_admin, sample, current_sample_index, current_sample, encoded_selected_sample_ids )}</tr>
%elif sample:
<tr>
@@ -220,6 +274,7 @@
%endif
</tr>
%else:
+ ## The Add sample button was clicked for this sample_widget
<tr>${render_editable_sample_row( is_admin, None, current_sample_index, current_sample, encoded_selected_sample_ids )}</tr>
%endif
%endfor
@@ -231,9 +286,7 @@
<tr><td>${sample_name}</td>
%for field_index, field in fields_dict.items():
- <%
- field_type = field[ 'type' ]
- %>
+ <% field_type = field[ 'type' ] %><td>
%if display_only:
%if sample_values[field_index]:
--- a/templates/requests/common/view_request.mako
+++ b/templates/requests/common/view_request.mako
@@ -22,7 +22,8 @@
is_unsubmitted = request.is_unsubmitted
can_edit_request = ( is_admin and not request.is_complete ) or request.is_unsubmitted
can_add_samples = is_unsubmitted
- can_edit_or_delete_samples = request.samples and not is_complete
+ can_delete_samples = request.samples and not is_complete
+ can_edit_samples = request.samples and ( is_admin or not is_complete )
can_submit = request.samples and is_unsubmitted
%>
@@ -131,14 +132,23 @@
${states}
<div style="clear: both"></div></div>
+ %if request.samples and request.is_submitted:
+ <script type="text/javascript">
+ // Updater
+ updater( {${ ",".join( [ '"%s" : "%s"' % ( s.id, s.state.name ) for s in request.samples ] ) }});
+ </script>
+ %endif
</div></div></div></div><p/>
%if current_samples:
- <% grid_header = '<h3>Samples</h3>' %>
- ${render_samples_grid( cntrller, request, current_samples=current_samples, action='view_request', editing_samples=False, encoded_selected_sample_ids=[], render_buttons=can_edit_or_delete_samples, grid_header=grid_header )}
+ <%
+ grid_header = '<h3>Samples</h3>'
+ render_buttons = can_edit_samples
+ %>
+ ${render_samples_grid( cntrller, request, current_samples=current_samples, action='view_request', editing_samples=False, encoded_selected_sample_ids=[], render_buttons=render_buttons, grid_header=grid_header )}
%else:
There are no samples.
%if can_add_samples:
1
0
galaxy-dist commit 4053c425b536: No longer pre-generate menus on page load for popup-style menus. Instead, create menu dynamically when needed, greatly improving load time especially on data libraries with large number of potential menus.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1288748718 14400
# Node ID 4053c425b536b9878f6f8bdfac75453adec7bdf3
# Parent e000a6800e1cbfa15a190bb2aff90a5956882a43
No longer pre-generate menus on page load for popup-style menus. Instead, create menu dynamically when needed, greatly improving load time especially on data libraries with large number of potential menus.
Remove the creation of a background element that closes the active menu clicked. Instead, bind an event to close active menus to the document object of current and all other framesets. Tested in IE.
Update Tool Search/Recently Used code to reflect new changes.
Made some small tweaks to pass JSlint
--- a/templates/root/index.mako
+++ b/templates/root/index.mako
@@ -46,10 +46,8 @@
"Export to File": function() {
galaxy_main.location = "${h.url_for( controller='history', action='export_archive' )}";
},
- "Delete": function()
- {
- if ( confirm( "Really delete the current history?" ) )
- {
+ "Delete": function() {
+ if ( confirm( "Really delete the current history?" ) ) {
galaxy_main.location = "${h.url_for( controller='history', action='delete_current' )}";
}
},
@@ -59,98 +57,108 @@
}
});
+ var menu_options = {}; // Holds dictionary of { label: toggle_fn }
+
+ SHOW_TOOL = "Show Tool Search";
+ HIDE_TOOL = "Hide Tool Search";
+ SHOW_RECENT = "Show Recently Used";
+ HIDE_RECENT = "Hide Recently Used";
+
+ var toggle_tool_search_fn = function() {
+ // Show/hide menu and update vars, user preferences.
+ var menu = $("#galaxy_tools").contents().find('#tool-search'),
+ pref_value, menu_option_text, old_text;
+ if (menu.is(":visible")) {
+ // Hide menu.
+ pref_value = "False";
+ menu_option_text = SHOW_TOOL;
+ old_text = HIDE_TOOL;
+
+ // Reset search.
+ reset_tool_search(true);
+ } else {
+ // Show menu.
+ pref_value = "True";
+ menu_option_text = HIDE_TOOL;
+ old_text = SHOW_TOOL;
+ }
+ menu.toggle();
+
+ // Update menu option.
+ delete menu_options[old_text];
+ menu_options[menu_option_text] = toggle_tool_search_fn;
+ make_popupmenu( $("#tools-options-button"), menu_options );
+ galaxy_async.set_user_pref("show_tool_search", pref_value);
+ };
+
+ var toggle_recently_used_fn = function() {
+ // Show/hide menu.
+ var ru_menu = $('#galaxy_tools').contents().find('#recently_used_wrapper'),
+ ru_menu_body = ru_menu.find(".toolSectionBody"),
+ pref_value, old_text, menu_option_text;
+ if (ru_menu.hasClass("user_pref_visible")) {
+ // Hide menu.
+ ru_menu_body.slideUp();
+ ru_menu.slideUp();
+
+ // Set vars used below and in tool menu frame.
+ pref_value = "False";
+ old_text = HIDE_RECENT;
+ menu_option_text = SHOW_RECENT;
+ } else {
+ // "Show" menu.
+ if (!$('#galaxy_tools').contents().find('#tool-search-query').hasClass("search_active")) {
+ // Default.
+ ru_menu.slideDown();
+ } else {
+ // Search active: tf there are matching tools in RU menu, show menu.
+ if ( ru_menu.find(".toolTitle.search_match").length !== 0 ) {
+ ru_menu.slideDown();
+ ru_menu_body.slideDown();
+ }
+ }
+ // Set vars used below and in tool menu frame.
+ pref_value = "True";
+ old_text = SHOW_RECENT;
+ menu_option_text = HIDE_RECENT;
+ }
+
+ // Update menu class and option.
+ ru_menu.toggleClass("user_pref_hidden user_pref_visible");
+ delete menu_options[old_text];
+ menu_options[menu_option_text] = toggle_recently_used_fn;
+ make_popupmenu( $("#tools-options-button"), menu_options );
+ galaxy_async.set_user_pref("show_recently_used_menu", pref_value);
+ };
+
// Init tool options.
- make_popupmenu( $("#tools-options-button"), {
- ## Search tools menu item.
- %if trans.app.toolbox_search.enabled:
- <%
- show_tool_search = False
- if trans.user:
- show_tool_search = trans.user.preferences.get( "show_tool_search", "False" )
-
- if show_tool_search == "True":
- initial_text = "Hide Search"
- else:
- initial_text = "Search Tools"
- %>
- "${initial_text}": function() {
- // Show/hide menu and update vars, user preferences.
- var menu = $("#galaxy_tools").contents().find('#tool-search');
- if (menu.is(":visible"))
- {
- // Hide menu.
- pref_value = "False";
- menu_option_text = "Search Tools";
- menu.toggle();
-
- // Reset search.
- reset_tool_search(true);
- }
- else
- {
- // Show menu.
- pref_value = "True";
- menu_option_text = "Hide Search";
- menu.toggle();
- }
-
- // Update menu option.
- $("#tools-options-button-menu").find("li").eq(0).text(menu_option_text);
-
- galaxy_async.set_user_pref("show_tool_search", pref_value);
- },
- %endif
- ## Recently used tools menu.
- %if trans.user:
- <%
- if trans.user.preferences.get( 'show_recently_used_menu', 'False' ) == 'True':
- action = "Hide"
- else:
- action = "Show"
- %>
- "${action} Recently Used": function() {
- // Show/hide menu.
- var ru_menu = $('#galaxy_tools').contents().find('#recently_used_wrapper');
- var ru_menu_body = ru_menu.find(".toolSectionBody");
- var pref_value = null;
- var menu_option_text = null;
- if (ru_menu.hasClass("user_pref_visible"))
- {
- // Hide menu.
- ru_menu_body.slideUp();
- ru_menu.slideUp();
-
- // Set vars used below and in tool menu frame.
- pref_value = "False";
- menu_option_text = "Show Recently Used";
- }
- else
- {
- // "Show" menu.
- if (!$('#galaxy_tools').contents().find('#tool-search-query').hasClass("search_active"))
- // Default.
- ru_menu.slideDown();
- else
- // Search active: tf there are matching tools in RU menu, show menu.
- if ( ru_menu.find(".toolTitle.search_match").length != 0 )
- {
- ru_menu.slideDown();
- ru_menu_body.slideDown();
- }
-
- // Set vars used below and in tool menu frame.
- pref_value = "True";
- menu_option_text = "Hide Recently Used";
- }
-
- // Update menu class and option.
- ru_menu.toggleClass("user_pref_hidden user_pref_visible");
- $("#tools-options-button-menu").find("li").eq(1).text(menu_option_text);
-
- galaxy_async.set_user_pref("show_recently_used_menu", pref_value);
- }
- %endif
- });
+ ## Search tools menu item.
+ %if trans.app.toolbox_search.enabled:
+ <%
+ show_tool_search = False
+ if trans.user:
+ show_tool_search = trans.user.preferences.get( "show_tool_search", "False" )
+
+ if show_tool_search == "True":
+ action = "HIDE_TOOL"
+ else:
+ action = "SHOW_TOOL"
+ %>
+ menu_options[ ${action} ] = toggle_tool_search_fn;
+ %endif
+ ## Recently used tools menu.
+ %if trans.user:
+ <%
+ if trans.user.preferences.get( 'show_recently_used_menu', 'False' ) == 'True':
+ action = "HIDE_RECENT"
+ else:
+ action = "SHOW_RECENT"
+ %>
+ menu_options[ ${action} ] = toggle_recently_used_fn;
+ %endif
+
+
+ make_popupmenu( $("#tools-options-button"), menu_options );
});
</script></%def>
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -7,7 +7,7 @@ if (!Array.indexOf) {
}
}
return -1;
- }
+ };
}
// Returns the number of keys (elements) in an array/dictionary.
@@ -39,93 +39,89 @@ function obj_length(obj) {
});
};
-function ensure_popup_helper() {
- // And the helper below the popup menus
- if ( $( "#popup-helper" ).length === 0 ) {
- $( "<div id='popup-helper'/>" ).css( {
- background: 'white', opacity: 0, zIndex: 15000,
- position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'
- } ).appendTo( "body" ).hide();
- }
-}
-
-function attach_popupmenu( button_element, wrapper ) {
- var clean = function() {
- wrapper.unbind().hide();
- $("#popup-helper").unbind( "click.popupmenu" ).hide();
- // $(document).unbind( "click.popupmenu" );
- };
- var click_handler = function( e ) {
- // var o = $(button_element).offset();
- $("#popup-helper").bind( "click.popupmenu", clean ).show();
- // $(document).bind( "click.popupmenu", clean );
- // Show off screen to get size right
- wrapper.click( clean ).css( { left: 0, top: -1000 } ).show();
- // console.log( e.pageX, $(document).scrollLeft() + $(window).width(), $(menu_element).width() );
- var x = e.pageX - wrapper.width() / 2 ;
- x = Math.min( x, $(document).scrollLeft() + $(window).width() - $(wrapper).width() - 20 );
- x = Math.max( x, $(document).scrollLeft() + 20 );
- // console.log( e.pageX, $(document).scrollLeft() + $(window).width(), $(menu_element).width() );
-
-
- wrapper.css( {
- top: e.pageY - 5,
- left: x
- } );
- return false;
- };
- $(button_element).bind("click", click_handler);
+// Toggle popup menu options using regular expression on option names.
+function show_hide_popupmenu_options( menu, option_name_re, show ) {
+ show = (show === undefined ? true : show );
+ var re = new RegExp(option_name_re);
+ $(menu).find("li").each( function() {
+ if ( re.exec($(this).text()) ) {
+ if (show) {
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ }
+ });
}
function make_popupmenu( button_element, options ) {
- ensure_popup_helper();
- // var container_element = $(button_element);
- // if ( container_element.parent().hasClass( "combo-button" ) ) {
- // container_element = container_element.parent();
- // }
- // container_element).css( "position", "relative" );
- var menu_element = $( "<ul id='" + button_element.attr('id') + "-menu'></ul>" );
- if (obj_length(options) <= 0) {
- $("<li/>").html("No options").appendTo(menu_element);
- }
- $.each( options, function( k, v ) {
- if (v) {
- $("<li/>").html(k).click(v).appendTo(menu_element);
- } else {
- $("<li class='head'/>").html(k).appendTo(menu_element);
- }
+ button_element.bind("click.show_popup", function(e) {
+ // Close existing visible menus
+ $(".popmenu-wrapper").remove();
+
+
+ // Need setTimeouts so clicks don't interfere with each other
+ setTimeout( function() {
+ // Dynamically generate the wrapper holding all the selectable options of the menu.
+ var menu_element = $( "<ul id='" + button_element.attr('id') + "-menu'></ul>" );
+ if (obj_length(options) <= 0) {
+ $("<li>No Options.</li>").appendTo(menu_element);
+ }
+ $.each( options, function( k, v ) {
+ if (v) {
+ $("<li/>").html(k).click(v).appendTo(menu_element);
+ } else {
+ $("<li class='head'/>").html(k).appendTo(menu_element);
+ }
+ });
+ var wrapper = $( "<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'>" );
+ wrapper.append( menu_element )
+ .append( "<div class='overlay-border'>" )
+ .appendTo( "body" );
+
+ var x = e.pageX - wrapper.width() / 2 ;
+ x = Math.min( x, $(document).scrollLeft() + $(window).width() - $(wrapper).width() - 20 );
+ x = Math.max( x, $(document).scrollLeft() + 20 );
+
+ wrapper.css( {
+ top: e.pageY - 5,
+ left: x
+ } );
+ }, 10);
+
+ setTimeout( function() {
+ // Bind click event to current window and all frames to remove any visible menus
+ // Bind to document object instead of window object for IE compat
+ var close_popup = function(el) {
+ $(el).bind("click.close_popup", function() {
+ $(".popmenu-wrapper").remove();
+ el.unbind("click.close_popup");
+ });
+ };
+ close_popup( $(window.document) ); // Current frame
+ close_popup( $(window.top.document) ); // Parent frame
+ for (var frame_id = window.top.frames.length; frame_id--;) { // Sibling frames
+ var frame = $(window.top.frames[frame_id].document);
+ close_popup(frame);
+ }
+ }, 50);
+
+ return false;
});
- var wrapper = $( "<div class='popmenu-wrapper'>" );
- wrapper.append( menu_element )
- .append( "<div class='overlay-border'>" )
- .css( "position", "absolute" )
- .appendTo( "body" )
- .hide();
- attach_popupmenu( button_element, wrapper );
- return menu_element;
-}
-
-// Toggle popup menu options using regular expression on option names.
-function show_hide_popupmenu_options( menu, option_name_re, show ) {
- var show = (show === undefined ? true : show );
- var re = new RegExp(option_name_re);
- $(menu).find("li").each( function() {
- if ( re.exec( $(this).text() ) )
- if (show)
- $(this).show();
- else
- $(this).hide();
- });
+
}
function make_popup_menus() {
jQuery( "div[popupmenu]" ).each( function() {
var options = {};
- $(this).find( "a" ).each( function() {
- var confirmtext = $(this).attr( "confirm" ),
- href = $(this).attr( "href" ),
- target = $(this).attr( "target" );
- options[ $(this).text() ] = function() {
+ var menu = $(this);
+ menu.find( "a" ).each( function() {
+ var link = $(this),
+ link_dom = link.get(0);
+ var confirmtext = link_dom.getAttribute( "confirm" ),
+ href = link_dom.getAttribute( "href" ),
+ target = link_dom.getAttribute( "target" );
+ options[ link.text() ] = function() {
if ( !confirmtext || confirm( confirmtext ) ) {
var f = window;
if ( target == "_parent" ) {
@@ -137,14 +133,18 @@ function make_popup_menus() {
}
};
});
- var b = $( "#" + $(this).attr( 'popupmenu' ) );
- b.find("a").bind("click", function(e) {
+ var box = $( "#" + menu.attr( 'popupmenu' ) );
+
+ // For menus with clickable link text, make clicking on the link go through instead
+ // of activating the popup menu
+ box.find("a").bind("click", function(e) {
e.stopPropagation(); // Stop bubbling so clicking on the link goes through
return true;
});
- make_popupmenu( b, options );
- $(this).remove();
- b.addClass( "popup" ).show();
+
+ make_popupmenu(box, options);
+ box.addClass("popup");
+ menu.remove();
});
}
@@ -160,15 +160,17 @@ function naturalSort(a, b) {
xD = (new Date(x)).getTime(),
yD = xD ? (new Date(y)).getTime() : null;
// natural sorting of dates
- if ( yD )
- if ( xD < yD ) return -1;
- else if ( xD > yD ) return 1;
+ if ( yD ) {
+ if ( xD < yD ) { return -1; }
+ else if ( xD > yD ) { return 1; }
+ }
// natural sorting through split numeric strings and default strings
- for( var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++ ) {
+ var oFxNcL, oFyNcL;
+ for ( var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++ ) {
oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];
oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];
- if (oFxNcL < oFyNcL) return -1;
- else if (oFxNcL > oFyNcL) return 1;
+ if (oFxNcL < oFyNcL) { return -1; }
+ else if (oFxNcL > oFyNcL) { return 1; }
}
return 0;
}
@@ -176,14 +178,17 @@ function naturalSort(a, b) {
// Replace select box with a text input box + autocomplete.
function replace_big_select_inputs(min_length, max_length) {
// To do replace, jQuery's autocomplete plugin must be loaded.
- if (!jQuery().autocomplete)
+ if (!jQuery().autocomplete) {
return;
+ }
// Set default for min_length and max_length
- if (min_length === undefined)
+ if (min_length === undefined) {
min_length = 20;
- if (max_length === undefined)
+ }
+ if (max_length === undefined) {
max_length = 3000;
+ }
$('select').each( function() {
var select_elt = $(this);
@@ -194,7 +199,7 @@ function replace_big_select_inputs(min_l
}
// Skip multi-select because widget cannot handle multi-select.
- if (select_elt.attr('multiple') == true) {
+ if (select_elt.attr('multiple') === true) {
return;
}
@@ -240,13 +245,14 @@ function replace_big_select_inputs(min_l
});
// Set initial text if it's empty.
- if ( start_value == '' || start_value == '?') {
+ if ( start_value === '' || start_value === '?') {
text_input_elt.attr('value', 'Click to Search or Select');
}
// Sort dbkey options list only.
- if (select_elt.attr('name') == 'dbkey')
+ if (select_elt.attr('name') == 'dbkey') {
select_options = select_options.sort(naturalSort);
+ }
// Do autocomplete.
var autocomplete_options = { selectFirst: false, autoFill: false, mustMatch: false, matchContains: true, max: max_length, minChars : 0, hideForLessThanMinChars : false };
@@ -265,7 +271,7 @@ function replace_big_select_inputs(min_l
}
else {
// If there is a non-empty start value, use that; otherwise unknown.
- if (start_value != "") {
+ if (start_value !== "") {
text_input_elt.attr('value', start_value);
} else {
// This is needed to make the DB key work.
@@ -283,9 +289,9 @@ function replace_big_select_inputs(min_l
// Get refresh vals.
var ref_on_change_vals = select_elt.attr('refresh_on_change_values'),
last_selected_value = select_elt.attr("last_selected_value");
- if (ref_on_change_vals !== undefined)
+ if (ref_on_change_vals !== undefined) {
ref_on_change_vals = ref_on_change_vals.split(',');
-
+ }
// Function that attempts to refresh based on the value in the text element.
var try_refresh_fn = function() {
// Get new value and see if it can be matched.
@@ -371,10 +377,11 @@ function async_save_text(click_to_edit_e
},
success: function(processed_text) {
// Set new text and call finish method.
- if (processed_text != "")
+ if (processed_text !== "") {
text_elt.text(processed_text);
- else
+ } else {
text_elt.html("<em>None</em>");
+ }
if (on_finish) {
on_finish(t);
}
@@ -415,15 +422,16 @@ function init_history_items(historywrapp
// If Mozilla, hide scrollbars in hidden items since they cause animation bugs
if ( $.browser.mozilla ) {
$( "div.historyItemBody" ).each( function() {
- if ( ! $(this).is( ":visible" ) ) $(this).find( "pre.peek" ).css( "overflow", "hidden" );
- })
+ if ( !$(this).is(":visible") ) { $(this).find( "pre.peek" ).css( "overflow", "hidden" ); }
+ });
}
historywrapper.each( function() {
- var id = this.id;
- var body = $(this).children( "div.historyItemBody" );
- var peek = body.find( "pre.peek" )
+ var id = this.id,
+ body = $(this).children( "div.historyItemBody" ),
+ peek = body.find( "pre.peek" );
$(this).find( ".historyItemTitleBar > .historyItemTitle" ).wrap( "<a href='javascript:void(0);'></a>" ).click( function() {
+ var prefs;
if ( body.is(":visible") ) {
// Hiding stuff here
if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ); }
@@ -431,7 +439,7 @@ function init_history_items(historywrapp
if (!nochanges) { // Ignore embedded item actions
// Save setting
- var prefs = $.jStore.store("history_expand_state");
+ prefs = $.jStore.store("history_expand_state");
if (prefs) {
delete prefs[id];
$.jStore.store("history_expand_state", prefs);
@@ -445,7 +453,7 @@ function init_history_items(historywrapp
if (!nochanges) {
// Save setting
- var prefs = $.jStore.store("history_expand_state");
+ prefs = $.jStore.store("history_expand_state");
if (prefs === undefined) { prefs = {}; }
prefs[id] = true;
$.jStore.store("history_expand_state", prefs);
@@ -470,7 +478,7 @@ function init_history_items(historywrapp
});
$.jStore.store("history_expand_state", prefs);
}).show();
- }
+ };
if (noinit) {
action();
@@ -497,7 +505,7 @@ function reset_tool_search( initValue )
// Function may be called in top frame or in tool_menu_frame;
// in either case, get the tool menu frame.
var tool_menu_frame = $("#galaxy_tools").contents();
- if (tool_menu_frame.length == 0) {
+ if (tool_menu_frame.length === 0) {
tool_menu_frame = $(document);
}
@@ -532,7 +540,7 @@ function reset_tool_search( initValue )
var GalaxyAsync = function(log_action) {
this.url_dict = {};
this.log_action = (log_action === undefined ? false : log_action);
-}
+};
GalaxyAsync.prototype.set_func_url = function( func_name, url ) {
this.url_dict[func_name] = url;
@@ -566,36 +574,6 @@ GalaxyAsync.prototype.log_user_action =
});
};
-// Add to trackster browser functionality
-$(".trackster-add").live("click", function() {
- var dataset = this,
- dataset_jquery = $(this);
- $.ajax({
- url: dataset_jquery.attr("data-url"),
- dataType: "html",
- error: function() { alert( "Could not add this dataset to browser." ); },
- success: function(table_html) {
- var parent = window.parent;
- parent.show_modal("Add to Browser:", table_html, {
- "Cancel": function() {
- parent.hide_modal();
- },
- "Insert into selected": function() {
- $(parent.document).find('input[name=id]:checked').each(function() {
- var vis_id = $(this).val();
- parent.location = dataset_jquery.attr("action-url") + "&id=" + vis_id;
- });
- },
- "Insert into new browser": function() {
- parent.location = dataset_jquery.attr("new-url");
- }
- });
- }
- });
-});
-
-
-
$(document).ready( function() {
$("select[refresh_on_change='true']").change( function() {
var select_field = $(this),
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function ensure_popup_helper(){if($("#popup-helper").length===0){$("<div id='popup-helper'/>").css({background:"white",opacity:0,zIndex:15000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scr
ollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return false};$(b).bind("click",c)}function make_popupmenu(c,b){ensure_popup_helper();var a=$("<ul id='"+c.attr("id")+"-menu'></ul>");if(obj_length(b)<=0){$("<li/>").html("No options").appendTo(a)}$.each(b,function(f,e){if(e){$("<li/>").html(f).click(e).appendTo(a)}else{$("<li class='head'/>").html(f).appendTo(a)}});var d=$("<div class='popmenu-wrapper'>");d.append(a).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(c,d);return a}function show_hide_popupmenu_options(d,c,a){var a=(a===undefined?true:a);var b=new RegExp(c);$(d).find("li").each(function(){if(b.exec($(this).text())){if(a){$(this).show()}else{$(this).hide()}}})}function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("ta
rget");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=window.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));a.find("a").bind("click",function(b){b.stopPropagation();return true});make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}function naturalSort(i,g){var n=/(-?[0-9\.]+)/g,j=i.toString().toLowerCase()||"",f=g.toString().toLowerCase()||"",k=String.fromCharCode(0),l=j.replace(n,k+"$1"+k).split(k),e=f.replace(n,k+"$1"+k).split(k),d=(new Date(j)).getTime(),m=d?(new Date(f)).getTime():null;if(m){if(d<m){return -1}else{if(d>m){return 1}}}for(var h=0,c=Math.max(l.length,e.length);h<c;h++){oFxNcL=parseFloat(l[h])||l[h];oFyNcL=parseFloat(e[h])||e[h];if(oFxNcL<oFyNcL){return -1}else{if(oFxNcL>oFyNcL){return 1}}}return 0}function replace_big_select_inputs(a,b){if(!jQuery().autocomplete){return}if(a===undefined){a=20}if(b===undefined){b=3000}$("select").each(function(){var d=$(this);var
g=d.find("option").length;if((g<a)||(g>b)){return}if(d.attr("multiple")==true){return}if(d.hasClass("no-autocomplete")){return}var m=d.attr("value");var c=$("<input type='text' class='text-and-autocomplete-select'></input>");c.attr("size",40);c.attr("name",d.attr("name"));c.attr("id",d.attr("id"));c.click(function(){var n=$(this).val();$(this).val("Loading...");$(this).showAllInCache();$(this).val(n);$(this).select()});var e=[];var i={};d.children("option").each(function(){var o=$(this).text();var n=$(this).attr("value");e.push(o);i[o]=n;i[n]=n;if(n==m){c.attr("value",o)}});if(m==""||m=="?"){c.attr("value","Click to Search or Select")}if(d.attr("name")=="dbkey"){e=e.sort(naturalSort)}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:b,minChars:0,hideForLessThanMinChars:false};c.autocomplete(e,f);d.replaceWith(c);var k=function(){var o=c.attr("value");var n=i[o];if(n!==null&&n!==undefined){c.attr("value",n)}else{if(m!=""){c.attr("value",m)}else{c.
attr("value","?")}}};c.parents("form").submit(function(){k()});$(document).bind("convert_dbkeys",function(){k()});if(d.attr("refresh_on_change")=="true"){var h=d.attr("refresh_on_change_values"),l=d.attr("last_selected_value");if(h!==undefined){h=h.split(",")}var j=function(){var n=i[c.attr("value")];if(l!==n&&n!==null&&n!==undefined){if(h!==undefined&&$.inArray(n,h)===-1&&$.inArray(l,h)===-1){return}c.attr("value",n);$(window).trigger("refresh_on_change");c.parents("form").submit()}};c.bind("result",j);c.keyup(function(n){if(n.keyCode===13){j()}});c.keydown(function(n){if(n.keyCode===13){return false}})}})}function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).live("click",function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(
function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!=""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStore.store("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStore.remove("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id;var h=$(this).children("div.historyItemBody");var i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").cl
ick(function(){if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){var k=$.jStore.store("history_expand_state");if(k){delete k[j];$.jStore.store("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){var k=$.jStore.store("history_expand_state");if(k===undefined){k={}}k[j]=true;$.jStore.store("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStore.store("history_expand_state");if(h===undefined){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStore.store("history_expand_state",h)}).show()};if(a){b()}else{$.jStore.init("galaxy");$.jStore.engineReady(function(){b()})}}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function rese
t_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length==0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools");b.css("font-style","italic")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};Ga
laxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};$(".trackster-add").live("click",function(){var b=this,a=$(this);$.ajax({url:a.attr("data-url"),dataType:"html",error:function(){alert("Could not add this dataset to browser.")},success:function(c){var d=window.parent;d.show_modal("Add to Browser:",c,{Cancel:function(){d.hide_modal()},"Insert into selected":function(){$(d.document).find("input[name=id]:checked").each(function(){var e=$(this).val();d.location=a.attr("action-url")+"&id="+e})},"Insert into new browser":function(){d.location=a.attr("new-url")}})}})});$(document).ready(function(){$("select[refresh_on_change='true']").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_val
ue");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").click(function(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus();replace_big_select_inputs(20,1500)});
+if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function show_hide_popupmenu_options(d,c,a){a=(a===undefined?true:a);var b=new RegExp(c);$(d).find("li").each(function(){if(b.exec($(this).text())){if(a){$(this).show()}else{$(this).hide()}}})}function make_popupmenu(b,a){b.bind("click.show_popup",function(c){$(".popmenu-wrapper").remove();setTimeout(function(){var e=$("<ul id='"+b.attr("id")+"-menu'></ul>");if(obj_length(a)<=0){$("<li>No Options.</li>").appendTo(e)}$.each(a,function(h,g){if(g){$("<li/>").html(h).click(g).appendTo(e)}else{$("<li class='head'/
>").html(h).appendTo(e)}});var f=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'>");f.append(e).append("<div class='overlay-border'>").appendTo("body");var d=c.pageX-f.width()/2;d=Math.min(d,$(document).scrollLeft()+$(window).width()-$(f).width()-20);d=Math.max(d,$(document).scrollLeft()+20);f.css({top:c.pageY-5,left:d})},10);setTimeout(function(){var e=function(g){$(g).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();g.unbind("click.close_popup")})};e($(window.document));e($(window.top.document));for(var d=window.top.frames.length;d--;){var f=$(window.top.frames[d].document);e(f)}},50);return false})}function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var a={};var c=$(this);c.find("a").each(function(){var f=$(this),h=f.get(0);var d=h.getAttribute("confirm"),e=h.getAttribute("href"),g=h.getAttribute("target");a[f.text()]=function(){if(!d||confirm(d)){var i=window;if(g=="_parent"){i=window.parent}else{if(g=="_
top"){i=window.top}}i.location=e}}});var b=$("#"+c.attr("popupmenu"));b.find("a").bind("click",function(d){d.stopPropagation();return true});make_popupmenu(b,a);b.addClass("popup");c.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}function replace_big_select_inputs(a,b){if(!jQuery().autocomplete){return}if(a===undefined){a=20}if(b===undefined){b=3000}$("select").each(function(){var d=$(this);var g=d.find("option").length;if((g<a)||(g>b)){return}if(d.attr("multiple")===true){return}if(d.hasClass("no-autocomplete")){return}var m=d.attr("value");var c
=$("<input type='text' class='text-and-autocomplete-select'></input>");c.attr("size",40);c.attr("name",d.attr("name"));c.attr("id",d.attr("id"));c.click(function(){var n=$(this).val();$(this).val("Loading...");$(this).showAllInCache();$(this).val(n);$(this).select()});var e=[];var i={};d.children("option").each(function(){var o=$(this).text();var n=$(this).attr("value");e.push(o);i[o]=n;i[n]=n;if(n==m){c.attr("value",o)}});if(m===""||m==="?"){c.attr("value","Click to Search or Select")}if(d.attr("name")=="dbkey"){e=e.sort(naturalSort)}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:b,minChars:0,hideForLessThanMinChars:false};c.autocomplete(e,f);d.replaceWith(c);var k=function(){var o=c.attr("value");var n=i[o];if(n!==null&&n!==undefined){c.attr("value",n)}else{if(m!==""){c.attr("value",m)}else{c.attr("value","?")}}};c.parents("form").submit(function(){k()});$(document).bind("convert_dbkeys",function(){k()});if(d.attr("refresh_on_change")=="true
"){var h=d.attr("refresh_on_change_values"),l=d.attr("last_selected_value");if(h!==undefined){h=h.split(",")}var j=function(){var n=i[c.attr("value")];if(l!==n&&n!==null&&n!==undefined){if(h!==undefined&&$.inArray(n,h)===-1&&$.inArray(l,h)===-1){return}c.attr("value",n);$(window).trigger("refresh_on_change");c.parents("form").submit()}};c.bind("result",j);c.keyup(function(n){if(n.keyCode===13){j()}});c.keydown(function(n){if(n.keyCode===13){return false}})}})}function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).live("click",function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]
=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStore.store("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStore.remove("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStore.store("history_expand_state");i
f(k){delete k[j];$.jStore.store("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStore.store("history_expand_state");if(k===undefined){k={}}k[j]=true;$.jStore.store("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStore.store("history_expand_state");if(h===undefined){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStore.store("history_expand_state",h)}).show()};if(a){b()}else{$.jStore.init("galaxy");$.jStore.engineReady(function(){b()})}}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("searc
h_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools");b.css("font-style","italic")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({ur
l:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};$(document).ready(function(){$("select[refresh_on_change='true']").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").click(function(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus();replace_big_select_inputs(20,1500)});
1
0