galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- 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
commit/galaxy-central: jmchilton: Some PEP-8 fixes for lib/galaxy/model/__init__.py.
by commits-noreply@bitbucket.org 04 Sep '14
by commits-noreply@bitbucket.org 04 Sep '14
04 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a90ec4d4066f/
Changeset: a90ec4d4066f
User: jmchilton
Date: 2014-09-04 16:31:05
Summary: Some PEP-8 fixes for lib/galaxy/model/__init__.py.
Affected #: 1 file
diff -r dc5e8d1d7a77f9a87a6a825fd8fa9236c9e9a229 -r a90ec4d4066f67149322f68d2dc5c8b98fe4dbcb lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -2466,6 +2466,7 @@
val = getattr( ldda.datatype, name )
rval['metadata_' + name] = val
return rval
+
def get_template_widgets( self, trans, get_contents=True ):
# See if we have any associated templatesThe get_contents
# param is passed by callers that are inheriting a template - these
@@ -2492,6 +2493,7 @@
else:
return template.get_widgets( trans.user )
return []
+
def templates_dict( self, use_name=False ):
"""
Returns a dict of template info
@@ -2510,6 +2512,7 @@
tmp_dict[ name ] = content.get( field[ 'name' ] )
template_data[template.name] = tmp_dict
return template_data
+
def templates_json( self, use_name=False ):
return json.dumps( self.templates_dict( use_name=use_name ) )
@@ -2533,6 +2536,7 @@
self.info = info
self.inheritable = inheritable
+
class LibraryFolderInfoAssociation( object ):
def __init__( self, folder, form_definition, info, inheritable=False ):
self.folder = folder
@@ -2540,15 +2544,18 @@
self.info = info
self.inheritable = inheritable
+
class LibraryDatasetDatasetInfoAssociation( object ):
def __init__( self, library_dataset_dataset_association, form_definition, info ):
# TODO: need to figure out if this should be inheritable to the associated LibraryDataset
self.library_dataset_dataset_association = library_dataset_dataset_association
self.template = form_definition
self.info = info
+
@property
def inheritable( self ):
- return True #always allow inheriting, used for replacement
+ return True # always allow inheriting, used for replacement
+
class ValidationError( object ):
def __init__( self, message=None, err_type=None, attributes=None ):
@@ -2556,42 +2563,47 @@
self.err_type = err_type
self.attributes = attributes
+
class DatasetToValidationErrorAssociation( object ):
def __init__( self, dataset, validation_error ):
self.dataset = dataset
self.validation_error = validation_error
+
class ImplicitlyConvertedDatasetAssociation( object ):
- def __init__( self, id = None, parent = None, dataset = None, file_type = None, deleted = False, purged = False, metadata_safe = True ):
+
+ def __init__( self, id=None, parent=None, dataset=None, file_type=None, deleted=False, purged=False, metadata_safe=True ):
self.id = id
if isinstance(dataset, HistoryDatasetAssociation):
self.dataset = dataset
elif isinstance(dataset, LibraryDatasetDatasetAssociation):
self.dataset_ldda = dataset
else:
- raise AttributeError, 'Unknown dataset type provided for dataset: %s' % type( dataset )
+ raise AttributeError( 'Unknown dataset type provided for dataset: %s' % type( dataset ) )
if isinstance(parent, HistoryDatasetAssociation):
self.parent_hda = parent
elif isinstance(parent, LibraryDatasetDatasetAssociation):
self.parent_ldda = parent
else:
- raise AttributeError, 'Unknown dataset type provided for parent: %s' % type( parent )
+ raise AttributeError( 'Unknown dataset type provided for parent: %s' % type( parent ) )
self.type = file_type
self.deleted = deleted
self.purged = purged
self.metadata_safe = metadata_safe
- def clear( self, purge = False, delete_dataset = True ):
+ def clear( self, purge=False, delete_dataset=True ):
self.deleted = True
if self.dataset:
if delete_dataset:
self.dataset.deleted = True
if purge:
self.dataset.purged = True
- if purge and self.dataset.deleted: #do something with purging
+ if purge and self.dataset.deleted: # do something with purging
self.purged = True
- try: os.unlink( self.file_name )
- except Exception, e: print "Failed to purge associated file (%s) from disk: %s" % ( self.file_name, e )
+ try:
+ os.unlink( self.file_name )
+ except Exception, e:
+ print "Failed to purge associated file (%s) from disk: %s" % ( self.file_name, e )
DEFAULT_COLLECTION_NAME = "Unnamed Collection"
@@ -2903,6 +2915,7 @@
self.tool_id = None
self.message = message
+
class GalaxySession( object ):
def __init__( self,
id=None,
@@ -2924,24 +2937,29 @@
self.is_valid = is_valid
self.prev_session_id = prev_session_id
self.histories = []
+
def add_history( self, history, association=None ):
if association is None:
self.histories.append( GalaxySessionToHistoryAssociation( self, history ) )
else:
self.histories.append( association )
+
def get_disk_usage( self ):
if self.disk_usage is None:
return 0
return self.disk_usage
+
def set_disk_usage( self, bytes ):
self.disk_usage = bytes
total_disk_usage = property( get_disk_usage, set_disk_usage )
+
class GalaxySessionToHistoryAssociation( object ):
def __init__( self, galaxy_session, history ):
self.galaxy_session = galaxy_session
self.history = history
+
class UCI( object ):
def __init__( self ):
self.id = None
@@ -2962,14 +2980,14 @@
self.latest_workflow_id = None
self.workflows = []
- def copy_tags_from(self,target_user,source_workflow):
+ def copy_tags_from(self, target_user, source_workflow):
for src_swta in source_workflow.owner_tags:
new_swta = src_swta.copy()
new_swta.user = target_user
self.tags.append(new_swta)
- def to_dict( self, view='collection', value_mapper = None ):
- rval = super( StoredWorkflow, self ).to_dict( view=view, value_mapper = value_mapper )
+ def to_dict( self, view='collection', value_mapper=None ):
+ rval = super( StoredWorkflow, self ).to_dict( view=view, value_mapper=value_mapper )
tags_str_list = []
for tag in self.tags:
tag_str = tag.user_tname
@@ -3007,12 +3025,11 @@
return False
def to_dict( self, view='collection', value_mapper=None):
- rval = super( Workflow, self ).to_dict( view=view, value_mapper = value_mapper )
- rval['uuid'] = ( lambda uuid: str( uuid ) if uuid else None )( self.uuid )
+ rval = super( Workflow, self ).to_dict( view=view, value_mapper=value_mapper )
+ rval['uuid'] = ( lambda uuid: str( uuid ) if uuid else None )( self.uuid )
return rval
-
class WorkflowStep( object ):
def __init__( self ):
@@ -3061,7 +3078,7 @@
dict_collection_visible_keys = ( 'id', 'update_time', 'workflow_id' )
dict_element_visible_keys = ( 'id', 'update_time', 'workflow_id' )
- def to_dict( self, view='collection', value_mapper = None ):
+ def to_dict( self, view='collection', value_mapper=None ):
rval = super( WorkflowInvocation, self ).to_dict( view=view, value_mapper=value_mapper )
if view == 'element':
steps = {}
@@ -3072,12 +3089,12 @@
inputs = {}
for step in self.steps:
- if step.workflow_step.type =='tool':
+ if step.workflow_step.type == 'tool':
for step_input in step.workflow_step.input_connections:
if step_input.output_step.type == 'data_input':
for job_input in step.job.input_datasets:
if job_input.name == step_input.input_name:
- inputs[str(step_input.output_step.order_index)] = { "id" : job_input.dataset_id, "src" : "hda"}
+ inputs[str(step_input.output_step.order_index)] = { "id": job_input.dataset_id, "src": "hda"}
rval['inputs'] = inputs
return rval
@@ -3086,19 +3103,20 @@
dict_collection_visible_keys = ( 'id', 'update_time', 'job_id', 'workflow_step_id' )
dict_element_visible_keys = ( 'id', 'update_time', 'job_id', 'workflow_step_id' )
- def to_dict( self, view='collection', value_mapper = None ):
+ def to_dict( self, view='collection', value_mapper=None ):
rval = super( WorkflowInvocationStep, self ).to_dict( view=view, value_mapper=value_mapper )
rval['order_index'] = self.workflow_step.order_index
return rval
class MetadataFile( object ):
- def __init__( self, dataset = None, name = None ):
+ def __init__( self, dataset=None, name=None ):
if isinstance( dataset, HistoryDatasetAssociation ):
self.history_dataset = dataset
elif isinstance( dataset, LibraryDatasetDatasetAssociation ):
self.library_dataset = dataset
self.name = name
+
@property
def file_name( self ):
assert self.id is not None, "ID must be set before filename used (commit the object)"
@@ -3129,14 +3147,15 @@
class FormDefinition( object, Dictifiable ):
# The following form_builder classes are supported by the FormDefinition class.
supported_field_types = [ AddressField, CheckboxField, PasswordField, SelectField, TextArea, TextField, WorkflowField, WorkflowMappingField, HistoryField ]
- types = Bunch( REQUEST = 'Sequencing Request Form',
- SAMPLE = 'Sequencing Sample Form',
- EXTERNAL_SERVICE = 'External Service Information Form',
- RUN_DETAILS_TEMPLATE = 'Sample run details template',
- LIBRARY_INFO_TEMPLATE = 'Library information template',
- USER_INFO = 'User Information' )
+ types = Bunch( REQUEST='Sequencing Request Form',
+ SAMPLE='Sequencing Sample Form',
+ EXTERNAL_SERVICE='External Service Information Form',
+ RUN_DETAILS_TEMPLATE='Sample run details template',
+ LIBRARY_INFO_TEMPLATE='Library information template',
+ USER_INFO='User Information' )
dict_collection_visible_keys = ( 'id', 'name' )
dict_element_visible_keys = ( 'id', 'name', 'desc', 'form_definition_current_id', 'fields', 'layout' )
+
def __init__( self, name=None, desc=None, fields=[], form_definition_current=None, form_type=None, layout=None ):
self.name = name
self.desc = desc
@@ -3144,6 +3163,7 @@
self.form_definition_current = form_definition_current
self.type = form_type
self.layout = layout
+
def grid_fields( self, grid_index ):
# Returns a dictionary whose keys are integers corresponding to field positions
# on the grid and whose values are the field.
@@ -3152,6 +3172,7 @@
if str( f[ 'layout' ] ) == str( grid_index ):
gridfields[i] = f
return gridfields
+
def get_widgets( self, user, contents={}, **kwd ):
'''
Return the list of widgets that comprise a form definition,
@@ -3213,24 +3234,28 @@
field_widget.params = params
elif field_type == 'SelectField':
for option in field[ 'selectlist' ]:
+
if option == value:
field_widget.add_option( option, option, selected=True )
else:
field_widget.add_option( option, option )
elif field_type == 'CheckboxField':
+
field_widget.set_checked( value )
if field[ 'required' ] == 'required':
req = 'Required'
else:
req = 'Optional'
if field[ 'helptext' ]:
- helptext='%s (%s)' % ( field[ 'helptext' ], req )
+ helptext = '%s (%s)' % ( field[ 'helptext' ], req )
else:
helptext = '(%s)' % req
widgets.append( dict( label=field[ 'label' ],
+
widget=field_widget,
helptext=helptext ) )
return widgets
+
def field_as_html( self, field ):
"""Generates disabled html for a field"""
type = field[ 'type' ]
@@ -3245,21 +3270,25 @@
# Return None if unsupported field type
return None
+
class FormDefinitionCurrent( object ):
def __init__(self, form_definition=None):
self.latest_form = form_definition
+
class FormValues( object ):
def __init__(self, form_def=None, content=None):
self.form_definition = form_def
self.content = content
+
class Request( object, Dictifiable ):
- states = Bunch( NEW = 'New',
- SUBMITTED = 'In Progress',
- REJECTED = 'Rejected',
- COMPLETE = 'Complete' )
+ states = Bunch( NEW='New',
+ SUBMITTED='In Progress',
+ REJECTED='Rejected',
+ COMPLETE='Complete' )
dict_collection_visible_keys = ( 'id', 'name', 'state' )
+
def __init__( self, name=None, desc=None, request_type=None, user=None, form_values=None, notification=None ):
self.name = name
self.desc = desc
@@ -3268,17 +3297,20 @@
self.user = user
self.notification = notification
self.samples_list = []
+
@property
def state( self ):
latest_event = self.latest_event
if latest_event:
return latest_event.state
return None
+
@property
def latest_event( self ):
if self.events:
return self.events[0]
return None
+
@property
def samples_have_common_state( self ):
"""
@@ -3294,6 +3326,7 @@
if s.state.id != state_for_comparison.id:
return False
return state_for_comparison
+
@property
def last_comment( self ):
latest_event = self.latest_event
@@ -3302,26 +3335,34 @@
return latest_event.comment
return ''
return 'No comment'
+
def get_sample( self, sample_name ):
for sample in self.samples:
if sample.name == sample_name:
return sample
return None
+
@property
def is_unsubmitted( self ):
return self.state in [ self.states.REJECTED, self.states.NEW ]
+
@property
def is_rejected( self ):
return self.state == self.states.REJECTED
+
@property
def is_submitted( self ):
return self.state == self.states.SUBMITTED
+
@property
def is_new( self ):
+
return self.state == self.states.NEW
+
@property
def is_complete( self ):
return self.state == self.states.COMPLETE
+
@property
def samples_without_library_destinations( self ):
# Return all samples that are not associated with a library
@@ -3330,6 +3371,7 @@
if not sample.library:
samples.append( sample )
return samples
+
@property
def samples_with_bar_code( self ):
# Return all samples that have associated bar code
@@ -3338,6 +3380,7 @@
if sample.bar_code:
samples.append( sample )
return samples
+
def send_email_notification( self, trans, common_state, final_state=False ):
# Check if an email notification is configured to be sent when the samples
# are in this state
@@ -3390,7 +3433,7 @@
try:
send_mail( frm, to, subject, body, trans.app.config )
comments = "Email notification sent to %s." % ", ".join( to ).strip().strip( ',' )
- except Exception,e:
+ except Exception, e:
comments = "Email notification failed. (%s)" % str(e)
# update the request history with the email notification event
elif not trans.app.config.smtp_server:
@@ -3401,16 +3444,19 @@
trans.sa_session.flush()
return comments
+
class RequestEvent( object ):
def __init__(self, request=None, request_state=None, comment=''):
self.request = request
self.state = request_state
self.comment = comment
+
class ExternalService( object ):
- data_transfer_protocol = Bunch( HTTP = 'http',
- HTTPS = 'https',
- SCP = 'scp' )
+ data_transfer_protocol = Bunch( HTTP='http',
+ HTTPS='https',
+ SCP='scp' )
+
def __init__( self, name=None, description=None, external_service_type_id=None, version=None, form_definition_id=None, form_values_id=None, deleted=None ):
self.name = name
self.description = description
@@ -3419,9 +3465,11 @@
self.form_definition_id = form_definition_id
self.form_values_id = form_values_id
self.deleted = deleted
- self.label = None # Used in the request_type controller's __build_external_service_select_field() method
+ self.label = None # Used in the request_type controller's __build_external_service_select_field() method
+
def get_external_service_type( self, trans ):
return trans.app.external_service_types.all_external_service_types[ self.external_service_type_id ]
+
def load_data_transfer_settings( self, trans ):
trans.app.external_service_types.reload( self.external_service_type_id )
self.data_transfer = {}
@@ -3442,33 +3490,39 @@
automatic_transfer = data_transfer_obj.config.get( 'automatic_transfer', 'false' )
http_configs[ 'automatic_transfer' ] = galaxy.util.string_as_bool( automatic_transfer )
self.data_transfer[ self.data_transfer_protocol.HTTP ] = http_configs
+
def populate_actions( self, trans, item, param_dict=None ):
return self.get_external_service_type( trans ).actions.populate( self, item, param_dict=param_dict )
+
class RequestType( object, Dictifiable ):
dict_collection_visible_keys = ( 'id', 'name', 'desc' )
dict_element_visible_keys = ( 'id', 'name', 'desc', 'request_form_id', 'sample_form_id' )
- rename_dataset_options = Bunch( NO = 'Do not rename',
- SAMPLE_NAME = 'Preprend sample name',
- EXPERIMENT_NAME = 'Prepend experiment name',
- EXPERIMENT_AND_SAMPLE_NAME = 'Prepend experiment and sample name')
+ rename_dataset_options = Bunch( NO='Do not rename',
+ SAMPLE_NAME='Preprend sample name',
+ EXPERIMENT_NAME='Prepend experiment name',
+ EXPERIMENT_AND_SAMPLE_NAME='Prepend experiment and sample name')
permitted_actions = get_permitted_actions( filter='REQUEST_TYPE' )
+
def __init__( self, name=None, desc=None, request_form=None, sample_form=None ):
self.name = name
self.desc = desc
self.request_form = request_form
self.sample_form = sample_form
+
@property
def external_services( self ):
external_services = []
for rtesa in self.external_service_associations:
external_services.append( rtesa.external_service )
return external_services
+
def get_external_service( self, external_service_type_id ):
for rtesa in self.external_service_associations:
if rtesa.external_service.external_service_type_id == external_service_type_id:
return rtesa.external_service
return None
+
def get_external_services_for_manual_data_transfer( self, trans ):
'''Returns all external services that use manual data transfer'''
external_services = []
@@ -3481,6 +3535,7 @@
if not transfer_type_settings[ 'automatic_transfer' ]:
external_services.append( external_service )
return external_services
+
def delete_external_service_associations( self, trans ):
'''Deletes all external service associations.'''
flush_needed = False
@@ -3489,20 +3544,24 @@
flush_needed = True
if flush_needed:
trans.sa_session.flush()
+
def add_external_service_association( self, trans, external_service ):
rtesa = trans.model.RequestTypeExternalServiceAssociation( self, external_service )
trans.sa_session.add( rtesa )
trans.sa_session.flush()
+
@property
def final_sample_state( self ):
# The states mapper for this object orders ascending
return self.states[-1]
+
@property
def run_details( self ):
if self.run:
# self.run[0] is [RequestTypeRunAssociation]
return self.run[0]
return None
+
def get_template_widgets( self, trans, get_contents=True ):
# See if we have any associated templates. The get_contents param
# is passed by callers that are inheriting a template - these are
@@ -3520,23 +3579,27 @@
return template.get_widgets( trans.user )
return []
+
class RequestTypeExternalServiceAssociation( object ):
def __init__( self, request_type, external_service ):
self.request_type = request_type
self.external_service = external_service
+
class RequestTypePermissions( object ):
def __init__( self, action, request_type, role ):
self.action = action
self.request_type = request_type
self.role = role
+
class Sample( object, Dictifiable ):
# The following form_builder classes are supported by the Sample class.
supported_field_types = [ CheckboxField, SelectField, TextField, WorkflowField, WorkflowMappingField, HistoryField ]
- bulk_operations = Bunch( CHANGE_STATE = 'Change state',
- SELECT_LIBRARY = 'Select data library and folder' )
+ bulk_operations = Bunch( CHANGE_STATE='Change state',
+ SELECT_LIBRARY='Select data library and folder' )
dict_collection_visible_keys = ( 'id', 'name' )
+
def __init__(self, name=None, desc=None, request=None, form_values=None, bar_code=None, library=None, folder=None, workflow=None, history=None):
self.name = name
self.desc = desc
@@ -3547,17 +3610,20 @@
self.folder = folder
self.history = history
self.workflow = workflow
+
@property
def state( self ):
latest_event = self.latest_event
if latest_event:
return latest_event.state
return None
+
@property
def latest_event( self ):
if self.events:
return self.events[0]
return None
+
@property
def adding_to_library_dataset_files( self ):
adding_to_library_datasets = []
@@ -3565,6 +3631,7 @@
if dataset.status == SampleDataset.transfer_status.ADD_TO_LIBRARY:
adding_to_library_datasets.append( dataset )
return adding_to_library_datasets
+
@property
def inprogress_dataset_files( self ):
inprogress_datasets = []
@@ -3572,6 +3639,7 @@
if dataset.status not in [ SampleDataset.transfer_status.NOT_STARTED, SampleDataset.transfer_status.COMPLETE ]:
inprogress_datasets.append( dataset )
return inprogress_datasets
+
@property
def queued_dataset_files( self ):
queued_datasets = []
@@ -3579,6 +3647,7 @@
if dataset.status == SampleDataset.transfer_status.IN_QUEUE:
queued_datasets.append( dataset )
return queued_datasets
+
@property
def transfer_error_dataset_files( self ):
transfer_error_datasets = []
@@ -3586,6 +3655,7 @@
if dataset.status == SampleDataset.transfer_status.ERROR:
transfer_error_datasets.append( dataset )
return transfer_error_datasets
+
@property
def transferred_dataset_files( self ):
transferred_datasets = []
@@ -3593,6 +3663,7 @@
if dataset.status == SampleDataset.transfer_status.COMPLETE:
transferred_datasets.append( dataset )
return transferred_datasets
+
@property
def transferring_dataset_files( self ):
transferring_datasets = []
@@ -3600,6 +3671,7 @@
if dataset.status == SampleDataset.transfer_status.TRANSFERRING:
transferring_datasets.append( dataset )
return transferring_datasets
+
@property
def untransferred_dataset_files( self ):
untransferred_datasets = []
@@ -3607,6 +3679,7 @@
if dataset.status != SampleDataset.transfer_status.COMPLETE:
untransferred_datasets.append( dataset )
return untransferred_datasets
+
def get_untransferred_dataset_size( self, filepath, scp_configs ):
def print_ticks( d ):
pass
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Update tag latest_2014.08.11 for changeset e8453771b1db
by commits-noreply@bitbucket.org 04 Sep '14
by commits-noreply@bitbucket.org 04 Sep '14
04 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/db520d154716/
Changeset: db520d154716
Branch: stable
User: natefoo
Date: 2014-09-04 16:00:23
Summary: Update tag latest_2014.08.11 for changeset e8453771b1db
Affected #: 1 file
diff -r e8453771b1dbfe462974b63216e00752fb8c4097 -r db520d1547165e56b3a0a0ff01fb854c0f93e4b1 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -18,4 +18,4 @@
81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04
2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
-20f4fdf1735aeff23a6e7ab00389781fe3f3142c latest_2014.08.11
+e8453771b1dbfe462974b63216e00752fb8c4097 latest_2014.08.11
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
04 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/dc5e8d1d7a77/
Changeset: dc5e8d1d7a77
User: jmchilton
Date: 2014-09-04 15:09:52
Summary: Merge latest stable.
Affected #: 2 files
diff -r fd25aea901ca120e8ac085e83c3835abb09e6e28 -r dc5e8d1d7a77f9a87a6a825fd8fa9236c9e9a229 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -18,4 +18,4 @@
81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04
2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
-ea12550fbc34260ae70bde38db59a4024f35f988 latest_2014.08.11
+20f4fdf1735aeff23a6e7ab00389781fe3f3142c latest_2014.08.11
diff -r fd25aea901ca120e8ac085e83c3835abb09e6e28 -r dc5e8d1d7a77f9a87a6a825fd8fa9236c9e9a229 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -2130,6 +2130,8 @@
elif isinstance( value, basestring ):
if value.startswith( "dce:" ):
rval = trans.sa_session.query( trans.app.model.DatasetCollectionElement ).get( value[ len( "dce:"): ] )
+ elif value.startswith( "hdca:" ):
+ rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( value[ len( "hdca:"): ] )
else:
rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( value )
if rval and isinstance( rval, trans.app.model.HistoryDatasetCollectionAssociation ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: ToolForm: Fix multi-select field
by commits-noreply@bitbucket.org 04 Sep '14
by commits-noreply@bitbucket.org 04 Sep '14
04 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/fd25aea901ca/
Changeset: fd25aea901ca
User: guerler
Date: 2014-09-04 05:33:30
Summary: ToolForm: Fix multi-select field
Affected #: 8 files
diff -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c -r fd25aea901ca120e8ac085e83c3835abb09e6e28 static/scripts/mvc/tools/tools-section.js
--- a/static/scripts/mvc/tools/tools-section.js
+++ b/static/scripts/mvc/tools/tools-section.js
@@ -336,7 +336,14 @@
id : 'field-' + id,
data : options,
value : options[0].value,
+ multiple : input_def.multiple,
onchange : function(value) {
+ // pick the first dataset if multiple might be selected
+ // TODO: iterate over all datasets and filter common/consistent columns
+ if (input_def.multiple) {
+ value = value[0];
+ }
+
// get referenced columns
var column_list = self.app.tree.findReferences(id, 'data_column');
@@ -437,18 +444,16 @@
// column selection field
_field_column : function (input_def) {
return new Ui.Select.View({
- id : 'field-' + input_def.id
+ id : 'field-' + input_def.id,
+ multiple: input_def.multiple
});
},
// text input field
_field_text : function(input_def) {
- var TextClass = Ui.Input;
- if (input_def.area) {
- TextClass = Ui.Textarea;
- }
- return new TextClass({
- id : 'field-' + input_def.id
+ return new Ui.Input({
+ id : 'field-' + input_def.id,
+ area : input_def.area
});
},
diff -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c -r fd25aea901ca120e8ac085e83c3835abb09e6e28 static/scripts/mvc/ui/ui-misc.js
--- a/static/scripts/mvc/ui/ui-misc.js
+++ b/static/scripts/mvc/ui/ui-misc.js
@@ -312,7 +312,8 @@
placeholder : '',
disabled : false,
visible : true,
- cls : ''
+ cls : '',
+ area : false
},
// initialize
@@ -352,60 +353,11 @@
// element
_template: function(options) {
- return '<input id="' + options.id + '" type="' + options.type + '" value="' + options.value + '" placeholder="' + options.placeholder + '" class="ui-input ' + options.cls + '">';
- }
-});
-
-// plugin
-var Textarea = Backbone.View.extend({
- // options
- optionsDefault: {
- value : '',
- type : 'text',
- placeholder : '',
- disabled : false,
- visible : true,
- cls : ''
- },
-
- // initialize
- initialize : function(options) {
- // configure options
- this.options = Utils.merge(options, this.optionsDefault);
-
- // create new element
- this.setElement(this._template(this.options));
-
- // disable input field
- if (this.options.disabled) {
- this.$el.prop('disabled', true);
+ if (options.area) {
+ return '<textarea id="' + options.id + '" class="ui-textarea ' + options.cls + '"></textarea>';
+ } else {
+ return '<input id="' + options.id + '" type="' + options.type + '" value="' + options.value + '" placeholder="' + options.placeholder + '" class="ui-input ' + options.cls + '">';
}
-
- // hide input field
- if (!this.options.visible) {
- this.$el.hide();
- }
-
- // onchange event handler. fires on user activity.
- var self = this;
- this.$el.on('input', function() {
- if (self.options.onchange) {
- self.options.onchange(self.$el.val());
- }
- });
- },
-
- // value
- value : function (new_val) {
- if (new_val !== undefined) {
- this.$el.val(new_val);
- }
- return this.$el.val();
- },
-
- // element
- _template: function(options) {
- return '<textarea id="' + options.id + '" class="ui-textarea ' + options.cls + '"></textarea>';
}
});
@@ -455,7 +407,6 @@
Checkbox : Checkbox,
Searchbox : Searchbox,
Select : Select,
- Textarea : Textarea,
Hidden : Hidden,
Slider : Slider
}
diff -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c -r fd25aea901ca120e8ac085e83c3835abb09e6e28 static/scripts/mvc/ui/ui-select-default.js
--- a/static/scripts/mvc/ui/ui-select-default.js
+++ b/static/scripts/mvc/ui/ui-select-default.js
@@ -7,24 +7,19 @@
var View = Backbone.View.extend({
// options
optionsDefault : {
- id : '',
- cls : '',
- empty : 'No data available',
- visible : true,
- wait : false
+ id : '',
+ cls : '',
+ empty : 'No data available',
+ visible : true,
+ wait : false,
+ multiple : false
},
- // value
- selected : null,
-
// initialize
initialize : function(options) {
// configure options
this.options = Utils.merge(options, this.optionsDefault);
- // initial value
- this.selected = this.options.value;
-
// create new element
this.setElement(this._template(this.options));
@@ -32,21 +27,17 @@
this.$select = this.$el.find('#select');
this.$icon = this.$el.find('#icon');
- // add change event. fires only on user activity
- var self = this;
- this.$select.on('change', function() {
- self.value(self.$select.val());
- });
-
- // add change event. fires on trigger
- this.on('change', function() {
- if (self.options.onchange) {
- self.options.onchange(self.value());
- }
- });
+ // configure multiple
+ if (this.options.multiple) {
+ this.$select.prop('multiple', true);
+ this.$select.addClass('ui-select-multiple');
+ this.$icon.remove();
+ } else {
+ this.$el.addClass('ui-select');
+ }
// refresh
- this._refresh();
+ this.update(this.options.data);
// show/hide
if (!this.options.visible) {
@@ -59,31 +50,25 @@
} else {
this.show();
}
+
+ // add change event. fires only on user activity
+ var self = this;
+ this.$select.on('change', function() {
+ self._change();
+ });
+
+ // add change event. fires on trigger
+ this.on('change', function() {
+ self._change();
+ });
},
// value
value : function (new_value) {
-
- // get current id/value
- var before = this.selected;
-
- // check if new_value is defined
if (new_value !== undefined) {
- this.selected = new_value;
this.$select.val(new_value);
}
-
- // get current id/value
- var after = this.selected;
- if (after) {
- // fire onchange
- if (after != before && this.options.onchange) {
- this.options.onchange(after);
- }
- }
-
- // return
- return after;
+ return this.$select.val();
},
// first
@@ -157,6 +142,9 @@
// render
update: function(options) {
+ // backup current value
+ var current = this.$select.val();
+
// remove all options
this.$select.find('option').remove();
@@ -167,6 +155,14 @@
// refresh
this._refresh();
+
+ // set previous value
+ this.$select.val(current);
+
+ // check if any value was set
+ if (!this.$select.val()) {
+ this.$select.val(this.first());
+ }
},
// set on change event
@@ -179,6 +175,13 @@
return this.$select.find('option[value=' + value + ']').length > 0;
},
+ // change
+ _change: function() {
+ if (this.options.onchange) {
+ this.options.onchange(this.$select.val());
+ }
+ },
+
// refresh
_refresh: function() {
// remove placeholder
@@ -196,41 +199,21 @@
// enable select field
this.enable();
}
-
- // update value
- if (this.selected) {
- this.$select.val(this.selected);
- }
},
- // option
+ // template option
_templateOption: function(options) {
return '<option value="' + options.value + '">' + options.label + '</option>';
},
- // element
+ // template
_template: function(options) {
- var tmpl = '<div id="' + options.id + '" class="ui-select">' +
- '<div class="button">' +
- '<i id="icon"/>' +
- '</div>' +
- '<select id="select" class="select ' + options.cls + ' ' + options.id + '">';
- for (key in options.data) {
- // options
- var item = options.data[key];
-
- // identify selected value
- var tag = '';
- if (item.value == options.value || item.value == '') {
- tag = 'selected';
- }
-
- // add template string
- tmpl += '<option value="' + item.value + '" ' + tag + '>' + item.label + '</option>';
- }
- tmpl += '</select>' +
- '</div>';
- return tmpl;
+ return '<div id="' + options.id + '">' +
+ '<div class="button">' +
+ '<i id="icon"/>' +
+ '</div>' +
+ '<select id="select" class="select ' + options.cls + ' ' + options.id + '"></select>' +
+ '</div>';
}
});
diff -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c -r fd25aea901ca120e8ac085e83c3835abb09e6e28 static/scripts/packed/mvc/tools/tools-section.js
--- a/static/scripts/packed/mvc/tools/tools-section.js
+++ b/static/scripts/packed/mvc/tools/tools-section.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;f.cls_tr="section-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f])}},_add:function(h){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f)}},_addConditional:function(f){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f);for(var h in f.cases){var g=f.id+"-section-"+h;var j=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(j.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(h,f){var j=f.id;var g=null;switch(h){case"text":g=this._field_text(f);break;case"select":g=this._field_select(f);break;case"data":g=this._field_data(f);break;case"data_column":g=this._field_column(f);break;case"conditional":g=this._field_conditional(f);break;case"hidden":g=this._field_hidden(f);break;case"integer":g=this._field_slider(f);break;case"float":g=this._field_slider(f);break;case"boolean":g=this._field_boolean(f);break;default:g=this._field_text(f);console.debug("tools-form::_addRow() : Unmatched field type ("+h+").")}if(f.value!==undefined){g.value(f.value)}this.app.field_list[j]=g;var i=$("<div/>");i.append(g.$el);if(f.help){i.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(i);this.table.append(j)},_field_conditional:function(f){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}return new e.Select.View({id:"field-"+f.id,data:h,onchange:function(s){for(var q in f.cases){var m=f.cases[q];var p=f.id+"-section-"+q;var l=g.table.get(p);var o=false;for(var n in m.inputs){var r=m.inputs[n].type;if(r&&r!=="hidden"){o=true;break}}if(m.value==s&&o){l.fadeIn("fast")}else{l.hide()}}}})},_field_data:function(f){var g=this;var l=f.id;var k=this.app.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+l,data:h,value:h[0].value,onchange:function(u){var s=g.app.tree.findReferences(l,"data_column");var n=g.app.datasets.filter(u);if(n&&s.length>0){console.debug("tool-form::field_data() - Selected dataset "+u+".");var w=n.get("metadata_column_types");if(!w){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+u+".")}for(var p in s){var q=g.app.input_list[s[p]];var r=g.app.field_list[s[p]];if(!q||!r){console.debug("tool-form::field_data() - FAILED: Column not found.")}var o=q.numerical;var m=[];for(var v in w){var t=w[v];if(t=="int"||t=="float"||!o){m.push({label:"Column: "+(parseInt(v)+1)+" ["+w[v]+"]",value:v})}}if(r){r.update(m);if(!r.exists(r.value())){r.value(r.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+u+".")}}})},_field_select:function(f){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;switch(f.display){case"checkboxes":k=e.Checkbox;break;case"radio":k=e.RadioButton;break}if(f.multiple){k=e.Checkbox}return new k.View({id:"field-"+f.id,data:g})},_field_column:function(f){return new e.Select.View({id:"field-"+f.id})},_field_text:function(g){var f=e.Input;if(g.area){f=e.Textarea}return new f({id:"field-"+g.id})},_field_slider:function(f){return new e.Slider.View({id:"field-"+f.id,min:f.min||0,max:f.max||1000,decimal:f.type=="float"})},_field_hidden:function(f){return new e.Hidden({id:"field-"+f.id})},_field_boolean:function(f){return new e.RadioButton.View({id:"field-"+f.id,data:[{label:"Yes",value:true},{label:"No",value:false}]})}});return{View:d}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;f.cls_tr="section-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f])}},_add:function(h){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f)}},_addConditional:function(f){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f);for(var h in f.cases){var g=f.id+"-section-"+h;var j=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(j.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(h,f){var j=f.id;var g=null;switch(h){case"text":g=this._field_text(f);break;case"select":g=this._field_select(f);break;case"data":g=this._field_data(f);break;case"data_column":g=this._field_column(f);break;case"conditional":g=this._field_conditional(f);break;case"hidden":g=this._field_hidden(f);break;case"integer":g=this._field_slider(f);break;case"float":g=this._field_slider(f);break;case"boolean":g=this._field_boolean(f);break;default:g=this._field_text(f);console.debug("tools-form::_addRow() : Unmatched field type ("+h+").")}if(f.value!==undefined){g.value(f.value)}this.app.field_list[j]=g;var i=$("<div/>");i.append(g.$el);if(f.help){i.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(i);this.table.append(j)},_field_conditional:function(f){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}return new e.Select.View({id:"field-"+f.id,data:h,onchange:function(s){for(var q in f.cases){var m=f.cases[q];var p=f.id+"-section-"+q;var l=g.table.get(p);var o=false;for(var n in m.inputs){var r=m.inputs[n].type;if(r&&r!=="hidden"){o=true;break}}if(m.value==s&&o){l.fadeIn("fast")}else{l.hide()}}}})},_field_data:function(f){var g=this;var l=f.id;var k=this.app.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+l,data:h,value:h[0].value,onchange:function(u){var s=g.app.tree.findReferences(l,"data_column");var n=g.app.datasets.filter(u);if(n&&s.length>0){console.debug("tool-form::field_data() - Selected dataset "+u+".");var w=n.get("metadata_column_types");if(!w){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+u+".")}for(var p in s){var q=g.app.input_list[s[p]];var r=g.app.field_list[s[p]];if(!q||!r){console.debug("tool-form::field_data() - FAILED: Column not found.")}var o=q.numerical;var m=[];for(var v in w){var t=w[v];if(t=="int"||t=="float"||!o){m.push({label:"Column: "+(parseInt(v)+1)+" ["+w[v]+"]",value:v})}}if(r){r.update(m);if(!r.exists(r.value())){r.value(r.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+u+".")}}})},_field_select:function(f){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;switch(f.display){case"checkboxes":k=e.Checkbox;break;case"radio":k=e.RadioButton;break}if(f.multiple){k=e.Checkbox}return new k.View({id:"field-"+f.id,data:g})},_field_column:function(f){return new e.Select.View({id:"field-"+f.id,multiple:f.multiple})},_field_text:function(f){return new e.Input({id:"field-"+f.id,area:f.area})},_field_slider:function(f){return new e.Slider.View({id:"field-"+f.id,min:f.min||0,max:f.max||1000,decimal:f.type=="float"})},_field_hidden:function(f){return new e.Hidden({id:"field-"+f.id})},_field_boolean:function(f){return new e.RadioButton.View({id:"field-"+f.id,data:[{label:"Yes",value:true},{label:"No",value:false}]})}});return{View:d}});
\ No newline at end of file
diff -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c -r fd25aea901ca120e8ac085e83c3835abb09e6e28 static/scripts/packed/mvc/ui/ui-misc.js
--- a/static/scripts/packed/mvc/ui/ui-misc.js
+++ b/static/scripts/packed/mvc/ui/ui-misc.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-checkbox","mvc/ui/ui-radiobutton","mvc/ui/ui-button-menu","mvc/ui/ui-modal"],function(e,h,k,i,b,r,c){var q=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(s){return'<img class="ui-image '+s.cls+'" src="'+s.url+'"/>'}});var l=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},title:function(s){this.$el.html(s)},_template:function(s){return'<label class="ui-label '+s.cls+'">'+s.title+"</label>"},value:function(){return options.title}});var d=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){return'<div><span class="fa '+s.icon+'" class="ui-icon"/> '+s.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"btn btn-default",icon:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick);$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t='<button id="'+s.id+'" type="submit" style="float: '+s.floating+';" type="button" class="ui-button '+s.cls+'">';if(s.icon){t+='<i class="icon fa '+s.icon+'"></i> '}t+=s.title+"</button>";return t}});var o=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"icon-btn",icon:"",tooltip:"",onclick:null},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick);$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t="";if(s.title){t="width: auto;"}var u='<div id="'+s.id+'" style="float: '+s.floating+"; "+t+'" class="ui-button-icon '+s.cls+'">';if(s.title){u+='<div class="button"><i class="icon fa '+s.icon+'"/> <span class="title">'+s.title+"</span></div>"}else{u+='<i class="icon fa '+s.icon+'"/>'}u+="</div>";return u}});var p=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick)},_template:function(s){return'<div><a href="javascript:void(0)" class="ui-anchor '+s.cls+'">'+s.title+"</a></div>"}});var a=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:false},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(t.message);this.$el.fadeIn();if(!t.persistent){var s=this;window.setTimeout(function(){if(s.$el.is(":visible")){s.$el.fadeOut()}else{s.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(s){return'<div class="ui-message alert alert-'+s.status+'"/>'}});var f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));var s=this;if(this.options.onclick){this.$el.on("submit",function(v){var u=s.$el.find("#search");s.options.onclick(u.val())})}},_template:function(s){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+s.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var n=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<input id="'+s.id+'" type="'+s.type+'" value="'+s.value+'" placeholder="'+s.placeholder+'" class="ui-input '+s.cls+'">'}});var j=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<textarea id="'+s.id+'" class="ui-textarea '+s.cls+'"></textarea>'}});var m=Backbone.View.extend({optionsDefault:{value:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<hidden id="'+s.id+'" value="'+s.value+'"/>'}});return{Anchor:p,Button:g,ButtonIcon:o,ButtonMenu:r,Icon:d,Image:q,Input:n,Label:l,Message:a,Modal:c,RadioButton:b,Checkbox:i,Searchbox:f,Select:h,Textarea:j,Hidden:m,Slider:k}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-checkbox","mvc/ui/ui-radiobutton","mvc/ui/ui-button-menu","mvc/ui/ui-modal"],function(l,b,f,e,m,q,n){var d=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(r){return'<img class="ui-image '+r.cls+'" src="'+r.url+'"/>'}});var k=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},title:function(r){this.$el.html(r)},_template:function(r){return'<label class="ui-label '+r.cls+'">'+r.title+"</label>"},value:function(){return options.title}});var c=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){return'<div><span class="fa '+r.icon+'" class="ui-icon"/> '+r.title+"</div>"}});var h=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"btn btn-default",icon:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick);$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){var s='<button id="'+r.id+'" type="submit" style="float: '+r.floating+';" type="button" class="ui-button '+r.cls+'">';if(r.icon){s+='<i class="icon fa '+r.icon+'"></i> '}s+=r.title+"</button>";return s}});var i=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"icon-btn",icon:"",tooltip:"",onclick:null},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick);$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){var s="";if(r.title){s="width: auto;"}var t='<div id="'+r.id+'" style="float: '+r.floating+"; "+s+'" class="ui-button-icon '+r.cls+'">';if(r.title){t+='<div class="button"><i class="icon fa '+r.icon+'"/> <span class="title">'+r.title+"</span></div>"}else{t+='<i class="icon fa '+r.icon+'"/>'}t+="</div>";return t}});var g=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick)},_template:function(r){return'<div><a href="javascript:void(0)" class="ui-anchor '+r.cls+'">'+r.title+"</a></div>"}});var o=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:false},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement("<div></div>")},update:function(s){this.options=l.merge(s,this.optionsDefault);if(s.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(s.message);this.$el.fadeIn();if(!s.persistent){var r=this;window.setTimeout(function(){if(r.$el.is(":visible")){r.$el.fadeOut()}else{r.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(r){return'<div class="ui-message alert alert-'+r.status+'"/>'}});var a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(s){this.options=l.merge(s,this.optionsDefault);this.setElement(this._template(this.options));var r=this;if(this.options.onclick){this.$el.on("submit",function(u){var t=r.$el.find("#search");r.options.onclick(t.val())})}},_template:function(r){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+r.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var j=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:"",area:false},initialize:function(s){this.options=l.merge(s,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var r=this;this.$el.on("input",function(){if(r.options.onchange){r.options.onchange(r.$el.val())}})},value:function(r){if(r!==undefined){this.$el.val(r)}return this.$el.val()},_template:function(r){if(r.area){return'<textarea id="'+r.id+'" class="ui-textarea '+r.cls+'"></textarea>'}else{return'<input id="'+r.id+'" type="'+r.type+'" value="'+r.value+'" placeholder="'+r.placeholder+'" class="ui-input '+r.cls+'">'}}});var p=Backbone.View.extend({optionsDefault:{value:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},value:function(r){if(r!==undefined){this.$el.val(r)}return this.$el.val()},_template:function(r){return'<hidden id="'+r.id+'" value="'+r.value+'"/>'}});return{Anchor:g,Button:h,ButtonIcon:i,ButtonMenu:q,Icon:c,Image:d,Input:j,Label:k,Message:o,Modal:n,RadioButton:m,Checkbox:e,Searchbox:a,Select:b,Hidden:p,Slider:f}});
\ No newline at end of file
diff -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c -r fd25aea901ca120e8ac085e83c3835abb09e6e28 static/scripts/packed/mvc/ui/ui-select-default.js
--- a/static/scripts/packed/mvc/ui/ui-select-default.js
+++ b/static/scripts/packed/mvc/ui/ui-select-default.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:true,wait:false},selected:null,initialize:function(d){this.options=a.merge(d,this.optionsDefault);this.selected=this.options.value;this.setElement(this._template(this.options));this.$select=this.$el.find("#select");this.$icon=this.$el.find("#icon");var c=this;this.$select.on("change",function(){c.value(c.$select.val())});this.on("change",function(){if(c.options.onchange){c.options.onchange(c.value())}});this._refresh();if(!this.options.visible){this.hide()}if(this.options.wait){this.wait()}else{this.show()}},value:function(c){var d=this.selected;if(c!==undefined){this.selected=c;this.$select.val(c)}var e=this.selected;if(e){if(e!=d&&this.options.onchange){this.options.onchange(e)}}return e},first:function(){var c=this.$select.find("option");if(c.length>0){return c.val()}else{return undefined}},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass();this.$icon.addClass("fa fa-caret-down");this.$select.show();this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass();this.$icon.addClass("fa fa-spinner fa-spin");this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",false)},disable:function(){this.$select.prop("disabled",true)},add:function(c){this.$select.append(this._templateOption(c));this._refresh()},del:function(c){this.$select.find("option[value="+c+"]").remove();this.$select.trigger("change");this._refresh()},update:function(c){this.$select.find("option").remove();for(var d in c){this.$select.append(this._templateOption(c[d]))}this._refresh()},setOnChange:function(c){this.options.onchange=c},exists:function(c){return this.$select.find("option[value="+c+"]").length>0},_refresh:function(){this.$select.find("option[value=null]").remove();var c=this.$select.find("option").length;if(c==0){this.disable();this.$select.append(this._templateOption({value:"null",label:this.options.empty}))}else{this.enable()}if(this.selected){this.$select.val(this.selected)}},_templateOption:function(c){return'<option value="'+c.value+'">'+c.label+"</option>"},_template:function(e){var d='<div id="'+e.id+'" class="ui-select"><div class="button"><i id="icon"/></div><select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var f=e.data[key];var c="";if(f.value==e.value||f.value==""){c="selected"}d+='<option value="'+f.value+'" '+c+">"+f.label+"</option>"}d+="</select></div>";return d}});return{View:b}});
\ No newline at end of file
+define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:true,wait:false,multiple:false},initialize:function(d){this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.$select=this.$el.find("#select");this.$icon=this.$el.find("#icon");if(this.options.multiple){this.$select.prop("multiple",true);this.$select.addClass("ui-select-multiple");this.$icon.remove()}else{this.$el.addClass("ui-select")}this.update(this.options.data);if(!this.options.visible){this.hide()}if(this.options.wait){this.wait()}else{this.show()}var c=this;this.$select.on("change",function(){c._change()});this.on("change",function(){c._change()})},value:function(c){if(c!==undefined){this.$select.val(c)}return this.$select.val()},first:function(){var c=this.$select.find("option");if(c.length>0){return c.val()}else{return undefined}},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass();this.$icon.addClass("fa fa-caret-down");this.$select.show();this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass();this.$icon.addClass("fa fa-spinner fa-spin");this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",false)},disable:function(){this.$select.prop("disabled",true)},add:function(c){this.$select.append(this._templateOption(c));this._refresh()},del:function(c){this.$select.find("option[value="+c+"]").remove();this.$select.trigger("change");this._refresh()},update:function(c){var e=this.$select.val();this.$select.find("option").remove();for(var d in c){this.$select.append(this._templateOption(c[d]))}this._refresh();this.$select.val(e);if(!this.$select.val()){this.$select.val(this.first())}},setOnChange:function(c){this.options.onchange=c},exists:function(c){return this.$select.find("option[value="+c+"]").length>0},_change:function(){if(this.options.onchange){this.options.onchange(this.$select.val())}},_refresh:function(){this.$select.find("option[value=null]").remove();var c=this.$select.find("option").length;if(c==0){this.disable();this.$select.append(this._templateOption({value:"null",label:this.options.empty}))}else{this.enable()}},_templateOption:function(c){return'<option value="'+c.value+'">'+c.label+"</option>"},_template:function(c){return'<div id="'+c.id+'"><div class="button"><i id="icon"/></div><select id="select" class="select '+c.cls+" "+c.id+'"></select></div>'}});return{View:b}});
\ No newline at end of file
diff -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c -r fd25aea901ca120e8ac085e83c3835abb09e6e28 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1282,6 +1282,7 @@
.ui-table tbody{cursor:pointer}
.ui-table-plain tbody td{padding:5px 0px 5px 5px !important;border:none !important}
.ui-table-plain tbody{cursor:auto !important}
+.ui-table-form-info{clear:both !important}
.ui-table-form-separator{font-weight:bold;font-size:0.9em}
.ui-label{font-weight:bold}
.ui-message{padding:2px 2px 2px 10px}
@@ -1299,8 +1300,9 @@
.ui-portlet .no-scroll{height:calc(100% - 80px)}
.ui-popover{max-width:700px;display:none}.ui-popover .popover-close{position:absolute;right:10px;top:7px;font-size:1.2em;cursor:pointer}
.ui-popover .popover-title{padding:4px 10px}
-.ui-select{position:relative;height:27px;overflow:hidden;border:1px solid #bfbfbf;-moz-border-radius:3px;border-radius:3px}.ui-select .button{position:relative;width:25px;height:100%;float:right;border-left:1px solid #bfbfbf;padding-left:9px;padding-top:4px;background:#f2f2f2}
+.ui-select,.ui-select-multiple{position:relative;height:27px;overflow:hidden;border:1px solid #bfbfbf;-moz-border-radius:3px;border-radius:3px}.ui-select .button{position:relative;width:25px;height:100%;float:right;border-left:1px solid #bfbfbf;padding-left:9px;padding-top:4px;background:#f2f2f2}
.ui-select select{position:absolute;top:0px;height:100%;width:100%;padding-left:5px;cursor:pointer;background:transparent;border:0;border-radius:0;-webkit-appearance:none}
+.ui-select-multiple{height:100% !important;width:100% !important}
.libraryRow{background-color:#ebd9b2}
.datasetHighlighted{background-color:#f9f9f9}
.libraryItemDeleted-True{font-style:italic}
diff -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c -r fd25aea901ca120e8ac085e83c3835abb09e6e28 static/style/src/less/ui.less
--- a/static/style/src/less/ui.less
+++ b/static/style/src/less/ui.less
@@ -32,6 +32,7 @@
.ui-table-form-info {
&:extend(.toolParamHelp);
+ clear: both !important;
}
.ui-table-form-separator {
@@ -208,4 +209,10 @@
border-radius: 0;
-webkit-appearance: none;
}
+}
+
+.ui-select-multiple {
+ &:extend(.ui-select);
+ height: 100% !important;
+ width: 100% !important;
}
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Fix tool rerunning for data_collection parameters.
by commits-noreply@bitbucket.org 03 Sep '14
by commits-noreply@bitbucket.org 03 Sep '14
03 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e8453771b1db/
Changeset: e8453771b1db
Branch: stable
User: jmchilton
Date: 2014-09-03 22:05:29
Summary: Fix tool rerunning for data_collection parameters.
Bug report from takadonet - https://gist.github.com/Takadonet/ba21ca26748a459615e3. My testing shows this fixes that bug and likewise he confirmed the fix works.
Affected #: 1 file
diff -r 8b183d7571ab1180f8a82e0dfbaf57b098cc50a6 -r e8453771b1dbfe462974b63216e00752fb8c4097 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -2096,6 +2096,8 @@
elif isinstance( value, basestring ):
if value.startswith( "dce:" ):
rval = trans.sa_session.query( trans.app.model.DatasetCollectionElement ).get( value[ len( "dce:"): ] )
+ elif value.startswith( "hdca:" ):
+ rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( value[ len( "hdca:"): ] )
else:
rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( value )
if rval and isinstance( rval, trans.app.model.HistoryDatasetCollectionAssociation ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: ToolForm: Adjust textarea element
by commits-noreply@bitbucket.org 03 Sep '14
by commits-noreply@bitbucket.org 03 Sep '14
03 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6070f4fbb38f/
Changeset: 6070f4fbb38f
User: guerler
Date: 2014-09-03 22:47:14
Summary: ToolForm: Adjust textarea element
Affected #: 7 files
diff -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -248,6 +248,10 @@
def get_initial_value( self, trans, context, history=None ):
return self.value
+ def to_dict( self, trans, view='collection', value_mapper=None ):
+ d = super(TextToolParameter, self).to_dict(trans)
+ d['area'] = self.area
+ return d
class IntegerToolParameter( TextToolParameter ):
"""
@@ -460,7 +464,7 @@
return self.falsevalue
def to_dict( self, trans, view='collection', value_mapper=None ):
- d = super( ToolParameter, self ).to_dict()
+ d = super(BooleanToolParameter, self).to_dict(trans)
d['value'] = self.checked
d['truevalue'] = self.truevalue
d['falsevalue'] = self.falsevalue
diff -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c static/scripts/mvc/tools/tools-section.js
--- a/static/scripts/mvc/tools/tools-section.js
+++ b/static/scripts/mvc/tools/tools-section.js
@@ -204,11 +204,6 @@
case 'data_column':
field = this._field_column(input_def);
break;
-
- // text area field
- case 'textarea' :
- field = this._field_textarea(input_def);
- break;
// conditional select field
case 'conditional':
@@ -427,6 +422,11 @@
break;
}
+ // force checkboxes if multiple has been selected
+ if (input_def.multiple) {
+ SelectClass = Ui.Checkbox;
+ }
+
// select field
return new SelectClass.View({
id : 'field-' + input_def.id,
@@ -443,7 +443,11 @@
// text input field
_field_text : function(input_def) {
- return new Ui.Input({
+ var TextClass = Ui.Input;
+ if (input_def.area) {
+ TextClass = Ui.Textarea;
+ }
+ return new TextClass({
id : 'field-' + input_def.id
});
},
@@ -458,13 +462,6 @@
});
},
- // text area
- _field_textarea : function(input_def) {
- return new Ui.Textarea({
- id : 'field-' + input_def.id
- });
- },
-
// hidden field
_field_hidden : function(input_def) {
return new Ui.Hidden({
diff -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c static/scripts/mvc/ui/ui-misc.js
--- a/static/scripts/mvc/ui/ui-misc.js
+++ b/static/scripts/mvc/ui/ui-misc.js
@@ -405,7 +405,7 @@
// element
_template: function(options) {
- return '<textarea id="' + options.id + '" class="ui-textarea ' + options.cls + '" rows="5"></textarea>';
+ return '<textarea id="' + options.id + '" class="ui-textarea ' + options.cls + '"></textarea>';
}
});
diff -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c static/scripts/packed/mvc/tools/tools-section.js
--- a/static/scripts/packed/mvc/tools/tools-section.js
+++ b/static/scripts/packed/mvc/tools/tools-section.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;f.cls_tr="section-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f])}},_add:function(h){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f)}},_addConditional:function(f){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f);for(var h in f.cases){var g=f.id+"-section-"+h;var j=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(j.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(h,f){var j=f.id;var g=null;switch(h){case"text":g=this._field_text(f);break;case"select":g=this._field_select(f);break;case"data":g=this._field_data(f);break;case"data_column":g=this._field_column(f);break;case"textarea":g=this._field_textarea(f);break;case"conditional":g=this._field_conditional(f);break;case"hidden":g=this._field_hidden(f);break;case"integer":g=this._field_slider(f);break;case"float":g=this._field_slider(f);break;case"boolean":g=this._field_boolean(f);break;default:g=this._field_text(f);console.debug("tools-form::_addRow() : Unmatched field type ("+h+").")}if(f.value!==undefined){g.value(f.value)}this.app.field_list[j]=g;var i=$("<div/>");i.append(g.$el);if(f.help){i.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(i);this.table.append(j)},_field_conditional:function(f){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}return new e.Select.View({id:"field-"+f.id,data:h,onchange:function(s){for(var q in f.cases){var m=f.cases[q];var p=f.id+"-section-"+q;var l=g.table.get(p);var o=false;for(var n in m.inputs){var r=m.inputs[n].type;if(r&&r!=="hidden"){o=true;break}}if(m.value==s&&o){l.fadeIn("fast")}else{l.hide()}}}})},_field_data:function(f){var g=this;var l=f.id;var k=this.app.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+l,data:h,value:h[0].value,onchange:function(u){var s=g.app.tree.findReferences(l,"data_column");var n=g.app.datasets.filter(u);if(n&&s.length>0){console.debug("tool-form::field_data() - Selected dataset "+u+".");var w=n.get("metadata_column_types");if(!w){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+u+".")}for(var p in s){var q=g.app.input_list[s[p]];var r=g.app.field_list[s[p]];if(!q||!r){console.debug("tool-form::field_data() - FAILED: Column not found.")}var o=q.numerical;var m=[];for(var v in w){var t=w[v];if(t=="int"||t=="float"||!o){m.push({label:"Column: "+(parseInt(v)+1)+" ["+w[v]+"]",value:v})}}if(r){r.update(m);if(!r.exists(r.value())){r.value(r.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+u+".")}}})},_field_select:function(f){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;switch(f.display){case"checkboxes":k=e.Checkbox;break;case"radio":k=e.RadioButton;break}return new k.View({id:"field-"+f.id,data:g})},_field_column:function(f){return new e.Select.View({id:"field-"+f.id})},_field_text:function(f){return new e.Input({id:"field-"+f.id})},_field_slider:function(f){return new e.Slider.View({id:"field-"+f.id,min:f.min||0,max:f.max||1000,decimal:f.type=="float"})},_field_textarea:function(f){return new e.Textarea({id:"field-"+f.id})},_field_hidden:function(f){return new e.Hidden({id:"field-"+f.id})},_field_boolean:function(f){return new e.RadioButton.View({id:"field-"+f.id,data:[{label:"Yes",value:true},{label:"No",value:false}]})}});return{View:d}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;f.cls_tr="section-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f])}},_add:function(h){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f)}},_addConditional:function(f){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f);for(var h in f.cases){var g=f.id+"-section-"+h;var j=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(j.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(h,f){var j=f.id;var g=null;switch(h){case"text":g=this._field_text(f);break;case"select":g=this._field_select(f);break;case"data":g=this._field_data(f);break;case"data_column":g=this._field_column(f);break;case"conditional":g=this._field_conditional(f);break;case"hidden":g=this._field_hidden(f);break;case"integer":g=this._field_slider(f);break;case"float":g=this._field_slider(f);break;case"boolean":g=this._field_boolean(f);break;default:g=this._field_text(f);console.debug("tools-form::_addRow() : Unmatched field type ("+h+").")}if(f.value!==undefined){g.value(f.value)}this.app.field_list[j]=g;var i=$("<div/>");i.append(g.$el);if(f.help){i.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(i);this.table.append(j)},_field_conditional:function(f){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}return new e.Select.View({id:"field-"+f.id,data:h,onchange:function(s){for(var q in f.cases){var m=f.cases[q];var p=f.id+"-section-"+q;var l=g.table.get(p);var o=false;for(var n in m.inputs){var r=m.inputs[n].type;if(r&&r!=="hidden"){o=true;break}}if(m.value==s&&o){l.fadeIn("fast")}else{l.hide()}}}})},_field_data:function(f){var g=this;var l=f.id;var k=this.app.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+l,data:h,value:h[0].value,onchange:function(u){var s=g.app.tree.findReferences(l,"data_column");var n=g.app.datasets.filter(u);if(n&&s.length>0){console.debug("tool-form::field_data() - Selected dataset "+u+".");var w=n.get("metadata_column_types");if(!w){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+u+".")}for(var p in s){var q=g.app.input_list[s[p]];var r=g.app.field_list[s[p]];if(!q||!r){console.debug("tool-form::field_data() - FAILED: Column not found.")}var o=q.numerical;var m=[];for(var v in w){var t=w[v];if(t=="int"||t=="float"||!o){m.push({label:"Column: "+(parseInt(v)+1)+" ["+w[v]+"]",value:v})}}if(r){r.update(m);if(!r.exists(r.value())){r.value(r.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+u+".")}}})},_field_select:function(f){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;switch(f.display){case"checkboxes":k=e.Checkbox;break;case"radio":k=e.RadioButton;break}if(f.multiple){k=e.Checkbox}return new k.View({id:"field-"+f.id,data:g})},_field_column:function(f){return new e.Select.View({id:"field-"+f.id})},_field_text:function(g){var f=e.Input;if(g.area){f=e.Textarea}return new f({id:"field-"+g.id})},_field_slider:function(f){return new e.Slider.View({id:"field-"+f.id,min:f.min||0,max:f.max||1000,decimal:f.type=="float"})},_field_hidden:function(f){return new e.Hidden({id:"field-"+f.id})},_field_boolean:function(f){return new e.RadioButton.View({id:"field-"+f.id,data:[{label:"Yes",value:true},{label:"No",value:false}]})}});return{View:d}});
\ No newline at end of file
diff -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c static/scripts/packed/mvc/ui/ui-misc.js
--- a/static/scripts/packed/mvc/ui/ui-misc.js
+++ b/static/scripts/packed/mvc/ui/ui-misc.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-checkbox","mvc/ui/ui-radiobutton","mvc/ui/ui-button-menu","mvc/ui/ui-modal"],function(e,h,k,i,b,r,c){var q=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(s){return'<img class="ui-image '+s.cls+'" src="'+s.url+'"/>'}});var l=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},title:function(s){this.$el.html(s)},_template:function(s){return'<label class="ui-label '+s.cls+'">'+s.title+"</label>"},value:function(){return options.title}});var d=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){return'<div><span class="fa '+s.icon+'" class="ui-icon"/> '+s.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"btn btn-default",icon:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick);$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t='<button id="'+s.id+'" type="submit" style="float: '+s.floating+';" type="button" class="ui-button '+s.cls+'">';if(s.icon){t+='<i class="icon fa '+s.icon+'"></i> '}t+=s.title+"</button>";return t}});var o=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"icon-btn",icon:"",tooltip:"",onclick:null},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick);$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t="";if(s.title){t="width: auto;"}var u='<div id="'+s.id+'" style="float: '+s.floating+"; "+t+'" class="ui-button-icon '+s.cls+'">';if(s.title){u+='<div class="button"><i class="icon fa '+s.icon+'"/> <span class="title">'+s.title+"</span></div>"}else{u+='<i class="icon fa '+s.icon+'"/>'}u+="</div>";return u}});var p=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick)},_template:function(s){return'<div><a href="javascript:void(0)" class="ui-anchor '+s.cls+'">'+s.title+"</a></div>"}});var a=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:false},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(t.message);this.$el.fadeIn();if(!t.persistent){var s=this;window.setTimeout(function(){if(s.$el.is(":visible")){s.$el.fadeOut()}else{s.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(s){return'<div class="ui-message alert alert-'+s.status+'"/>'}});var f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));var s=this;if(this.options.onclick){this.$el.on("submit",function(v){var u=s.$el.find("#search");s.options.onclick(u.val())})}},_template:function(s){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+s.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var n=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<input id="'+s.id+'" type="'+s.type+'" value="'+s.value+'" placeholder="'+s.placeholder+'" class="ui-input '+s.cls+'">'}});var j=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<textarea id="'+s.id+'" class="ui-textarea '+s.cls+'" rows="5"></textarea>'}});var m=Backbone.View.extend({optionsDefault:{value:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<hidden id="'+s.id+'" value="'+s.value+'"/>'}});return{Anchor:p,Button:g,ButtonIcon:o,ButtonMenu:r,Icon:d,Image:q,Input:n,Label:l,Message:a,Modal:c,RadioButton:b,Checkbox:i,Searchbox:f,Select:h,Textarea:j,Hidden:m,Slider:k}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-checkbox","mvc/ui/ui-radiobutton","mvc/ui/ui-button-menu","mvc/ui/ui-modal"],function(e,h,k,i,b,r,c){var q=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(s){return'<img class="ui-image '+s.cls+'" src="'+s.url+'"/>'}});var l=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},title:function(s){this.$el.html(s)},_template:function(s){return'<label class="ui-label '+s.cls+'">'+s.title+"</label>"},value:function(){return options.title}});var d=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){return'<div><span class="fa '+s.icon+'" class="ui-icon"/> '+s.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"btn btn-default",icon:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick);$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t='<button id="'+s.id+'" type="submit" style="float: '+s.floating+';" type="button" class="ui-button '+s.cls+'">';if(s.icon){t+='<i class="icon fa '+s.icon+'"></i> '}t+=s.title+"</button>";return t}});var o=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"icon-btn",icon:"",tooltip:"",onclick:null},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick);$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t="";if(s.title){t="width: auto;"}var u='<div id="'+s.id+'" style="float: '+s.floating+"; "+t+'" class="ui-button-icon '+s.cls+'">';if(s.title){u+='<div class="button"><i class="icon fa '+s.icon+'"/> <span class="title">'+s.title+"</span></div>"}else{u+='<i class="icon fa '+s.icon+'"/>'}u+="</div>";return u}});var p=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick)},_template:function(s){return'<div><a href="javascript:void(0)" class="ui-anchor '+s.cls+'">'+s.title+"</a></div>"}});var a=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:false},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(t.message);this.$el.fadeIn();if(!t.persistent){var s=this;window.setTimeout(function(){if(s.$el.is(":visible")){s.$el.fadeOut()}else{s.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(s){return'<div class="ui-message alert alert-'+s.status+'"/>'}});var f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));var s=this;if(this.options.onclick){this.$el.on("submit",function(v){var u=s.$el.find("#search");s.options.onclick(u.val())})}},_template:function(s){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+s.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var n=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<input id="'+s.id+'" type="'+s.type+'" value="'+s.value+'" placeholder="'+s.placeholder+'" class="ui-input '+s.cls+'">'}});var j=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<textarea id="'+s.id+'" class="ui-textarea '+s.cls+'"></textarea>'}});var m=Backbone.View.extend({optionsDefault:{value:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<hidden id="'+s.id+'" value="'+s.value+'"/>'}});return{Anchor:p,Button:g,ButtonIcon:o,ButtonMenu:r,Icon:d,Image:q,Input:n,Label:l,Message:a,Modal:c,RadioButton:b,Checkbox:i,Searchbox:f,Select:h,Textarea:j,Hidden:m,Slider:k}});
\ No newline at end of file
diff -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -148,7 +148,7 @@
.form-control::-moz-placeholder{color:#999}
.form-control:-ms-input-placeholder{color:#999}
.form-control::-webkit-input-placeholder{color:#999}
-.form-control,.ui-input{display:block;width:100%;height:27px;padding:4px 10px;font-size:12px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #aaa;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}
+.form-control,.ui-input,.ui-textarea{display:block;width:100%;height:27px;padding:4px 10px;font-size:12px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #aaa;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}
.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}
textarea.form-control{height:auto}
.form-group{margin-bottom:15px}
@@ -1289,6 +1289,7 @@
.ui-button-icon{margin-right:5px}.ui-button-icon ul i{font-size:1.2em;margin-right:5px;position:relative;top:1px}
.ui-button-icon .button{margin-right:5px;margin-left:5px}
.ui-button-icon .title{position:relative;font-size:0.8em;font-weight:normal;top:-1px}
+.ui-textarea{height:100px !important}
.ui-tabs .ui-tabs-add{font-size:0.8em;margin-right:5px}
.ui-tabs .ui-tabs-delete{font-size:0.8em;margin-left:5px;cursor:pointer}
.no-highlight{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none;}
diff -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae -r 6070f4fbb38f88eb98cf65f0477924ffea9bc10c static/style/src/less/ui.less
--- a/static/style/src/less/ui.less
+++ b/static/style/src/less/ui.less
@@ -76,6 +76,11 @@
&:extend(.form-control);
}
+.ui-textarea {
+ &:extend(.form-control);
+ height: 100px !important;
+}
+
.ui-tabs {
.ui-tabs-add {
font-size : 0.8em;
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: ToolForm: Adjustments and refactoring
by commits-noreply@bitbucket.org 03 Sep '14
by commits-noreply@bitbucket.org 03 Sep '14
03 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e5e05b2b242a/
Changeset: e5e05b2b242a
User: guerler
Date: 2014-09-03 21:30:50
Summary: ToolForm: Adjustments and refactoring
Affected #: 9 files
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -459,6 +459,13 @@
else:
return self.falsevalue
+ def to_dict( self, trans, view='collection', value_mapper=None ):
+ d = super( ToolParameter, self ).to_dict()
+ d['value'] = self.checked
+ d['truevalue'] = self.truevalue
+ d['falsevalue'] = self.falsevalue
+ return d
+
@property
def legal_values( self ):
return [ self.truevalue, self.falsevalue ]
@@ -992,7 +999,8 @@
value = option[1]
d[ 'value' ] = value
- d[ 'display' ] = self.display
+ d['display'] = self.display
+ d['multiple'] = self.multiple
return d
@@ -1251,7 +1259,10 @@
d = super( ColumnListParameter, self ).to_dict( trans )
# add data reference
- d[ 'data_ref' ] = self.data_ref
+ d['data_ref'] = self.data_ref
+
+ # add numerical flag
+ d['numerical'] = self.numerical
# return
return d
@@ -2008,6 +2019,11 @@
ref = ref()
return ref
+ def to_dict( self, trans, view='collection', value_mapper=None ):
+ d = super( DataToolParameter, self ).to_dict( trans )
+ d['extensions'] = self.extensions
+ d['multiple'] = self.multiple
+ return d
class DataCollectionToolParameter( BaseDataToolParameter ):
"""
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae static/scripts/mvc/tools/tools-form.js
--- a/static/scripts/mvc/tools/tools-form.js
+++ b/static/scripts/mvc/tools/tools-form.js
@@ -38,9 +38,6 @@
// reset sequential input definition list
this.input_list = {};
- // create data model
- this.data = new Backbone.Model();
-
// initialize datasets
this.datasets = new ToolDatasets({
success: function() {
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae static/scripts/mvc/tools/tools-section.js
--- a/static/scripts/mvc/tools/tools-section.js
+++ b/static/scripts/mvc/tools/tools-section.js
@@ -11,12 +11,6 @@
// link inputs
this.inputs = options.inputs;
- // link datasets
- this.datasets = app.datasets;
-
- // link data model
- this.data = app.data;
-
// add table class for tr tag
// this assist in transforming the form into a json structure
options.cls_tr = 'section-row';
@@ -38,12 +32,12 @@
// load settings elements into table
for (var i in this.inputs) {
- this._add(this.inputs[i], this.data);
+ this._add(this.inputs[i]);
}
},
// add table row
- _add: function(input, data) {
+ _add: function(input) {
// link this
var self = this;
@@ -61,7 +55,7 @@
switch(type) {
// conditional field
case 'conditional':
- this._addConditional(input_def, data);
+ this._addConditional(input_def);
break;
// repeat block
case 'repeat':
@@ -69,12 +63,12 @@
break;
// default single element row
default:
- this._addRow(type, input_def, data);
+ this._addRow(type, input_def);
}
},
// add conditional block
- _addConditional: function(input_def, data) {
+ _addConditional: function(input_def) {
// add label to input definition root
input_def.label = input_def.test_param.label;
@@ -82,7 +76,7 @@
input_def.value = input_def.test_param.value;
// build options field
- this._addRow('conditional', input_def, data);
+ this._addRow('conditional', input_def);
// add fields
for (var i in input_def.cases) {
@@ -182,7 +176,7 @@
},
// add table row
- _addRow: function(field_type, input_def, data) {
+ _addRow: function(field_type, input_def) {
// get id
var id = input_def.id;
@@ -193,65 +187,64 @@
switch(field_type) {
// text input field
case 'text' :
- field = this._field_text(input_def, data);
+ field = this._field_text(input_def);
break;
// select field
case 'select' :
- field = this._field_select(input_def, data);
+ field = this._field_select(input_def);
break;
- // radiobox field
- case 'radiobutton' :
- field = this._field_radio(input_def, data);
- break;
-
// dataset
case 'data':
- field = this._field_data(input_def, data);
+ field = this._field_data(input_def);
break;
// dataset column
case 'data_column':
- field = this._field_column(input_def, data);
+ field = this._field_column(input_def);
break;
// text area field
case 'textarea' :
- field = this._field_textarea(input_def, data);
+ field = this._field_textarea(input_def);
break;
// conditional select field
case 'conditional':
- field = this._field_conditional(input_def, data);
+ field = this._field_conditional(input_def);
break;
// hidden field
case 'hidden':
- field = this._field_hidden(input_def, data);
+ field = this._field_hidden(input_def);
break;
// integer field
case 'integer':
- field = this._field_integer(input_def, data);
+ field = this._field_slider(input_def);
break;
+ // float field
+ case 'float':
+ field = this._field_slider(input_def);
+ break;
+
// boolean field
case 'boolean':
- field = this._field_radiobutton(input_def, data);
+ field = this._field_boolean(input_def);
break;
// default
default:
- field = this._field_text(input_def, data);
+ field = this._field_text(input_def);
console.debug('tools-form::_addRow() : Unmatched field type (' + field_type + ').');
}
- // set value
- if (!data.get(id)) {
- data.set(id, input_def.value);
+ // set field value
+ if (input_def.value !== undefined) {
+ field.value(input_def.value);
}
- field.value(data.get(id));
// add to field list
this.app.field_list[id] = field;
@@ -272,7 +265,7 @@
},
// conditional input field
- _field_conditional : function(input_def, data) {
+ _field_conditional : function(input_def) {
// link this
var self = this;
@@ -287,15 +280,10 @@
}
// select field
- var id = input_def.id;
return new Ui.Select.View({
- id : 'field-' + id,
+ id : 'field-' + input_def.id,
data : options,
- value : data.get(id),
onchange : function(value) {
- // update value
- data.set(id, value);
-
// check value in order to hide/show options
for (var i in input_def.cases) {
// get case
@@ -329,7 +317,7 @@
},
// data input field
- _field_data : function(input_def, data) {
+ _field_data : function(input_def) {
// link this
var self = this;
@@ -337,7 +325,7 @@
var id = input_def.id;
// get datasets
- var datasets = this.datasets.filterType();
+ var datasets = this.app.datasets.filterType();
// configure options fields
var options = [];
@@ -354,14 +342,11 @@
data : options,
value : options[0].value,
onchange : function(value) {
- // update value
- data.set(id, value);
-
// get referenced columns
- var column_list = self.app.tree.findReferences(id);
+ var column_list = self.app.tree.findReferences(id, 'data_column');
// find selected dataset
- var dataset = self.datasets.filter(value);
+ var dataset = self.app.datasets.filter(value);
// check dataset
if (dataset && column_list.length > 0) {
@@ -376,19 +361,34 @@
console.debug('tool-form::field_data() - FAILED: Could not find metadata for dataset ' + value + '.');
}
- // load column options
- var columns = [];
- for (var key in meta) {
- // add to selection
- columns.push({
- 'label' : 'Column: ' + (parseInt(key) + 1) + ' [' + meta[key] + ']',
- 'value' : key
- });
- }
-
// update referenced columns
for (var i in column_list) {
- var column_field = self.app.field_list[column_list[i]]
+ // get column input/field
+ var column_input = self.app.input_list[column_list[i]];
+ var column_field = self.app.field_list[column_list[i]];
+ if (!column_input || !column_field) {
+ console.debug('tool-form::field_data() - FAILED: Column not found.');
+ }
+
+ // is numerical?
+ var numerical = column_input.numerical;
+
+ // identify column options
+ var columns = [];
+ for (var key in meta) {
+ // get column type
+ var column_type = meta[key];
+
+ // add to selection
+ if (column_type == 'int' || column_type == 'float' || !numerical) {
+ columns.push({
+ 'label' : 'Column: ' + (parseInt(key) + 1) + ' [' + meta[key] + ']',
+ 'value' : key
+ });
+ }
+ }
+
+ // update field
if (column_field) {
column_field.update(columns);
if (!column_field.exists(column_field.value())) {
@@ -404,20 +404,8 @@
});
},
- // column selection field
- _field_column : function (input_def, data) {
- var id = input_def.id;
- return new Ui.Select.View({
- id : 'field-' + id,
- value : data.get(id),
- onchange : function(value) {
- data.set(id, value);
- }
- });
- },
-
// select field
- _field_select : function (input_def, data) {
+ _field_select : function (input_def) {
// configure options fields
var options = [];
for (var i in input_def.options) {
@@ -430,95 +418,66 @@
// identify display type
var SelectClass = Ui.Select;
- if (input_def.display == 'checkboxes') {
- SelectClass = Ui.Checkbox;
+ switch (input_def.display) {
+ case 'checkboxes':
+ SelectClass = Ui.Checkbox;
+ break;
+ case 'radio':
+ SelectClass = Ui.RadioButton;
+ break;
}
// select field
- var id = input_def.id;
return new SelectClass.View({
- id : 'field-' + id,
- data : options,
- value : data.get(id),
- onchange : function(value) {
- data.set(id, value);
- }
+ id : 'field-' + input_def.id,
+ data : options
});
},
-
+
+ // column selection field
+ _field_column : function (input_def) {
+ return new Ui.Select.View({
+ id : 'field-' + input_def.id
+ });
+ },
+
// text input field
- _field_text : function(input_def, data) {
- var id = input_def.id;
+ _field_text : function(input_def) {
return new Ui.Input({
- id : 'field-' + id,
- value : data.get(id),
- onchange : function(value) {
- data.set(id, value);
- }
+ id : 'field-' + input_def.id
});
},
// integer field
- _field_integer: function(input_def, data) {
- var id = input_def.id;
+ _field_slider: function(input_def) {
return new Ui.Slider.View({
- id : 'field-' + id,
- value : data.get(id),
- onchange : function(value) {
- data.set(id, value);
- }
+ id : 'field-' + input_def.id,
+ min : input_def.min || 0,
+ max : input_def.max || 1000,
+ decimal : input_def.type == 'float'
});
},
// text area
- _field_textarea : function(input_def, data) {
- var id = input_def.id;
+ _field_textarea : function(input_def) {
return new Ui.Textarea({
- id : 'field-' + id,
- onchange : function() {
- data.set(id, field.value());
- }
- });
- },
-
- // radio field
- _field_radio : function(input_def, data) {
- var id = input_def.id;
- return new Ui.RadioButton({
- id : 'field-' + id,
- data : input_def.data,
- value : data.get(id),
- onchange : function(value) {
- data.set(id, value);
- }
+ id : 'field-' + input_def.id
});
},
// hidden field
- _field_hidden : function(input_def, data) {
- var id = input_def.id;
+ _field_hidden : function(input_def) {
return new Ui.Hidden({
- id : 'field-' + id,
- value : data.get(id)
+ id : 'field-' + input_def.id
});
},
- // hidden field
- _field_radiobutton : function(input_def, data) {
- var id = input_def.id;
+ // boolean field
+ _field_boolean : function(input_def) {
return new Ui.RadioButton.View({
- id : 'field-' + id,
- value : data.get(id),
- data : [
- {
- label : 'Yes',
- value : 'true'
- },
- {
- label : 'No',
- value : 'false'
- }
- ]
+ id : 'field-' + input_def.id,
+ data : [ { label : 'Yes', value : true },
+ { label : 'No', value : false }]
});
}
});
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae static/scripts/mvc/tools/tools-tree.js
--- a/static/scripts/mvc/tools/tools-tree.js
+++ b/static/scripts/mvc/tools/tools-tree.js
@@ -66,7 +66,7 @@
},
// find referenced elements
- findReferences: function(identifier) {
+ findReferences: function(identifier, type) {
// referenced elements
var referenced = [];
@@ -105,7 +105,7 @@
}
// check for referenced element
- if (input.data_ref == name) {
+ if (input.data_ref == name && input.type == type) {
list.push(id);
}
}
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae static/scripts/mvc/ui/ui-slider.js
--- a/static/scripts/mvc/ui/ui-slider.js
+++ b/static/scripts/mvc/ui/ui-slider.js
@@ -7,7 +7,9 @@
optionsDefault: {
value : '',
min : 1,
- max : 100
+ max : 100,
+ step : 0.1,
+ decimal : false
},
// initialize
@@ -27,6 +29,11 @@
// backup integer field
this.$text = this.$el.find('#text');
+ // set step size
+ if (!this.options.decimal) {
+ this.options.step = 1;
+ }
+
// load slider plugin
this.$slider.slider(this.options);
@@ -38,7 +45,8 @@
// add text field event
this.$text.on('keydown', function (event) {
var v = event.which;
- if (!(v == 13 || v == 8 || v == 189 || (v >= 48 && v <= 57))) {
+ if (!(v == 13 || v == 8 || v == 37 || v == 39 || v == 189 || (v >= 48 && v <= 57)
+ || (self.options.decimal && $(this).val().indexOf('.') == -1) && v == 190)) {
event.preventDefault();
}
});
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae static/scripts/packed/mvc/tools/tools-form.js
--- a/static/scripts/packed/mvc/tools/tools-form.js
+++ b/static/scripts/packed/mvc/tools/tools-form.js
@@ -1,1 +1,1 @@
-define(["mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/citation/citation-model","mvc/citation/citation-view","mvc/tools","mvc/tools/tools-template","mvc/tools/tools-datasets","mvc/tools/tools-section","mvc/tools/tools-tree"],function(g,k,i,a,f,d,h,j,c){var e=Backbone.Model.extend({initialize:function(l){this.url=galaxy_config.root+"api/tools/"+l.id+"?io_details=true"}});var b=Backbone.View.extend({main_el:"body",initialize:function(m){var l=this;this.options=m;this.model=new e({id:m.id});this.tree=new c(this);this.field_list={};this.input_list={};this.data=new Backbone.Model();this.datasets=new h({success:function(){l._initializeToolForm()}})},_initializeToolForm:function(){var l=this;this.model.fetch({error:function(m){console.debug("tools-form::_initializeToolForm() : Attempt to fetch tool model failed.")},success:function(){l.inputs=l.model.get("inputs");l.portlet=new g.View({icon:"fa-wrench",title:"<b>"+l.model.get("name")+"</b> "+l.model.get("description"),buttons:{execute:new k.ButtonIcon({icon:"fa-check",tooltip:"Execute the tool",title:"Execute",floating:"clear",onclick:function(){console.log(l.tree.create(l))}})}});l.message=new k.Message();l.portlet.append(l.message.$el);$(l.main_el).append(l.portlet.$el);if(l.options.help!=""){$(l.main_el).append(d.help(l.options.help))}if(l.options.citations){$(l.main_el).append(d.citations());var m=new i.ToolCitationCollection();m.tool_id=l.options.id;var n=new a.CitationListView({collection:m});n.render();m.fetch()}l.setElement(l.portlet.content());l.section=new j.View(l,{inputs:l.model.get("inputs")});l.portlet.append(l.section.$el);l.refresh()}})},refresh:function(){this.tree.refresh();for(var l in this.field_list){this.field_list[l].trigger("change")}console.debug("tools-form::refresh() - Recreated tree structure. Refresh.")}});return{View:b}});
\ No newline at end of file
+define(["mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/citation/citation-model","mvc/citation/citation-view","mvc/tools","mvc/tools/tools-template","mvc/tools/tools-datasets","mvc/tools/tools-section","mvc/tools/tools-tree"],function(g,k,i,a,f,d,h,j,c){var e=Backbone.Model.extend({initialize:function(l){this.url=galaxy_config.root+"api/tools/"+l.id+"?io_details=true"}});var b=Backbone.View.extend({main_el:"body",initialize:function(m){var l=this;this.options=m;this.model=new e({id:m.id});this.tree=new c(this);this.field_list={};this.input_list={};this.datasets=new h({success:function(){l._initializeToolForm()}})},_initializeToolForm:function(){var l=this;this.model.fetch({error:function(m){console.debug("tools-form::_initializeToolForm() : Attempt to fetch tool model failed.")},success:function(){l.inputs=l.model.get("inputs");l.portlet=new g.View({icon:"fa-wrench",title:"<b>"+l.model.get("name")+"</b> "+l.model.get("description"),buttons:{execute:new k.ButtonIcon({icon:"fa-check",tooltip:"Execute the tool",title:"Execute",floating:"clear",onclick:function(){console.log(l.tree.create(l))}})}});l.message=new k.Message();l.portlet.append(l.message.$el);$(l.main_el).append(l.portlet.$el);if(l.options.help!=""){$(l.main_el).append(d.help(l.options.help))}if(l.options.citations){$(l.main_el).append(d.citations());var m=new i.ToolCitationCollection();m.tool_id=l.options.id;var n=new a.CitationListView({collection:m});n.render();m.fetch()}l.setElement(l.portlet.content());l.section=new j.View(l,{inputs:l.model.get("inputs")});l.portlet.append(l.section.$el);l.refresh()}})},refresh:function(){this.tree.refresh();for(var l in this.field_list){this.field_list[l].trigger("change")}console.debug("tools-form::refresh() - Recreated tree structure. Refresh.")}});return{View:b}});
\ No newline at end of file
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae static/scripts/packed/mvc/tools/tools-section.js
--- a/static/scripts/packed/mvc/tools/tools-section.js
+++ b/static/scripts/packed/mvc/tools/tools-section.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;this.datasets=g.datasets;this.data=g.data;f.cls_tr="section-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f],this.data)}},_add:function(h,j){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f,j);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f,j)}},_addConditional:function(f,j){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f,j);for(var h in f.cases){var g=f.id+"-section-"+h;var k=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(k.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(i,f,g){var k=f.id;var h=null;switch(i){case"text":h=this._field_text(f,g);break;case"select":h=this._field_select(f,g);break;case"radiobutton":h=this._field_radio(f,g);break;case"data":h=this._field_data(f,g);break;case"data_column":h=this._field_column(f,g);break;case"textarea":h=this._field_textarea(f,g);break;case"conditional":h=this._field_conditional(f,g);break;case"hidden":h=this._field_hidden(f,g);break;case"integer":h=this._field_integer(f,g);break;case"boolean":h=this._field_radiobutton(f,g);break;default:h=this._field_text(f,g);console.debug("tools-form::_addRow() : Unmatched field type ("+i+").")}if(!g.get(k)){g.set(k,f.value)}h.value(g.get(k));this.app.field_list[k]=h;var j=$("<div/>");j.append(h.$el);if(f.help){j.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(j);this.table.append(k)},_field_conditional:function(f,l){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}var m=f.id;return new e.Select.View({id:"field-"+m,data:h,value:l.get(m),onchange:function(u){l.set(m,u);for(var s in f.cases){var o=f.cases[s];var r=f.id+"-section-"+s;var n=g.table.get(r);var q=false;for(var p in o.inputs){var t=o.inputs[p].type;if(t&&t!=="hidden"){q=true;break}}if(o.value==u&&q){n.fadeIn("fast")}else{n.hide()}}}})},_field_data:function(f,l){var g=this;var m=f.id;var k=this.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+m,data:h,value:h[0].value,onchange:function(s){l.set(m,s);var o=g.app.tree.findReferences(m);var u=g.datasets.filter(s);if(u&&o.length>0){console.debug("tool-form::field_data() - Selected dataset "+s+".");var t=u.get("metadata_column_types");if(!t){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+s+".")}var r=[];for(var q in t){r.push({label:"Column: "+(parseInt(q)+1)+" ["+t[q]+"]",value:q})}for(var p in o){var n=g.app.field_list[o[p]];if(n){n.update(r);if(!n.exists(n.value())){n.value(n.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+s+".")}}})},_field_column:function(f,g){var h=f.id;return new e.Select.View({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_select:function(f,l){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;if(f.display=="checkboxes"){k=e.Checkbox}var m=f.id;return new k.View({id:"field-"+m,data:g,value:l.get(m),onchange:function(i){l.set(m,i)}})},_field_text:function(f,g){var h=f.id;return new e.Input({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_integer:function(f,g){var h=f.id;return new e.Slider.View({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_textarea:function(f,g){var h=f.id;return new e.Textarea({id:"field-"+h,onchange:function(){g.set(h,field.value())}})},_field_radio:function(f,g){var h=f.id;return new e.RadioButton({id:"field-"+h,data:f.data,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_hidden:function(f,g){var h=f.id;return new e.Hidden({id:"field-"+h,value:g.get(h)})},_field_radiobutton:function(f,g){var h=f.id;return new e.RadioButton.View({id:"field-"+h,value:g.get(h),data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]})}});return{View:d}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;f.cls_tr="section-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f])}},_add:function(h){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f)}},_addConditional:function(f){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f);for(var h in f.cases){var g=f.id+"-section-"+h;var j=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(j.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(h,f){var j=f.id;var g=null;switch(h){case"text":g=this._field_text(f);break;case"select":g=this._field_select(f);break;case"data":g=this._field_data(f);break;case"data_column":g=this._field_column(f);break;case"textarea":g=this._field_textarea(f);break;case"conditional":g=this._field_conditional(f);break;case"hidden":g=this._field_hidden(f);break;case"integer":g=this._field_slider(f);break;case"float":g=this._field_slider(f);break;case"boolean":g=this._field_boolean(f);break;default:g=this._field_text(f);console.debug("tools-form::_addRow() : Unmatched field type ("+h+").")}if(f.value!==undefined){g.value(f.value)}this.app.field_list[j]=g;var i=$("<div/>");i.append(g.$el);if(f.help){i.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(i);this.table.append(j)},_field_conditional:function(f){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}return new e.Select.View({id:"field-"+f.id,data:h,onchange:function(s){for(var q in f.cases){var m=f.cases[q];var p=f.id+"-section-"+q;var l=g.table.get(p);var o=false;for(var n in m.inputs){var r=m.inputs[n].type;if(r&&r!=="hidden"){o=true;break}}if(m.value==s&&o){l.fadeIn("fast")}else{l.hide()}}}})},_field_data:function(f){var g=this;var l=f.id;var k=this.app.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+l,data:h,value:h[0].value,onchange:function(u){var s=g.app.tree.findReferences(l,"data_column");var n=g.app.datasets.filter(u);if(n&&s.length>0){console.debug("tool-form::field_data() - Selected dataset "+u+".");var w=n.get("metadata_column_types");if(!w){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+u+".")}for(var p in s){var q=g.app.input_list[s[p]];var r=g.app.field_list[s[p]];if(!q||!r){console.debug("tool-form::field_data() - FAILED: Column not found.")}var o=q.numerical;var m=[];for(var v in w){var t=w[v];if(t=="int"||t=="float"||!o){m.push({label:"Column: "+(parseInt(v)+1)+" ["+w[v]+"]",value:v})}}if(r){r.update(m);if(!r.exists(r.value())){r.value(r.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+u+".")}}})},_field_select:function(f){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;switch(f.display){case"checkboxes":k=e.Checkbox;break;case"radio":k=e.RadioButton;break}return new k.View({id:"field-"+f.id,data:g})},_field_column:function(f){return new e.Select.View({id:"field-"+f.id})},_field_text:function(f){return new e.Input({id:"field-"+f.id})},_field_slider:function(f){return new e.Slider.View({id:"field-"+f.id,min:f.min||0,max:f.max||1000,decimal:f.type=="float"})},_field_textarea:function(f){return new e.Textarea({id:"field-"+f.id})},_field_hidden:function(f){return new e.Hidden({id:"field-"+f.id})},_field_boolean:function(f){return new e.RadioButton.View({id:"field-"+f.id,data:[{label:"Yes",value:true},{label:"No",value:false}]})}});return{View:d}});
\ No newline at end of file
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae static/scripts/packed/mvc/tools/tools-tree.js
--- a/static/scripts/packed/mvc/tools/tools-tree.js
+++ b/static/scripts/packed/mvc/tools/tools-tree.js
@@ -1,1 +1,1 @@
-define([],function(){return Backbone.Model.extend({initialize:function(a){this.app=a},refresh:function(){if(!this.app.section){return{}}this.dict={};this.xml=$("<div/>");this._iterate(this.app.section.$el,this.dict,this.xml)},_iterate:function(d,e,b){var a=this;var c=$(d).children();c.each(function(){var i=this;var h=$(i).attr("id");if($(i).hasClass("section-row")||$(i).hasClass("tab-pane")){e[h]={};var f=a.app.input_list[h];if(f){e[h]={input:f}}var g=$('<div id="'+h+'"/>');b.append(g);a._iterate(i,e[h],g)}else{a._iterate(i,e,b)}})},findReferences:function(c){var f=[];var b=this;function d(g,i){var h=$(i).children();var k=[];var j=false;h.each(function(){var n=this;var m=$(n).attr("id");if(m!==c){var l=b.app.input_list[m];if(l){if(l.name==g){j=true;return false}if(l.data_ref==g){k.push(m)}}}});if(!j){f=f.concat(k);h.each(function(){d(g,this)})}}var e=this.xml.find("#"+c);if(e.length>0){var a=this.app.input_list[c];if(a){d(a.name,e.parent())}}return f}})});
\ No newline at end of file
+define([],function(){return Backbone.Model.extend({initialize:function(a){this.app=a},refresh:function(){if(!this.app.section){return{}}this.dict={};this.xml=$("<div/>");this._iterate(this.app.section.$el,this.dict,this.xml)},_iterate:function(d,e,b){var a=this;var c=$(d).children();c.each(function(){var i=this;var h=$(i).attr("id");if($(i).hasClass("section-row")||$(i).hasClass("tab-pane")){e[h]={};var f=a.app.input_list[h];if(f){e[h]={input:f}}var g=$('<div id="'+h+'"/>');b.append(g);a._iterate(i,e[h],g)}else{a._iterate(i,e,b)}})},findReferences:function(c,e){var g=[];var b=this;function d(h,j){var i=$(j).children();var l=[];var k=false;i.each(function(){var o=this;var n=$(o).attr("id");if(n!==c){var m=b.app.input_list[n];if(m){if(m.name==h){k=true;return false}if(m.data_ref==h&&m.type==e){l.push(n)}}}});if(!k){g=g.concat(l);i.each(function(){d(h,this)})}}var f=this.xml.find("#"+c);if(f.length>0){var a=this.app.input_list[c];if(a){d(a.name,f.parent())}}return g}})});
\ No newline at end of file
diff -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 -r e5e05b2b242a99ab7a1c2748057db1f71ebd70ae static/scripts/packed/mvc/ui/ui-slider.js
--- a/static/scripts/packed/mvc/ui/ui-slider.js
+++ b/static/scripts/packed/mvc/ui/ui-slider.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{value:"",min:1,max:100},initialize:function(d){var c=this;this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.$slider=this.$el.find("#slider");this.$text=this.$el.find("#text");this.$slider.slider(this.options);this.$text.on("change",function(){c.value($(this).val())});this.$text.on("keydown",function(f){var e=f.which;if(!(e==13||e==8||e==189||(e>=48&&e<=57))){f.preventDefault()}});this.$slider.on("slide",function(e,f){c.value(f.value)})},value:function(c){if(c!==undefined){c=Math.max(Math.min(c,this.options.max),this.options.min);if(this.options.onchange){this.options.onchange(c)}this.$slider.slider("value",c);this.$text.val(c)}return this.$text.val()},_template:function(c){return'<div id="'+c.id+'" style=""><input id="text" type="text" class="ui-input" style="width: 50px; float: left"/><div id="slider" style="width: calc(100% - 60px); float: left; top: 8px; left: 10px;"/></div>'}});return{View:b}});
\ No newline at end of file
+define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{value:"",min:1,max:100,step:0.1,decimal:false},initialize:function(d){var c=this;this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.$slider=this.$el.find("#slider");this.$text=this.$el.find("#text");if(!this.options.decimal){this.options.step=1}this.$slider.slider(this.options);this.$text.on("change",function(){c.value($(this).val())});this.$text.on("keydown",function(f){var e=f.which;if(!(e==13||e==8||e==37||e==39||e==189||(e>=48&&e<=57)||(c.options.decimal&&$(this).val().indexOf(".")==-1)&&e==190)){f.preventDefault()}});this.$slider.on("slide",function(e,f){c.value(f.value)})},value:function(c){if(c!==undefined){c=Math.max(Math.min(c,this.options.max),this.options.min);if(this.options.onchange){this.options.onchange(c)}this.$slider.slider("value",c);this.$text.val(c)}return this.$text.val()},_template:function(c){return'<div id="'+c.id+'" style=""><input id="text" type="text" class="ui-input" style="width: 50px; float: left"/><div id="slider" style="width: calc(100% - 60px); float: left; top: 8px; left: 10px;"/></div>'}});return{View:b}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Fill out tool test for configured discovered datasets.
by commits-noreply@bitbucket.org 03 Sep '14
by commits-noreply@bitbucket.org 03 Sep '14
03 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ebbc5e725c62/
Changeset: ebbc5e725c62
User: jmchilton
Date: 2014-09-03 21:17:49
Summary: Fill out tool test for configured discovered datasets.
Add new example based on Anton's bamtools split work and label all the outputs as visible - this should likely be the default but until it is might as well demonstrate them as visible since that is how they are most useful.
Affected #: 1 file
diff -r e128330d8e78e3d2d7bbc5f60c7515fab9762626 -r ebbc5e725c62e22926e5c0141aeaa95a3da20239 test/functional/tools/multi_output_configured.xml
--- a/test/functional/tools/multi_output_configured.xml
+++ b/test/functional/tools/multi_output_configured.xml
@@ -10,6 +10,8 @@
echo "3" > subdir2/CUSTOM_3.txt;
mkdir subdir3;
echo "Foo" > subdir3/Foo;
+ echo "mapped reads" > split_bam_.MAPPED.bam;
+ echo "unmapped reads" > split_bam_.UNMAPPED.bam;
</command><inputs><param name="num_param" type="integer" value="7" />
@@ -17,9 +19,10 @@
</inputs><outputs><data format="txt" name="report">
- <discover_datasets pattern="__designation_and_ext__" directory="subdir1" />
- <discover_datasets pattern="CUSTOM_(?P<designation>.+)\.(?P<ext>.+)" directory="subdir2" />
- <discover_datasets pattern="__designation__" directory="subdir3" ext="input" />
+ <discover_datasets pattern="__designation_and_ext__" directory="subdir1" visible="true" />
+ <discover_datasets pattern="CUSTOM_(?P<designation>.+)\.(?P<ext>.+)" directory="subdir2" visible="true" />
+ <discover_datasets pattern="__designation__" directory="subdir3" ext="input" visible="true" />
+ <discover_datasets pattern="split_bam_\.(?P<designation>([A-Z-])\w+)\.bam" ext="txt" visible="true" /></data></outputs><tests>
@@ -45,6 +48,12 @@
<discovered_dataset designation="Foo" ftype="txt"><assert_contents><has_line line="Foo" /></assert_contents></discovered_dataset>
+ <discovered_dataset designation="MAPPED" ftype="txt">
+ <assert_contents><has_line line="mapped reads" /></assert_contents>
+ </discovered_dataset>
+ <discovered_dataset designation="UNMAPPED" ftype="txt">
+ <assert_contents><has_line line="unmapped reads" /></assert_contents>
+ </discovered_dataset></output></test></tests>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: small bugfix and new method in folder manager
by commits-noreply@bitbucket.org 03 Sep '14
by commits-noreply@bitbucket.org 03 Sep '14
03 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e128330d8e78/
Changeset: e128330d8e78
User: martenson
Date: 2014-09-03 17:14:42
Summary: small bugfix and new method in folder manager
Affected #: 1 file
diff -r 3180ca1c1994705a17dedb5d6c4f8373b4f5aae4 -r e128330d8e78e3d2d7bbc5f60c7515fab9762626 lib/galaxy/managers/folders.py
--- a/lib/galaxy/managers/folders.py
+++ b/lib/galaxy/managers/folders.py
@@ -83,7 +83,7 @@
Check whether the folder is accessible to current user.
By default every folder is accessible (contents have their own permissions).
"""
- return True
+ return folder
def get_folder_dict( self, trans, folder ):
"""
@@ -156,6 +156,19 @@
add_library_item_role_list = [ ( add_role.name, trans.security.encode_id( add_role.id ) ) for add_role in add_roles ]
return dict( modify_folder_role_list=modify_folder_role_list, manage_folder_role_list=manage_folder_role_list, add_library_item_role_list=add_library_item_role_list )
+ def can_add_item( self, trans, folder ):
+ """
+ Return true if the user has permissions to add item to the given folder.
+ """
+ if trans.user_is_admin:
+ return True
+ current_user_roles = trans.get_current_user_roles()
+ add_roles = set( trans.app.security_agent.get_roles_for_action( folder, trans.app.security_agent.permitted_actions.LIBRARY_ADD ) )
+ for role in current_user_roles:
+ if role in add_roles:
+ return True
+ return False
+
def cut_the_prefix( self, encoded_folder_id ):
"""
Remove the prefix from the encoded folder id.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Update tag latest_2014.08.11 for changeset 20f4fdf1735a
by commits-noreply@bitbucket.org 03 Sep '14
by commits-noreply@bitbucket.org 03 Sep '14
03 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8b183d7571ab/
Changeset: 8b183d7571ab
Branch: stable
User: natefoo
Date: 2014-09-03 16:00:28
Summary: Update tag latest_2014.08.11 for changeset 20f4fdf1735a
Affected #: 1 file
diff -r 20f4fdf1735aeff23a6e7ab00389781fe3f3142c -r 8b183d7571ab1180f8a82e0dfbaf57b098cc50a6 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -18,4 +18,4 @@
81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04
2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
-ea12550fbc34260ae70bde38db59a4024f35f988 latest_2014.08.11
+20f4fdf1735aeff23a6e7ab00389781fe3f3142c latest_2014.08.11
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Visualizations registry: in universe_wsgi.ini, set default value of visualization_plugins_directory to config/plugins/visualizations
by commits-noreply@bitbucket.org 03 Sep '14
by commits-noreply@bitbucket.org 03 Sep '14
03 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3180ca1c1994/
Changeset: 3180ca1c1994
User: carlfeberhard
Date: 2014-09-03 15:30:27
Summary: Visualizations registry: in universe_wsgi.ini, set default value of visualization_plugins_directory to config/plugins/visualizations
Affected #: 3 files
diff -r 012e6eb765684020eb597d8925e4ca5b58b9d904 -r 3180ca1c1994705a17dedb5d6c4f8373b4f5aae4 lib/galaxy/app.py
--- a/lib/galaxy/app.py
+++ b/lib/galaxy/app.py
@@ -96,11 +96,9 @@
# Load history import/export tools.
load_history_imp_exp_tools( self.toolbox )
# visualizations registry: associates resources with visualizations, controls how to render
- self.visualizations_registry = None
- if self.config.visualization_plugins_directory:
- self.visualizations_registry = VisualizationsRegistry( self,
- directories_setting=self.config.visualization_plugins_directory,
- template_cache_dir=self.config.template_cache )
+ self.visualizations_registry = VisualizationsRegistry( self,
+ directories_setting=self.config.visualization_plugins_directory,
+ template_cache_dir=self.config.template_cache )
# Load security policy.
self.security_agent = self.model.security_agent
self.host_security_agent = galaxy.security.HostAgent( model=self.security_agent.model, permitted_actions=self.security_agent.permitted_actions )
diff -r 012e6eb765684020eb597d8925e4ca5b58b9d904 -r 3180ca1c1994705a17dedb5d6c4f8373b4f5aae4 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -376,8 +376,9 @@
self.fluent_log = string_as_bool( kwargs.get( 'fluent_log', False ) )
self.fluent_host = kwargs.get( 'fluent_host', 'localhost' )
self.fluent_port = int( kwargs.get( 'fluent_port', 24224 ) )
- # visualization plugin framework
- self.visualization_plugins_directory = kwargs.get( 'visualization_plugins_directory', None )
+ # directory where the visualization/registry searches for plugins
+ self.visualization_plugins_directory = kwargs.get(
+ 'visualization_plugins_directory', 'config/plugins/visualizations' )
# Default chunk size for chunkable datatypes -- 64k
self.display_chunk_size = int( kwargs.get( 'display_chunk_size', 65536) )
diff -r 012e6eb765684020eb597d8925e4ca5b58b9d904 -r 3180ca1c1994705a17dedb5d6c4f8373b4f5aae4 universe_wsgi.ini.sample
--- a/universe_wsgi.ini.sample
+++ b/universe_wsgi.ini.sample
@@ -210,8 +210,8 @@
# Visualizations config directory: where to look for individual visualization plugins.
# The path is relative to the Galaxy root dir. To use an absolute path begin the path
-# with '/'.
-visualization_plugins_directory = config/plugins/visualizations
+# with '/'. Defaults to "config/plugins/visualizations".
+#visualization_plugins_directory = config/plugins/visualizations
# Each job is given a unique empty directory as its current working directory.
# This option defines in what parent directory those directories will be
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
15 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d1aad7b7405c/
Changeset: d1aad7b7405c
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Small tweaks to some functional test tools.
Add data labels so the tools works in the workflow editor and added a conditional switches to some with collection params and multiple input data parameters to test some state-y logic in workflow editor.
Affected #: 4 files
diff -r 8e699330dfcd889b02acccb058f16b28c95ac848 -r d1aad7b7405c82c9898e21662affd9e9c9ac7e3b test/functional/tools/collection_mixed_param.xml
--- a/test/functional/tools/collection_mixed_param.xml
+++ b/test/functional/tools/collection_mixed_param.xml
@@ -3,8 +3,19 @@
cat #for $f in $f1# ${f} #end for# $f2 >> $out1;
</command><inputs>
- <param name="f1" type="data_collection" collection_type="paired" />
- <param name="f2" type="data" format="txt" />
+ <param name="f1" type="data_collection" collection_type="paired" label="collection param" />
+ <param name="f2" type="data" format="txt" label="data param" />
+ <conditional name="advanced">
+ <param name="full" type="select" label="Parameter Settings">
+ <option value="no">Use defaults</option>
+ <option value="yes">Full parameter list</option>
+ </param>
+ <when value="yes">
+ <param name="advanced_threshold" type="integer" value="8" />
+ </when>
+ <when value="no">
+ </when>
+ </conditional></inputs><outputs><data format="txt" name="out1" />
diff -r 8e699330dfcd889b02acccb058f16b28c95ac848 -r d1aad7b7405c82c9898e21662affd9e9c9ac7e3b test/functional/tools/collection_paired_test.xml
--- a/test/functional/tools/collection_paired_test.xml
+++ b/test/functional/tools/collection_paired_test.xml
@@ -3,7 +3,7 @@
cat $f1.forward $f1['reverse'] >> $out1;
</command><inputs>
- <param name="f1" type="data_collection" collection_type="paired" />
+ <param name="f1" type="data_collection" collection_type="paired" label="Input pair" /></inputs><outputs><data format="txt" name="out1" />
diff -r 8e699330dfcd889b02acccb058f16b28c95ac848 -r d1aad7b7405c82c9898e21662affd9e9c9ac7e3b test/functional/tools/multi_data_param.xml
--- a/test/functional/tools/multi_data_param.xml
+++ b/test/functional/tools/multi_data_param.xml
@@ -4,8 +4,19 @@
cat #for $f in $f2# ${f} #end for# >> $out2
</command><inputs>
- <param name="f1" type="data" format="txt" multiple="true" />
- <param name="f2" type="data" format="txt" multiple="true" />
+ <param name="f1" type="data" format="txt" multiple="true" label="Data 1" />
+ <param name="f2" type="data" format="txt" multiple="true" label="Data 2" />
+ <conditional name="advanced">
+ <param name="full" type="select" label="Parameter Settings">
+ <option value="no">Use defaults</option>
+ <option value="yes">Full parameter list</option>
+ </param>
+ <when value="yes">
+ <param name="advanced_threshold" type="integer" value="8" />
+ </when>
+ <when value="no">
+ </when>
+ </conditional></inputs><outputs><data format="txt" name="out1" />
diff -r 8e699330dfcd889b02acccb058f16b28c95ac848 -r d1aad7b7405c82c9898e21662affd9e9c9ac7e3b test/qunit/tests/workflow_editor_tests.js
--- a/test/qunit/tests/workflow_editor_tests.js
+++ b/test/qunit/tests/workflow_editor_tests.js
@@ -803,11 +803,12 @@
return node;
},
addOutput: function( terminal, connected ) {
+ var self = this;
var connectedOutput = this.newOutputTerminal();
- var inputTerminal = this.newInputTerminal();
var node = terminal.node;
if( connected ) {
with_workflow_global( function() {
+ var inputTerminal = self.newInputTerminal();
new Connector( inputTerminal, connectedOutput );
} );
}
@@ -818,10 +819,11 @@
return this.addOutput( terminal, true );
},
addConnectedInput: function( terminal ) {
+ var self = this;
var connectedInput = this.newInputTerminal();
- var outputTerminal = this.newOutputTerminal();
var node = terminal.node;
with_workflow_global( function() {
+ var outputTerminal = self.newOutputTerminal();
new Connector( connectedInput, outputTerminal );
} );
this._addTerminalTo( connectedInput, node.input_terminals );
https://bitbucket.org/galaxy/galaxy-central/commits/b63d8c689f25/
Changeset: b63d8c689f25
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Add functional test tool demonstrating special parameters.
:(
Affected #: 2 files
diff -r d1aad7b7405c82c9898e21662affd9e9c9ac7e3b -r b63d8c689f25c7423b72c11455703a90b64ff42d test/functional/tools/samples_tool_conf.xml
--- a/test/functional/tools/samples_tool_conf.xml
+++ b/test/functional/tools/samples_tool_conf.xml
@@ -18,6 +18,7 @@
<tool file="parallelism_optional.xml" /><tool file="implicit_default_conds.xml" /><tool file="multi_data_param.xml" />
+ <tool file="special_params.xml" /><tool file="collection_paired_test.xml" /><tool file="collection_nested_test.xml" /><tool file="collection_mixed_param.xml" />
diff -r d1aad7b7405c82c9898e21662affd9e9c9ac7e3b -r b63d8c689f25c7423b72c11455703a90b64ff42d test/functional/tools/special_params.xml
--- /dev/null
+++ b/test/functional/tools/special_params.xml
@@ -0,0 +1,36 @@
+<tool id="special_params" name="special_params" version="1.0.0">
+ <command>echo $__root_dir__ > out_root_dir;
+ echo $__datatypes_config__ > out_datatypes_config;
+ echo $__admin_users__ > out_admin_users;
+ echo $__user_email__ > out_user_email
+ </command>
+ <inputs>
+ <param name="ignored" type="integer" value="0" />
+ </inputs>
+ <outputs>
+ <data format="txt" name="out_root_dir" from_work_dir="out_root_dir" />
+ <data format="txt" name="out_datatypes_config" from_work_dir="out_datatypes_config" />
+ <data format="txt" name="out_admin_users" from_work_dir="out_admin_users" />
+ <data format="txt" name="out_user_email" from_work_dir="out_user_email" />
+ </outputs>
+ <tests>
+ <test>
+ <output name="out_root_dir">
+ <!-- Is an absolute path. -->
+ <assert_contents><has_line_matching expression="^\/.*$" /></assert_contents>
+ </output>
+ <output name="out_datatypes_config">
+ <!-- Is an absolute path. -->
+ <assert_contents><has_line_matching expression="^\/.*$" /></assert_contents>
+ </output>
+ <output name="out_admin_users">
+ <!-- Has at least on e-mail address. -->
+ <assert_contents><has_text text="@" /></assert_contents>
+ </output>
+ <output name="out_user_email">
+ <!-- Looks like an e-mail address. -->
+ <assert_contents><has_line_matching expression="[^@]+@[^@]+\.[^@]+" /></assert_contents>
+ </output>
+ </test>
+ </tests>
+</tool>
https://bitbucket.org/galaxy/galaxy-central/commits/7dc4090783da/
Changeset: 7dc4090783da
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Add functional test tool demonstrating setting output dataset formats.
Directly setting format attribute, setting to format to 'input' (ambigious, non-deterministic and should be deprecated IMO), using format_source, and using change_format actions.
Affected #: 3 files
diff -r b63d8c689f25c7423b72c11455703a90b64ff42d -r 7dc4090783daea490af1e8b2ad41a3573eaa9eba test/functional/tools/output_format.xml
--- /dev/null
+++ b/test/functional/tools/output_format.xml
@@ -0,0 +1,72 @@
+<tool id="output_format" name="output_format" version="1.0.0">
+ <command>
+ echo "test" > 1;
+ echo "test" > 2;
+ echo "test" > 3;
+ echo "test" > 4;
+ echo "test" > 5;
+ </command>
+ <inputs>
+ <param name="input_data_1" type="data" format="data" />
+ <param name="input_data_2" type="data" format="data" />
+ <param name="input_text" type="text" value="1" />
+ </inputs>
+ <outputs>
+ <data format="txt" from_work_dir="1" name="direct_output" />
+ <!-- TODO: fixme, following input gets random type fastqsanger or
+ fastqsolexa. -->
+ <data format="input" from_work_dir="2" name="input_based_output" />
+ <data format="txt" from_work_dir="3" name="format_source_1_output" format_source="input_data_1" />
+ <data format="txt" from_work_dir="4" name="format_source_2_output" format_source="input_data_2" />
+ <data format="txt" from_work_dir="5" name="change_format_output">
+ <change_format>
+ <when input="input_text" value="foo" format="fastqsolexa" />
+ <when input="input_text" value="bar" format="fastqillumina" />
+ </change_format>
+ </data>
+ </outputs>
+ <tests>
+ <test>
+ <param name="input_data_1" value="1.fastqsanger" ftype="fastqsanger" />
+ <param name="input_data_2" value="1.fastqsolexa" ftype="fastqsolexa" />
+ <param name="input_text" value="foo" />
+ <output name="direct_output" ftype="txt">
+ <assert_contents><has_line line="test" /></assert_contents>
+ </output>
+ <!-- In this case input_based_output ftype is "randomly" either
+ fastqsanger or fastqsolexa -->
+ <output name="format_source_1_output" ftype="fastqsanger">
+ <assert_contents><has_line line="test" /></assert_contents>
+ </output>
+ <output name="format_source_2_output" ftype="fastqsolexa">
+ <assert_contents><has_line line="test" /></assert_contents>
+ </output>
+ <!-- input_text == bar => format set to fastsolexa -->
+ <output name="change_format_action" ftype="fastqsolexa">
+ <assert_contents><has_line line="test" /></assert_contents>
+ </output>
+ </test>
+ <test>
+ <param name="input_data_1" value="1.fastqsanger" ftype="fastqsanger" />
+ <param name="input_data_2" value="1.fastqsanger" ftype="fastqsanger" />
+ <param name="input_text" value="bar" />
+ <output name="input_based_output" ftype="fastqsanger">
+ <assert_contents><has_line line="test" /></assert_contents>
+ </output>
+ <!-- input_text == bar => format set to fastqillumina -->
+ <output name="change_format_action" ftype="fastqillumina">
+ <assert_contents><has_line line="test" /></assert_contents>
+ </output>
+ </test>
+ <test>
+ <param name="input_data_1" value="1.fastqsanger" ftype="fastqsanger" />
+ <param name="input_data_2" value="1.fastqsanger" ftype="fastqsanger" />
+ <param name="input_text" value="not_foo_or_bar" />
+ <!-- input_text doesn't match any when, default to explicitly declared
+ type. -->
+ <output name="change_format_action" ftype="text">
+ <assert_contents><has_line line="test" /></assert_contents>
+ </output>
+ </test>
+ </tests>
+</tool>
diff -r b63d8c689f25c7423b72c11455703a90b64ff42d -r 7dc4090783daea490af1e8b2ad41a3573eaa9eba test/functional/tools/sample_datatypes_conf.xml
--- a/test/functional/tools/sample_datatypes_conf.xml
+++ b/test/functional/tools/sample_datatypes_conf.xml
@@ -4,5 +4,11 @@
<datatype extension="velvet" type="galaxy.datatypes.assembly:Velvet" display_in_upload="true"/><datatype extension="txt" type="galaxy.datatypes.data:Text" display_in_upload="true"/><datatype extension="tabular" type="galaxy.datatypes.tabular:Tabular" display_in_upload="true"/>
+ <datatype extension="fasta" type="galaxy.datatypes.sequence:Fasta" display_in_upload="true" />
+ <datatype extension="fastq" type="galaxy.datatypes.sequence:Fastq" display_in_upload="true" />
+ <datatype extension="fastqsanger" type="galaxy.datatypes.sequence:FastqSanger" display_in_upload="true" />
+ <datatype extension="fastqsolexa" type="galaxy.datatypes.sequence:FastqSolexa" display_in_upload="true" />
+ <datatype extension="fastqcssanger" type="galaxy.datatypes.sequence:FastqCSSanger" display_in_upload="true" />
+ <datatype extension="fastqillumina" type="galaxy.datatypes.sequence:FastqIllumina" display_in_upload="true" /></registration></datatypes>
\ No newline at end of file
diff -r b63d8c689f25c7423b72c11455703a90b64ff42d -r 7dc4090783daea490af1e8b2ad41a3573eaa9eba test/functional/tools/samples_tool_conf.xml
--- a/test/functional/tools/samples_tool_conf.xml
+++ b/test/functional/tools/samples_tool_conf.xml
@@ -12,6 +12,7 @@
<tool file="composite_output.xml" /><tool file="metadata.xml" /><tool file="output_order.xml" />
+ <tool file="output_format.xml" /><tool file="disambiguate_repeats.xml" /><tool file="min_repeat.xml" /><tool file="parallelism.xml" />
https://bitbucket.org/galaxy/galaxy-central/commits/3632736a88ea/
Changeset: 3632736a88ea
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Add functional test tool demonstrating output filters.
Add new 'expect_num_outputs' attribute to 'test' element in tool XML to verify the produced number - needed to test output filtering.
Affected #: 5 files
diff -r 7dc4090783daea490af1e8b2ad41a3573eaa9eba -r 3632736a88ea3541bf64d8ba616e65db94c42b84 lib/galaxy/tools/test.py
--- a/lib/galaxy/tools/test.py
+++ b/lib/galaxy/tools/test.py
@@ -50,6 +50,9 @@
self.required_files = []
self.inputs = []
self.outputs = []
+ self.num_outputs = None # By default do not making assertions on
+ # number of outputs - but to test filtering
+ # allow explicitly state number of outputs.
self.error = False
self.exception = None
@@ -122,6 +125,10 @@
self.__parse_inputs_elems( test_elem, i )
self.outputs = parse_output_elems( test_elem )
+ num_outputs = test_elem.get( 'expect_num_outputs', None )
+ if num_outputs:
+ num_outputs = int( num_outputs )
+ self.num_outputs = num_outputs
except Exception, e:
self.error = True
self.exception = e
diff -r 7dc4090783daea490af1e8b2ad41a3573eaa9eba -r 3632736a88ea3541bf64d8ba616e65db94c42b84 test/base/interactor.py
--- a/test/base/interactor.py
+++ b/test/base/interactor.py
@@ -236,6 +236,9 @@
for output in datasets_object[ 'outputs' ]:
outputs_dict[ index ] = outputs_dict[ output.get("output_name") ] = output
index += 1
+ # Adding each item twice (once with index for backward compat),
+ # overiding length to reflect the real number of outputs.
+ outputs_dict.__len__ = lambda: index
return outputs_dict
def output_hid( self, output_data ):
diff -r 7dc4090783daea490af1e8b2ad41a3573eaa9eba -r 3632736a88ea3541bf64d8ba616e65db94c42b84 test/functional/test_toolbox.py
--- a/test/functional/test_toolbox.py
+++ b/test/functional/test_toolbox.py
@@ -49,7 +49,13 @@
def _verify_outputs( self, testdef, history, shed_tool_id, data_list, galaxy_interactor ):
maxseconds = testdef.maxseconds
-
+ if testdef.num_outputs is not None:
+ expected = testdef.num_outputs
+ actual = len( data_list )
+ if expected != actual:
+ messaage_template = "Incorrect number of outputs - expected %d, found %s."
+ message = messaage_template % ( expected, actual )
+ raise Exception( message )
for output_index, output_tuple in enumerate(testdef.outputs):
# Get the correct hid
name, outfile, attributes = output_tuple
diff -r 7dc4090783daea490af1e8b2ad41a3573eaa9eba -r 3632736a88ea3541bf64d8ba616e65db94c42b84 test/functional/tools/output_filter.xml
--- /dev/null
+++ b/test/functional/tools/output_filter.xml
@@ -0,0 +1,46 @@
+<tool id="output_filter" name="output_filter" version="1.0.0">
+ <command>
+ echo "test" > 1;
+ echo "test" > 2;
+ echo "test" > 3;
+ echo "test" > 4;
+ echo "test" > 5;
+ </command>
+ <inputs>
+ <param name="produce_out_1" type="boolean" truevalue="true" falsevalue="false" checked="False" label="Do Filter 1" />
+ <param name="filter_text_1" type="text" value="1" />
+ </inputs>
+ <outputs>
+ <data format="txt" from_work_dir="1" name="out_1">
+ <filter>produce_out_1 is True</filter>
+ </data>
+ <data format="txt" from_work_dir="2" name="out_2">
+ <filter>filter_text_1 in ["foo", "bar"]</filter>
+ <!-- Must pass all filters... -->
+ <filter>filter_text_1 == "foo"</filter>
+ </data>
+ <data format="txt" from_work_dir="3" name="out_3">
+ </data>
+ </outputs>
+ <tests>
+ <test expect_num_outputs="3">
+ <param name="produce_out_1" value="true" />
+ <param name="filter_text_1" value="foo" />
+ <output name="out_1"><assert_contents><has_line line="test" /></assert_contents></output>
+ <output name="out_2"><assert_contents><has_line line="test" /></assert_contents></output>
+ <output name="out_3"><assert_contents><has_line line="test" /></assert_contents></output>
+ </test>
+ <test expect_num_outputs="2">
+ <param name="produce_out_1" value="true" />
+ <param name="filter_text_1" value="bar" /><!-- fails second filter in out2 -->
+ <output name="out_1"><assert_contents><has_line line="test" /></assert_contents></output>
+ <output name="out_3"><assert_contents><has_line line="test" /></assert_contents></output>
+ </test>
+ <test expect_num_outputs="1">
+ <param name="produce_out_1" value="false" />
+ <param name="filter_text_1" value="not_foo_or_bar" />
+ <output name="out_3"><assert_contents><has_line line="test" /></assert_contents></output>
+ </test>
+ </tests>
+</tool>
+
diff -r 7dc4090783daea490af1e8b2ad41a3573eaa9eba -r 3632736a88ea3541bf64d8ba616e65db94c42b84 test/functional/tools/samples_tool_conf.xml
--- a/test/functional/tools/samples_tool_conf.xml
+++ b/test/functional/tools/samples_tool_conf.xml
@@ -13,6 +13,7 @@
<tool file="metadata.xml" /><tool file="output_order.xml" /><tool file="output_format.xml" />
+ <tool file="output_filter.xml" /><tool file="disambiguate_repeats.xml" /><tool file="min_repeat.xml" /><tool file="parallelism.xml" />
https://bitbucket.org/galaxy/galaxy-central/commits/2287d2496a71/
Changeset: 2287d2496a71
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: PEP-8 fixes for tools/actions/__init__.py.
Affected #: 1 file
diff -r 3632736a88ea3541bf64d8ba616e65db94c42b84 -r 2287d2496a71b05c6c595984c90721c3c743afe6 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -1,18 +1,13 @@
-import os
-
from galaxy.exceptions import ObjectInvalid
from galaxy.model import LibraryDatasetDatasetAssociation
from galaxy import model
from galaxy.tools.parameters import DataToolParameter
from galaxy.tools.parameters import DataCollectionToolParameter
from galaxy.tools.parameters.wrapped import WrappedParameters
-from galaxy.util.json import from_json_string
from galaxy.util.json import to_json_string
from galaxy.util.none_like import NoneDataset
from galaxy.util.odict import odict
from galaxy.util.template import fill_template
-from galaxy.util import listify
-from galaxy.util.json import to_json_string
from galaxy.web import url_for
import logging
@@ -194,8 +189,7 @@
input_dbkey = data.dbkey
# Collect chromInfo dataset and add as parameters to incoming
- db_datasets = {}
- ( chrom_info, db_dataset ) = trans.app.genome_builds.get_chrom_info( input_dbkey, trans=trans, custom_build_hack_get_len_from_fasta_conversion=tool.id!='CONVERTER_fasta_to_len' )
+ ( chrom_info, db_dataset ) = trans.app.genome_builds.get_chrom_info( input_dbkey, trans=trans, custom_build_hack_get_len_from_fasta_conversion=tool.id != 'CONVERTER_fasta_to_len' )
if db_dataset:
inp_data.update( { "chromInfo": db_dataset } )
incoming[ "chromInfo" ] = chrom_info
@@ -238,7 +232,7 @@
if name in incoming:
dataid = incoming[name]
data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( dataid )
- assert data != None
+ assert data is not None
out_data[name] = data
else:
# the type should match the input
https://bitbucket.org/galaxy/galaxy-central/commits/942b4bffc427/
Changeset: 942b4bffc427
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Unit test for galaxy.tools.action to ensure all datasets get same object store id.
Enables subsequent refactoring.
Affected #: 1 file
diff -r 2287d2496a71b05c6c595984c90721c3c743afe6 -r 942b4bffc4277d090e6cd788e706706f56aa1d62 test/unit/tools/test_actions.py
--- a/test/unit/tools/test_actions.py
+++ b/test/unit/tools/test_actions.py
@@ -25,6 +25,20 @@
</tool>
'''
+# Tool with two outputs - used to verify all datasets within same job get same
+# object store id.
+TWO_OUTPUTS = '''<tool id="test_tool" name="Test Tool">
+ <command>echo "$param1" < $out1</command>
+ <inputs>
+ <param type="text" name="param1" value="" />
+ </inputs>
+ <outputs>
+ <data name="out1" format="data" label="Output ($param1)" />
+ <data name="out2" format="data" label="Output 2 ($param1)" />
+ </outputs>
+</tool>
+'''
+
def test_on_text_for_names():
def assert_on_text_is( expected, *names ):
@@ -80,6 +94,11 @@
)
self.assertEquals( output[ "out1" ].name, "Test Tool on data 2 and data 1" )
+ def test_object_store_ids( self ):
+ _, output = self._simple_execute( contents=TWO_OUTPUTS )
+ self.assertEquals( output[ "out1" ].name, "Output (moo)" )
+ self.assertEquals( output[ "out2" ].name, "Output 2 (moo)" )
+
def test_params_wrapped( self ):
hda1 = self.__add_dataset()
_, output = self._simple_execute(
@@ -142,6 +161,14 @@
def __init__( self ):
self.created_datasets = []
+ self.first_create = True
+ self.object_store_id = "mycoolid"
def create( self, dataset ):
self.created_datasets.append( dataset )
+ if self.first_create:
+ self.first_create = False
+ assert dataset.object_store_id is None
+ dataset.object_store_id = self.object_store_id
+ else:
+ assert dataset.object_store_id == self.object_store_id
https://bitbucket.org/galaxy/galaxy-central/commits/8a1951d3cf45/
Changeset: 8a1951d3cf45
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Small galaxy.tools.actions refactor related to object store...
Breaks up the big loop in execute a little bit but will enable a much bigger breakup in subsequent refactoring because the loop will no longer have to update the object_store_id local variable - that will be tracked in new object.
Affected #: 1 file
diff -r 942b4bffc4277d090e6cd788e706706f56aa1d62 -r 8a1951d3cf45c6e3b74abffe9c90c22d28fd955e lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -213,7 +213,7 @@
# datasets first, then create the associations
parent_to_child_pairs = []
child_dataset_names = set()
- object_store_id = None
+ object_store_populator = ObjectStorePopulator( trans.app )
for name, output in tool.outputs.items():
for filter in output.filters:
try:
@@ -275,15 +275,9 @@
trans.sa_session.add( data )
trans.sa_session.flush()
trans.app.security_agent.set_all_dataset_permissions( data.dataset, output_permissions )
- # Create an empty file immediately. The first dataset will be
- # created in the "default" store, all others will be created in
- # the same store as the first.
- data.dataset.object_store_id = object_store_id
- try:
- trans.app.object_store.create( data.dataset )
- except ObjectInvalid:
- raise Exception('Unable to create output dataset: object store is full')
- object_store_id = data.dataset.object_store_id # these will be the same thing after the first output
+
+ object_store_populator.set_object_store_id( data )
+
# This may not be neccesary with the new parent/child associations
data.designation = name
# Copy metadata from one of the inputs if requested.
@@ -362,7 +356,7 @@
job.add_input_dataset( name, None )
for name, dataset in out_data.iteritems():
job.add_output_dataset( name, dataset )
- job.object_store_id = object_store_id
+ job.object_store_id = object_store_populator.object_store_id
if job_params:
job.params = to_json_string( job_params )
job.set_handler(tool.get_job_handler(job_params))
@@ -443,6 +437,27 @@
return name
+class ObjectStorePopulator( object ):
+ """ Small helper for interacting with the object store and making sure all
+ datasets from a job end up with the same object_store_id.
+ """
+
+ def __init__( self, app ):
+ self.object_store = app.object_store
+ self.object_store_id = None
+
+ def set_object_store_id( self, data ):
+ # Create an empty file immediately. The first dataset will be
+ # created in the "default" store, all others will be created in
+ # the same store as the first.
+ data.dataset.object_store_id = self.object_store_id
+ try:
+ self.object_store.create( data.dataset )
+ except ObjectInvalid:
+ raise Exception('Unable to create output dataset: object store is full')
+ self.object_store_id = data.dataset.object_store_id # these will be the same thing after the first output
+
+
def on_text_for_names( input_names ):
# input_names may contain duplicates... this is because the first value in
# multiple input dataset parameters will appear twice once as param_name
https://bitbucket.org/galaxy/galaxy-central/commits/3f2c5f313087/
Changeset: 3f2c5f313087
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Refactor tool action loop allowing reuse of job dataset creation logic.
Reusing this logic will be useful in the context of creating datasets belonging to output collections. This also breaks up the big loop slightly and allows a small reduction in cyclomatic complexity in subsequent refactoring.
Affected #: 1 file
diff -r 8a1951d3cf45c6e3b74abffe9c90c22d28fd955e -r 3f2c5f313087c63eabf8e9e251d3c5fe03db9868 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -214,6 +214,89 @@
parent_to_child_pairs = []
child_dataset_names = set()
object_store_populator = ObjectStorePopulator( trans.app )
+
+ def handle_output( name, output ):
+ if output.parent:
+ parent_to_child_pairs.append( ( output.parent, name ) )
+ child_dataset_names.add( name )
+ ## What is the following hack for? Need to document under what
+ ## conditions can the following occur? (james(a)bx.psu.edu)
+ # HACK: the output data has already been created
+ # this happens i.e. as a result of the async controller
+ if name in incoming:
+ dataid = incoming[name]
+ data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( dataid )
+ assert data is not None
+ out_data[name] = data
+ else:
+ # the type should match the input
+ ext = output.format
+ if ext == "input":
+ ext = input_ext
+ if output.format_source is not None and output.format_source in inp_data:
+ try:
+ input_dataset = inp_data[output.format_source]
+ input_extension = input_dataset.ext
+ ext = input_extension
+ except Exception:
+ pass
+
+ #process change_format tags
+ if output.change_format:
+ for change_elem in output.change_format:
+ for when_elem in change_elem.findall( 'when' ):
+ check = when_elem.get( 'input', None )
+ if check is not None:
+ try:
+ if '$' not in check:
+ #allow a simple name or more complex specifications
+ check = '${%s}' % check
+ if str( fill_template( check, context=wrapped_params.params ) ) == when_elem.get( 'value', None ):
+ ext = when_elem.get( 'format', ext )
+ except: # bad tag input value; possibly referencing a param within a different conditional when block or other nonexistent grouping construct
+ continue
+ else:
+ check = when_elem.get( 'input_dataset', None )
+ if check is not None:
+ check = inp_data.get( check, None )
+ if check is not None:
+ if str( getattr( check, when_elem.get( 'attribute' ) ) ) == when_elem.get( 'value', None ):
+ ext = when_elem.get( 'format', ext )
+ data = trans.app.model.HistoryDatasetAssociation( extension=ext, create_dataset=True, sa_session=trans.sa_session )
+ if output.hidden:
+ data.visible = False
+ # Commit the dataset immediately so it gets database assigned unique id
+ trans.sa_session.add( data )
+ trans.sa_session.flush()
+ trans.app.security_agent.set_all_dataset_permissions( data.dataset, output_permissions )
+
+ object_store_populator.set_object_store_id( data )
+
+ # This may not be neccesary with the new parent/child associations
+ data.designation = name
+ # Copy metadata from one of the inputs if requested.
+ if output.metadata_source:
+ data.init_meta( copy_from=inp_data[output.metadata_source] )
+ else:
+ data.init_meta()
+ # Take dbkey from LAST input
+ data.dbkey = str(input_dbkey)
+ # Set state
+ # FIXME: shouldn't this be NEW until the job runner changes it?
+ data.state = data.states.QUEUED
+ data.blurb = "queued"
+ # Set output label
+ data.name = self.get_output_name( output, data, tool, on_text, trans, incoming, history, wrapped_params.params, job_params )
+ # Store output
+ out_data[ name ] = data
+ if output.actions:
+ #Apply pre-job tool-output-dataset actions; e.g. setting metadata, changing format
+ output_action_params = dict( out_data )
+ output_action_params.update( incoming )
+ output.actions.apply_action( data, output_action_params )
+ # Store all changes to database
+ trans.sa_session.flush()
+
for name, output in tool.outputs.items():
for filter in output.filters:
try:
@@ -221,87 +304,8 @@
break # do not create this dataset
except Exception, e:
log.debug( 'Dataset output filter failed: %s' % e )
- else: # all filters passed
- if output.parent:
- parent_to_child_pairs.append( ( output.parent, name ) )
- child_dataset_names.add( name )
- ## What is the following hack for? Need to document under what
- ## conditions can the following occur? (james(a)bx.psu.edu)
- # HACK: the output data has already been created
- # this happens i.e. as a result of the async controller
- if name in incoming:
- dataid = incoming[name]
- data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( dataid )
- assert data is not None
- out_data[name] = data
- else:
- # the type should match the input
- ext = output.format
- if ext == "input":
- ext = input_ext
- if output.format_source is not None and output.format_source in inp_data:
- try:
- input_dataset = inp_data[output.format_source]
- input_extension = input_dataset.ext
- ext = input_extension
- except Exception, e:
- pass
-
- #process change_format tags
- if output.change_format:
- for change_elem in output.change_format:
- for when_elem in change_elem.findall( 'when' ):
- check = when_elem.get( 'input', None )
- if check is not None:
- try:
- if '$' not in check:
- #allow a simple name or more complex specifications
- check = '${%s}' % check
- if str( fill_template( check, context=wrapped_params.params ) ) == when_elem.get( 'value', None ):
- ext = when_elem.get( 'format', ext )
- except: # bad tag input value; possibly referencing a param within a different conditional when block or other nonexistent grouping construct
- continue
- else:
- check = when_elem.get( 'input_dataset', None )
- if check is not None:
- check = inp_data.get( check, None )
- if check is not None:
- if str( getattr( check, when_elem.get( 'attribute' ) ) ) == when_elem.get( 'value', None ):
- ext = when_elem.get( 'format', ext )
- data = trans.app.model.HistoryDatasetAssociation( extension=ext, create_dataset=True, sa_session=trans.sa_session )
- if output.hidden:
- data.visible = False
- # Commit the dataset immediately so it gets database assigned unique id
- trans.sa_session.add( data )
- trans.sa_session.flush()
- trans.app.security_agent.set_all_dataset_permissions( data.dataset, output_permissions )
-
- object_store_populator.set_object_store_id( data )
-
- # This may not be neccesary with the new parent/child associations
- data.designation = name
- # Copy metadata from one of the inputs if requested.
- if output.metadata_source:
- data.init_meta( copy_from=inp_data[output.metadata_source] )
- else:
- data.init_meta()
- # Take dbkey from LAST input
- data.dbkey = str(input_dbkey)
- # Set state
- # FIXME: shouldn't this be NEW until the job runner changes it?
- data.state = data.states.QUEUED
- data.blurb = "queued"
- # Set output label
- data.name = self.get_output_name( output, data, tool, on_text, trans, incoming, history, wrapped_params.params, job_params )
- # Store output
- out_data[ name ] = data
- if output.actions:
- #Apply pre-job tool-output-dataset actions; e.g. setting metadata, changing format
- output_action_params = dict( out_data )
- output_action_params.update( incoming )
- output.actions.apply_action( data, output_action_params )
- # Store all changes to database
- trans.sa_session.flush()
+ else:
+ handle_output( name, output )
# Add all the top-level (non-child) datasets to the history unless otherwise specified
for name in out_data.keys():
if name not in child_dataset_names and name not in incoming: # don't add children; or already existing datasets, i.e. async created
https://bitbucket.org/galaxy/galaxy-central/commits/b7c657b77647/
Changeset: b7c657b77647
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Unit tests for tool action code determining output formats.
With refactoring to reduce cyclomatic complexity. Also renaming 'input_ext' what it actually is 'random_input_ext'. We should fix that or at least issue a huge warning if we detect 'input' could have reasonable been different things.
Affected #: 2 files
diff -r 3f2c5f313087c63eabf8e9e251d3c5fe03db9868 -r b7c657b77647164126ffd75ba1bb8692fb808eff lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -229,39 +229,7 @@
assert data is not None
out_data[name] = data
else:
- # the type should match the input
- ext = output.format
- if ext == "input":
- ext = input_ext
- if output.format_source is not None and output.format_source in inp_data:
- try:
- input_dataset = inp_data[output.format_source]
- input_extension = input_dataset.ext
- ext = input_extension
- except Exception:
- pass
-
- #process change_format tags
- if output.change_format:
- for change_elem in output.change_format:
- for when_elem in change_elem.findall( 'when' ):
- check = when_elem.get( 'input', None )
- if check is not None:
- try:
- if '$' not in check:
- #allow a simple name or more complex specifications
- check = '${%s}' % check
- if str( fill_template( check, context=wrapped_params.params ) ) == when_elem.get( 'value', None ):
- ext = when_elem.get( 'format', ext )
- except: # bad tag input value; possibly referencing a param within a different conditional when block or other nonexistent grouping construct
- continue
- else:
- check = when_elem.get( 'input_dataset', None )
- if check is not None:
- check = inp_data.get( check, None )
- if check is not None:
- if str( getattr( check, when_elem.get( 'attribute' ) ) ) == when_elem.get( 'value', None ):
- ext = when_elem.get( 'format', ext )
+ ext = determine_output_format( output, wrapped_params.params, inp_data, input_ext )
data = trans.app.model.HistoryDatasetAssociation( extension=ext, create_dataset=True, sa_session=trans.sa_session )
if output.hidden:
data.visible = False
@@ -484,3 +452,51 @@
else:
on_text = ""
return on_text
+
+
+def determine_output_format(output, parameter_context, input_datasets, random_input_ext):
+ """ Determines the output format for a dataset based on an abstract
+ description of the output (galaxy.tools.ToolOutput), the parameter
+ wrappers, a map of the input datasets (name => HDA), and the last input
+ extensions in the tool form.
+
+ TODO: Don't deal with XML here - move this logic into ToolOutput.
+ TODO: Make the input extension used deterministic instead of random.
+ """
+ # the type should match the input
+ ext = output.format
+ if ext == "input":
+ ext = random_input_ext
+ if output.format_source is not None and output.format_source in input_datasets:
+ try:
+ input_dataset = input_datasets[output.format_source]
+ input_extension = input_dataset.ext
+ ext = input_extension
+ except Exception:
+ pass
+
+ #process change_format tags
+ if output.change_format:
+ for change_elem in output.change_format:
+ print change_elem
+ for when_elem in change_elem.findall( 'when' ):
+ check = when_elem.get( 'input', None )
+ print check
+ if check is not None:
+ try:
+ if '$' not in check:
+ #allow a simple name or more complex specifications
+ check = '${%s}' % check
+ if str( fill_template( check, context=parameter_context ) ) == when_elem.get( 'value', None ):
+ ext = when_elem.get( 'format', ext )
+ except: # bad tag input value; possibly referencing a param within a different conditional when block or other nonexistent grouping construct
+ continue
+ else:
+ check = when_elem.get( 'input_dataset', None )
+ if check is not None:
+ check = input_datasets.get( check, None )
+ if check is not None:
+ if str( getattr( check, when_elem.get( 'attribute' ) ) ) == when_elem.get( 'value', None ):
+ ext = when_elem.get( 'format', ext )
+
+ return ext
diff -r 3f2c5f313087c63eabf8e9e251d3c5fe03db9868 -r b7c657b77647164126ffd75ba1bb8692fb808eff test/unit/tools/test_actions.py
--- a/test/unit/tools/test_actions.py
+++ b/test/unit/tools/test_actions.py
@@ -1,8 +1,11 @@
import unittest
from galaxy import model
+from galaxy.tools import ToolOutput
from galaxy.tools.actions import DefaultToolAction
from galaxy.tools.actions import on_text_for_names
+from galaxy.tools.actions import determine_output_format
+from elementtree.ElementTree import XML
import tools_support
@@ -135,6 +138,57 @@
)
+def test_determine_output_format():
+ # Test simple case of explicitly defined output with no changes.
+ direct_output = quick_output("txt")
+ __assert_output_format_is("txt", direct_output)
+
+ # Test if format is "input" (which just uses the last input on the form.)
+ input_based_output = quick_output("input")
+ __assert_output_format_is("fastq", input_based_output, [("i1", "fasta"), ("i2", "fastq")])
+
+ # Test using format_source (testing a couple different positions)
+ input_based_output = quick_output("txt", format_source="i1")
+ __assert_output_format_is("fasta", input_based_output, [("i1", "fasta"), ("i2", "fastq")])
+
+ input_based_output = quick_output("txt", format_source="i2")
+ __assert_output_format_is("fastq", input_based_output, [("i1", "fasta"), ("i2", "fastq")])
+
+ change_format_xml = """<data><change_format>
+ <when input="options_type.output_type" value="solexa" format="fastqsolexa" />
+ <when input="options_type.output_type" value="illumina" format="fastqillumina" />
+ </change_format></data>"""
+
+ change_format_output = quick_output("fastq", change_format_xml=change_format_xml)
+ # Test maching a change_format when.
+ __assert_output_format_is("fastqillumina", change_format_output, param_context={"options_type": {"output_type": "illumina"}} )
+ # Test change_format but no match
+ __assert_output_format_is("fastq", change_format_output, param_context={"options_type": {"output_type": "sanger"}} )
+
+
+def __assert_output_format_is( expected, output, input_extensions=[], param_context=[] ):
+ inputs = {}
+ last_ext = "data"
+ for name, ext in input_extensions:
+ hda = model.HistoryDatasetAssociation(extension=ext)
+ inputs[ name ] = hda
+ last_ext = ext
+
+ actual_format = determine_output_format( output, param_context, inputs, last_ext )
+ assert actual_format == expected, "Actual format %s, does not match expected %s" % (actual_format, expected)
+
+
+def quick_output(format, format_source=None, change_format_xml=None):
+ test_output = ToolOutput( "test_output" )
+ test_output.format = format
+ test_output.format_source = format_source
+ if change_format_xml:
+ test_output.change_format = XML(change_format_xml)
+ else:
+ test_output.change_format = None
+ return test_output
+
+
class MockTrans( object ):
def __init__( self, app, history, user=None ):
https://bitbucket.org/galaxy/galaxy-central/commits/3e485075985b/
Changeset: 3e485075985b
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Break up tool action loop by refactoring filtering logic out.
Affected #: 1 file
diff -r b7c657b77647164126ffd75ba1bb8692fb808eff -r 3e485075985bb492f83fdd49ee5d5042e6404d80 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -266,13 +266,7 @@
trans.sa_session.flush()
for name, output in tool.outputs.items():
- for filter in output.filters:
- try:
- if not eval( filter.text.strip(), globals(), incoming ):
- break # do not create this dataset
- except Exception, e:
- log.debug( 'Dataset output filter failed: %s' % e )
- else:
+ if not filter_output(output, incoming):
handle_output( name, output )
# Add all the top-level (non-child) datasets to the history unless otherwise specified
for name in out_data.keys():
@@ -454,6 +448,16 @@
return on_text
+def filter_output(output, incoming):
+ for filter in output.filters:
+ try:
+ if not eval( filter.text.strip(), globals(), incoming ):
+ return True # do not create this dataset
+ except Exception, e:
+ log.debug( 'Dataset output filter failed: %s' % e )
+ return False
+
+
def determine_output_format(output, parameter_context, input_datasets, random_input_ext):
""" Determines the output format for a dataset based on an abstract
description of the output (galaxy.tools.ToolOutput), the parameter
https://bitbucket.org/galaxy/galaxy-central/commits/ea812c16cbf9/
Changeset: ea812c16cbf9
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Small optimization for implicit collection creation from tool execution.
Don't write out encode identifier, add to dict, and then reload object in dataset collection service - just pass through the object in the dictionary as is.
Affected #: 2 files
diff -r 3e485075985bb492f83fdd49ee5d5042e6404d80 -r ea812c16cbf9674b2ba153041c3dd33bf36b7fe2 lib/galaxy/dataset_collections/__init__.py
--- a/lib/galaxy/dataset_collections/__init__.py
+++ b/lib/galaxy/dataset_collections/__init__.py
@@ -54,8 +54,12 @@
):
"""
"""
- if element_identifiers:
+ # Trust embedded, newly created objects created by tool subsystem.
+ trusted_identifiers = implicit_collection_info is not None
+
+ if element_identifiers and not trusted_identifiers:
validate_input_element_identifiers( element_identifiers )
+
dataset_collection = self.__create_dataset_collection(
trans=trans,
collection_type=collection_type,
diff -r 3e485075985bb492f83fdd49ee5d5042e6404d80 -r ea812c16cbf9674b2ba153041c3dd33bf36b7fe2 lib/galaxy/dataset_collections/structure.py
--- a/lib/galaxy/dataset_collections/structure.py
+++ b/lib/galaxy/dataset_collections/structure.py
@@ -78,7 +78,7 @@
child_identifiers[ "name" ] = identifier
element_identifiers.append( child_identifiers )
else:
- element_identifiers.append( dict( name=identifier, src="hda", id=trans.security.encode_id( datasets[ 0 ].id ) ) )
+ element_identifiers.append( dict( name=identifier, __object__=datasets[ 0 ] ) )
datasets = datasets[ len( child ): ]
https://bitbucket.org/galaxy/galaxy-central/commits/148b770b37aa/
Changeset: 148b770b37aa
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Refactor some collection-y tool methods ahead of collection outputs.
Tool mapping "structure" logic no longer assumes tool outputs are datasets - could also potentially handle logic related to structure of output collections as well now.
These variable names will make for sense down the road when tools that explicitly create collections exist and can be mapped over.
Affected #: 4 files
diff -r ea812c16cbf9674b2ba153041c3dd33bf36b7fe2 -r 148b770b37aa202facde8c79bc49bbd875f92ddc lib/galaxy/dataset_collections/__init__.py
--- a/lib/galaxy/dataset_collections/__init__.py
+++ b/lib/galaxy/dataset_collections/__init__.py
@@ -74,7 +74,7 @@
if implicit_collection_info:
for input_name, input_collection in implicit_collection_info[ "implicit_inputs" ]:
dataset_collection_instance.add_implicit_input_collection( input_name, input_collection )
- for output_dataset in implicit_collection_info.get( "outputs_datasets" ):
+ for output_dataset in implicit_collection_info.get( "outputs" ):
output_dataset.hidden_beneath_collection_instance = dataset_collection_instance
trans.sa_session.add( output_dataset )
diff -r ea812c16cbf9674b2ba153041c3dd33bf36b7fe2 -r 148b770b37aa202facde8c79bc49bbd875f92ddc lib/galaxy/dataset_collections/structure.py
--- a/lib/galaxy/dataset_collections/structure.py
+++ b/lib/galaxy/dataset_collections/structure.py
@@ -3,6 +3,8 @@
import logging
log = logging.getLogger( __name__ )
+from .type_description import map_over_collection_type
+
class Leaf( object ):
@@ -70,21 +72,27 @@
def __len__( self ):
return sum( [ len( c[ 1 ] ) for c in self.children ] )
- def element_identifiers_for_datasets( self, trans, datasets ):
+ def element_identifiers_for_outputs( self, trans, outputs ):
element_identifiers = []
+ elements_collection_type = None
for identifier, child in self.children:
if isinstance( child, Tree ):
- child_identifiers = child.element_identifiers_for_datasets( trans, datasets[ 0:len( child ) ] )
+ child_identifiers = child.element_identifiers_for_outputs( trans, outputs[ 0:len( child ) ] )
child_identifiers[ "name" ] = identifier
element_identifiers.append( child_identifiers )
+ elements_collection_type = child_identifiers[ "collection_type" ]
else:
- element_identifiers.append( dict( name=identifier, __object__=datasets[ 0 ] ) )
+ output_object = outputs[ 0 ]
+ element_identifiers.append( dict( name=identifier, __object__=output_object ) )
+ if hasattr( output_object, "collection_type" ):
+ elements_collection_type = output_object.collection_type
- datasets = datasets[ len( child ): ]
+ outputs = outputs[ len( child ): ]
+ collection_type = map_over_collection_type( self.collection_type_description.rank_collection_type(), elements_collection_type )
return dict(
src="new_collection",
- collection_type=self.collection_type_description.collection_type,
+ collection_type=collection_type,
element_identifiers=element_identifiers,
)
diff -r ea812c16cbf9674b2ba153041c3dd33bf36b7fe2 -r 148b770b37aa202facde8c79bc49bbd875f92ddc lib/galaxy/dataset_collections/type_description.py
--- a/lib/galaxy/dataset_collections/type_description.py
+++ b/lib/galaxy/dataset_collections/type_description.py
@@ -104,3 +104,16 @@
def __str__( self ):
return "CollectionTypeDescription[%s]" % self.collection_type
+
+
+def map_over_collection_type( mapped_over_collection_type, target_collection_type ):
+ if hasattr( mapped_over_collection_type, 'collection_type' ):
+ mapped_over_collection_type = mapped_over_collection_type.collection_type
+
+ if not target_collection_type:
+ return mapped_over_collection_type
+ else:
+ if hasattr( target_collection_type, 'collection_type' ):
+ target_collection_type = target_collection_type.collection_type
+
+ return "%s:%s" % (mapped_over_collection_type, target_collection_type)
diff -r ea812c16cbf9674b2ba153041c3dd33bf36b7fe2 -r 148b770b37aa202facde8c79bc49bbd875f92ddc lib/galaxy/tools/execute.py
--- a/lib/galaxy/tools/execute.py
+++ b/lib/galaxy/tools/execute.py
@@ -46,14 +46,14 @@
self.failed_jobs = 0
self.execution_errors = []
self.output_datasets = []
- self.output_datasets_by_output_name = collections.defaultdict(list)
+ self.outputs_by_output_name = collections.defaultdict(list)
self.created_collections = {}
def record_success( self, job, outputs ):
self.successful_jobs.append( job )
self.output_datasets.extend( outputs )
for output_name, output_dataset in outputs:
- self.output_datasets_by_output_name[ output_name ].append( output_dataset )
+ self.outputs_by_output_name[ output_name ].append( output_dataset )
def record_error( self, error ):
self.failed_jobs += 1
@@ -82,19 +82,19 @@
collections = {}
implicit_inputs = list(self.collection_info.collections.iteritems())
- for output_name, outputs_datasets in self.output_datasets_by_output_name.iteritems():
- if not len( structure ) == len( outputs_datasets ):
+ for output_name, outputs in self.outputs_by_output_name.iteritems():
+ if not len( structure ) == len( outputs ):
# Output does not have the same structure, if all jobs were
# successfully submitted this shouldn't have happened.
log.warn( "Problem matching up datasets while attempting to create implicit dataset collections")
continue
output = self.tool.outputs[ output_name ]
- element_identifiers_for_datasets = structure.element_identifiers_for_datasets( trans, outputs_datasets )
+ element_identifiers = structure.element_identifiers_for_outputs( trans, outputs )
implicit_collection_info = dict(
implicit_inputs=implicit_inputs,
implicit_output_name=output_name,
- outputs_datasets=outputs_datasets
+ outputs=outputs
)
try:
output_collection_name = self.tool_action.get_output_name(
@@ -110,12 +110,14 @@
except Exception:
output_collection_name = "%s across %s" % ( self.tool.name, on_text )
+ child_element_identifiers = element_identifiers[ "element_identifiers" ]
+ collection_type = element_identifiers[ "collection_type" ]
collection = trans.app.dataset_collections_service.create(
trans=trans,
parent=history,
name=output_collection_name,
- element_identifiers=element_identifiers_for_datasets[ "element_identifiers" ],
- collection_type=structure.collection_type_description.collection_type,
+ element_identifiers=child_element_identifiers,
+ collection_type=collection_type,
implicit_collection_info=implicit_collection_info,
)
collections[ output_name ] = collection
https://bitbucket.org/galaxy/galaxy-central/commits/8b0230532488/
Changeset: 8b0230532488
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Fix unit tests broken with 9f63d96.
Affected #: 3 files
diff -r 148b770b37aa202facde8c79bc49bbd875f92ddc -r 8b02305324881c506162b5ba60b7512c01d951cf test/unit/jobs/test_job_wrapper.py
--- a/test/unit/jobs/test_job_wrapper.py
+++ b/test/unit/jobs/test_job_wrapper.py
@@ -137,7 +137,9 @@
integrated_datatypes_configs=os.path.join(test_directory, "datatypes_conf.xml"),
),
)
- self.job_config = Bunch()
+ self.job_config = Bunch(
+ dynamic_params=None,
+ )
self.model = Bunch(context=MockContext(model_objects))
diff -r 148b770b37aa202facde8c79bc49bbd875f92ddc -r 8b02305324881c506162b5ba60b7512c01d951cf test/unit/jobs/test_mapper.py
--- a/test/unit/jobs/test_mapper.py
+++ b/test/unit/jobs/test_mapper.py
@@ -119,6 +119,7 @@
def __init__( self ):
self.rule_response = None
+ self.dynamic_params = None
def get_destination( self, rep ):
# Called to transform dynamic job destination rule response
diff -r 148b770b37aa202facde8c79bc49bbd875f92ddc -r 8b02305324881c506162b5ba60b7512c01d951cf test/unit/tools_support.py
--- a/test/unit/tools_support.py
+++ b/test/unit/tools_support.py
@@ -103,7 +103,9 @@
)
# Setup some attributes for downstream extension by specific tests.
- self.job_config = Bunch()
+ self.job_config = Bunch(
+ dynamic_params=None,
+ )
# Two ways to handle model layer, one is to stub out some objects that
# have an interface similar to real model (mock_model) and can keep
https://bitbucket.org/galaxy/galaxy-central/commits/3d73e68aa3fb/
Changeset: 3d73e68aa3fb
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Delete incorrect unit test added in d15f9a1.
Don't know what I was thinking - it doesn't look like that method ever had that behavior.
Affected #: 1 file
diff -r 8b02305324881c506162b5ba60b7512c01d951cf -r 3d73e68aa3fb0e9300e2eeb655de3d09b9c31d67 test/unit/workflows/test_modules.py
--- a/test/unit/workflows/test_modules.py
+++ b/test/unit/workflows/test_modules.py
@@ -22,13 +22,6 @@
assert not tool_module.get_errors()
-def test_missing_tool_has_errors():
- trans = MockTrans()
- tool_dict = { "type": "tool", "tool_id": "cat1" }
- tool_module = modules.module_factory.from_dict( trans, tool_dict )
- assert tool_module.get_errors()
-
-
def test_cannot_create_tool_modules_for_missing_tools():
trans = MockTrans()
exception = False
https://bitbucket.org/galaxy/galaxy-central/commits/012e6eb76568/
Changeset: 012e6eb76568
User: jmchilton
Date: 2014-09-03 14:43:25
Summary: Fix workflow rendering unit test when run in suite.
It was stubbing out connection stuff which worked fine when running test on its own - but after any test sets up the sql alchemy mappings this breaks down because events are trying to fire. This just uses actual model classes - which is just as easy anyway really.
Affected #: 1 file
diff -r 3d73e68aa3fb0e9300e2eeb655de3d09b9c31d67 -r 012e6eb765684020eb597d8925e4ca5b58b9d904 test/unit/workflows/test_render.py
--- a/test/unit/workflows/test_render.py
+++ b/test/unit/workflows/test_render.py
@@ -1,5 +1,4 @@
from galaxy import model
-from galaxy.util import bunch
from galaxy.workflow import render
@@ -18,6 +17,12 @@
workflow.steps.append( workflow_step )
return workflow_step
+ def connection( **kwds ):
+ conn = model.WorkflowStepConnection()
+ for key, value in kwds.iteritems():
+ setattr(conn, key, value)
+ return conn
+
step_0 = add_step(
type="data_input",
order_index=0,
@@ -32,12 +37,13 @@
input_connections=[],
position={"top": 6, "left": 4}
)
+
step_2 = add_step(
type="tool",
tool_id="cat1",
order_index=2,
input_connections=[
- bunch.Bunch(input_name="input1", output_step=step_0, output_name="di1")
+ connection(input_name="input1", output_step=step_0, output_name="di1")
],
position={"top": 13, "left": 10}
)
@@ -46,7 +52,7 @@
tool_id="cat1",
order_index=3,
input_connections=[
- bunch.Bunch(input_name="input1", output_step=step_0, output_name="di1")
+ connection(input_name="input1", output_step=step_0, output_name="di1")
],
position={"top": 33, "left": 103}
)
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8e699330dfcd/
Changeset: 8e699330dfcd
User: jmchilton
Date: 2014-09-02 22:41:48
Summary: Merge stable.
Affected #: 3 files
diff -r d45b4b6ff827386ff3de59bc155e95f2cf2f5656 -r 8e699330dfcd889b02acccb058f16b28c95ac848 static/scripts/galaxy.workflow_editor.canvas.js
--- a/static/scripts/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/galaxy.workflow_editor.canvas.js
@@ -302,19 +302,12 @@
inputFilled = false;
} else {
if( this.multiple ) {
- if( ! this.connected() ) {
+ if(this._collectionAttached()) {
+ // Can only attach one collection to multiple input
+ // data parameter.
+ inputsFilled = true;
+ } else {
inputFilled = false;
- } else {
- var firstOutput = this.connectors[ 0 ].handle1;
- if( ! firstOutput ){
- inputFilled = false;
- } else {
- if( firstOutput.isDataCollectionInput || firstOutput.isMappedOver() || firstOutput.datatypes.indexOf( "input_collection" ) > 0 ) {
- inputFilled = true;
- } else {
- inputFilled = false;
- }
- }
}
} else {
inputFilled = true;
@@ -322,6 +315,22 @@
}
return inputFilled;
},
+ _collectionAttached: function( ) {
+ if( ! this.connected() ) {
+ return false;
+ } else {
+ var firstOutput = this.connectors[ 0 ].handle1;
+ if( ! firstOutput ){
+ return false;
+ } else {
+ if( firstOutput.isDataCollectionInput || firstOutput.isMappedOver() || firstOutput.datatypes.indexOf( "input_collection" ) > 0 ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ },
_mappingConstraints: function( ) {
// If this is a connected terminal, return list of collection types
// other terminals connected to node are constraining mapping to.
@@ -407,7 +416,9 @@
var thisMapOver = this.mapOver();
if( otherCollectionType.isCollection ) {
if( this.multiple ) {
- if( this.connected() ) {
+ if( this.connected() && ! this._collectionAttached() ) {
+ // if single inputs attached, cannot also attach a
+ // collection (yet...)
return false;
}
if( otherCollectionType.rank == 1 ) {
diff -r d45b4b6ff827386ff3de59bc155e95f2cf2f5656 -r 8e699330dfcd889b02acccb058f16b28c95ac848 static/scripts/packed/galaxy.workflow_editor.canvas.js
--- a/static/scripts/packed/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js
@@ -1,1 +1,1 @@
-function CollectionTypeDescription(a){this.collectionType=a;this.isCollection=true;this.rank=a.split(":").length}$.extend(CollectionTypeDescription.prototype,{append:function(a){if(a===NULL_COLLECTION_TYPE_DESCRIPTION){return this}if(a===ANY_COLLECTION_TYPE_DESCRIPTION){return otherCollectionType}return new CollectionTypeDescription(this.collectionType+":"+a.collectionType)},canMatch:function(a){if(a===NULL_COLLECTION_TYPE_DESCRIPTION){return false}if(a===ANY_COLLECTION_TYPE_DESCRIPTION){return true}return a.collectionType==this.collectionType},canMapOver:function(b){if(b===NULL_COLLECTION_TYPE_DESCRIPTION){return false}if(b===ANY_COLLECTION_TYPE_DESCRIPTION){return false}if(this.rank<=b.rank){return false}var a=b.collectionType;return this._endsWith(this.collectionType,a)},effectiveMapOver:function(a){var c=a.collectionType;var b=this.collectionType.substring(0,this.collectionType.length-c.length-1);return new CollectionTypeDescription(b)},equal:function(a){return a.collectionType==this.collectionType},toString:function(){return"CollectionType["+this.collectionType+"]"},_endsWith:function(b,a){return b.indexOf(a,b.length-a.length)!==-1}});NULL_COLLECTION_TYPE_DESCRIPTION={isCollection:false,canMatch:function(a){return false},canMapOver:function(a){return false},toString:function(){return"NullCollectionType[]"},append:function(a){return a},equal:function(a){return a===this}};ANY_COLLECTION_TYPE_DESCRIPTION={isCollection:true,canMatch:function(a){return NULL_COLLECTION_TYPE_DESCRIPTION!==a},canMapOver:function(a){return false},toString:function(){return"AnyCollectionType[]"},append:function(a){throw"Cannot append to ANY_COLLECTION_TYPE_DESCRIPTION"},equal:function(a){return a===this}};var TerminalMapping=Backbone.Model.extend({initialize:function(a){this.mapOver=a.mapOver||NULL_COLLECTION_TYPE_DESCRIPTION;this.terminal=a.terminal;this.terminal.terminalMapping=this},disableMapOver:function(){this.setMapOver(NULL_COLLECTION_TYPE_DESCRIPTION)},setMapOver:function(a){this.mapOver=a;this.trigger("change")}});var TerminalMappingView=Backbone.View.extend({tagName:"div",className:"fa-icon-button fa fa-folder-o",initialize:function(b){var a="Run tool in parallel over collection";this.$el.tooltip({delay:500,title:a});this.model.bind("change",_.bind(this.render,this))},render:function(){if(this.model.mapOver.isCollection){this.$el.show()}else{this.$el.hide()}},});var InputTerminalMappingView=TerminalMappingView.extend({events:{click:"onClick",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",},onMouseEnter:function(b){var a=this.model;if(!a.terminal.connected()&&a.mapOver.isCollection){this.$el.css("color","red")}},onMouseLeave:function(a){this.$el.css("color","black")},onClick:function(b){var a=this.model;if(!a.terminal.connected()&&a.mapOver.isCollection){a.terminal.resetMapping()}},});var InputTerminalMapping=TerminalMapping;var InputCollectionTerminalMapping=TerminalMapping;var OutputTerminalMapping=TerminalMapping;var OutputTerminalMappingView=TerminalMappingView;var InputCollectionTerminalMappingView=InputTerminalMappingView;var OutputCollectionTerminalMapping=TerminalMapping;var OutputCollectionTerminalMappingView=TerminalMappingView;var Terminal=Backbone.Model.extend({initialize:function(a){this.element=a.element;this.connectors=[]},connect:function(a){this.connectors.push(a);if(this.node){this.node.markChanged()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.markChanged();this.resetMappingIfNeeded()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})},destroyInvalidConnections:function(){_.each(this.connectors,function(a){a.destroyIfInvalid()})},setMapOver:function(a){if(this.multiple){return}if(!this.mapOver().equal(a)){this.terminalMapping.setMapOver(a);_.each(this.node.output_terminals,function(b){b.setMapOver(a)})}},mapOver:function(){if(!this.terminalMapping){return NULL_COLLECTION_TYPE_DESCRIPTION}else{return this.terminalMapping.mapOver}},isMappedOver:function(){return this.terminalMapping&&this.terminalMapping.mapOver.isCollection},resetMapping:function(){this.terminalMapping.disableMapOver()},resetMappingIfNeeded:function(){},});var OutputTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.datatypes=a.datatypes},resetMappingIfNeeded:function(){if(!this.node.hasConnectedOutputTerminals()&&!this.node.hasConnectedMappedInputTerminals()){_.each(this.node.mappedInputTerminals(),function(b){b.resetMappingIfNeeded()})}var a=!this.node.hasMappedOverInputTerminals();if(a){this.resetMapping()}},resetMapping:function(){this.terminalMapping.disableMapOver();_.each(this.connectors,function(a){var b=a.handle2;if(b){b.resetMappingIfNeeded();a.destroyIfInvalid()}})}});var BaseInputTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.update(a.input)},canAccept:function(a){if(this._inputFilled()){return false}else{return this.attachable(a)}},resetMappingIfNeeded:function(){var b=this.mapOver();if(!b.isCollection){return}var a=this.node.hasConnectedMappedInputTerminals()||(!this.node.hasConnectedOutputTerminals());if(a){this.resetMapping()}},resetMapping:function(){this.terminalMapping.disableMapOver();if(!this.node.hasMappedOverInputTerminals()){_.each(this.node.output_terminals,function(a){a.resetMapping()})}},connected:function(){return this.connectors.length!==0},_inputFilled:function(){var a;if(!this.connected()){a=false}else{if(this.multiple){if(!this.connected()){a=false}else{var b=this.connectors[0].handle1;if(!b){a=false}else{if(b.isDataCollectionInput||b.isMappedOver()||b.datatypes.indexOf("input_collection")>0){a=true}else{a=false}}}}else{a=true}}return a},_mappingConstraints:function(){if(!this.node){return[]}var b=this.mapOver();if(b.isCollection){return[b]}var a=[];if(!this.node.hasConnectedOutputTerminals()){_.each(this.node.connectedMappedInputTerminals(),function(c){a.push(c.mapOver())})}else{a.push(_.first(_.values(this.node.output_terminals)).mapOver())}return a},_producesAcceptableDatatype:function(a){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){var h=f[b];if(h=="input"||h=="input_collection"||issubtype(f[b],this.datatypes[c])){return true}}}return false},_otherCollectionType:function(a){var c=NULL_COLLECTION_TYPE_DESCRIPTION;if(a.isDataCollectionInput){c=a.collectionType}else{var b=a.mapOver();if(b.isCollection){c=b}}return c},});var InputTerminal=BaseInputTerminal.extend({update:function(a){this.datatypes=a.extensions;this.multiple=a.multiple;this.collection=false},connect:function(a){BaseInputTerminal.prototype.connect.call(this,a);var b=a.handle1;if(!b){return}var c=this._otherCollectionType(b);if(c.isCollection){this.setMapOver(c)}},attachable:function(b){var d=this._otherCollectionType(b);var a=this.mapOver();if(d.isCollection){if(this.multiple){if(this.connected()){return false}if(d.rank==1){return this._producesAcceptableDatatype(b)}else{return false}}if(a.isCollection&&a.canMatch(d)){return this._producesAcceptableDatatype(b)}else{var c=this._mappingConstraints();if(c.every(_.bind(d.canMatch,d))){return this._producesAcceptableDatatype(b)}else{return false}}}else{if(a.isCollection){return false}}return this._producesAcceptableDatatype(b)}});var InputCollectionTerminal=BaseInputTerminal.extend({update:function(a){this.multiple=false;this.collection=true;this.datatypes=a.extensions;if(a.collection_type){this.collectionType=new CollectionTypeDescription(a.collection_type)}else{this.collectionType=ANY_COLLECTION_TYPE_DESCRIPTION}},connect:function(b){BaseInputTerminal.prototype.connect.call(this,b);var a=b.handle1;if(!a){return}var c=this._effectiveMapOver(a);this.setMapOver(c)},_effectiveMapOver:function(a){var b=this.collectionType;var c=this._otherCollectionType(a);if(!b.canMatch(c)){return c.effectiveMapOver(b)}else{return NULL_COLLECTION_TYPE_DESCRIPTION}},_effectiveCollectionType:function(){var b=this.collectionType;var a=this.mapOver();return a.append(b)},attachable:function(b){var g=this._otherCollectionType(b);if(g.isCollection){var f=this._effectiveCollectionType();var a=this.mapOver();if(f.canMatch(g)){return this._producesAcceptableDatatype(b)}else{if(a.isCollection){return false}else{if(g.canMapOver(this.collectionType)){var d=this._effectiveMapOver(b);if(!d.isCollection){return false}var c=this._mappingConstraints();if(c.every(d.canMatch)){return this._producesAcceptableDatatype(b)}}}}}return false}});var OutputCollectionTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.datatypes=a.datatypes;this.collectionType=new CollectionTypeDescription(a.collection_type);this.isDataCollectionInput=true},update:function(a){var b=new CollectionTypeDescription(a.collection_type);if(b.collectionType!=this.collectionType.collectionType){_.each(this.connectors,function(c){c.destroy()})}this.collectionType=b}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},destroyIfInvalid:function(){if(this.handle1&&this.handle2&&!this.handle2.attachable(this.handle1)){this.destroy()}},redraw:function(){var f=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}f.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var v=function(c){return $(c).offset().left-f.offset().left};var p=function(c){return $(c).offset().top-f.offset().top};if(!this.handle1||!this.handle2){return}var o=v(this.handle1.element)+5;var n=p(this.handle1.element)+5;var x=v(this.handle2.element)+5;var u=p(this.handle2.element)+5;var k=100;var r=Math.min(o,x);var a=Math.max(o,x);var q=Math.min(n,u);var B=Math.max(n,u);var d=Math.min(Math.max(Math.abs(B-q)/2,100),300);var w=r-k;var A=q-k;var y=a-r+2*k;var s=B-q+2*k;this.canvas.style.left=w+"px";this.canvas.style.top=A+"px";this.canvas.setAttribute("width",y);this.canvas.setAttribute("height",s);o-=w;n-=A;x-=w;u-=A;var z=this.canvas.getContext("2d"),h=null,l=null;var g=1;if(this.handle1&&this.handle1.isMappedOver()){var h=[-6,-3,0,3,6];g=5}else{var h=[0]}if(this.handle2&&this.handle2.isMappedOver()){var l=[-6,-3,0,3,6];g=5}else{var l=[0]}var b=this;for(var t=0;t<g;t++){var m=5,j=7;if(h.length>1||l.length>1){m=1;j=3}b.draw_outlined_curve(o,n,x,u,d,m,j,h[t%h.length],l[t%l.length])}},draw_outlined_curve:function(j,i,l,k,a,b,f,g,d){var g=g||0;var d=d||0;var h=this.canvas.getContext("2d");h.lineCap="round";h.strokeStyle=this.outer_color;h.lineWidth=f;h.beginPath();h.moveTo(j,i+g);h.bezierCurveTo(j+a,i+g,l-a,k+d,l,k+d);h.stroke();h.strokeStyle=this.inner_color;h.lineWidth=b;h.beginPath();h.moveTo(j,i+g);h.bezierCurveTo(j+a,i+g,l-a,k+d,l,k+d);h.stroke()}});var Node=Backbone.Model.extend({initialize:function(a){this.element=a.element;this.input_terminals={};this.output_terminals={};this.tool_errors={}},connectedOutputTerminals:function(){return this._connectedTerminals(this.output_terminals)},_connectedTerminals:function(b){var a=[];$.each(b,function(c,d){if(d.connectors.length>0){a.push(d)}});return a},hasConnectedOutputTerminals:function(){var a=this.output_terminals;for(var b in a){if(a[b].connectors.length>0){return true}}return false},connectedMappedInputTerminals:function(){return this._connectedMappedTerminals(this.input_terminals)},hasConnectedMappedInputTerminals:function(){var c=this.input_terminals;for(var b in c){var a=c[b];if(a.connectors.length>0&&a.isMappedOver()){return true}}return false},_connectedMappedTerminals:function(b){var a=[];$.each(b,function(c,d){var f=d.mapOver();if(f.isCollection){if(d.connectors.length>0){a.push(d)}}});return a},mappedInputTerminals:function(){return this._mappedTerminals(this.input_terminals)},_mappedTerminals:function(b){var a=[];$.each(b,function(c,d){var f=d.mapOver();if(f.isCollection){a.push(d)}});return a},hasMappedOverInputTerminals:function(){var a=false;_.each(this.input_terminals,function(b){var c=b.mapOver();if(c.isCollection){a=true}});return a},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(b){if(b.type){this.type=b.type}this.name=b.name;this.form_html=b.form_html;this.tool_state=b.tool_state;this.tool_errors=b.tool_errors;this.tooltip=b.tooltip?b.tooltip:"";this.annotation=b.annotation;this.post_job_actions=b.post_job_actions?b.post_job_actions:{};this.workflow_outputs=b.workflow_outputs?b.workflow_outputs:[];var a=this;var c=new NodeView({el:this.element[0],node:a,});a.nodeView=c;$.each(b.data_inputs,function(f,d){c.addDataInput(d)});if((b.data_inputs.length>0)&&(b.data_outputs.length>0)){c.addRule()}$.each(b.data_outputs,function(f,d){c.addDataOutput(d)});c.render();workflow.node_changed(this)},update_field_data:function(d){var c=this;nodeView=c.nodeView;this.tool_state=d.tool_state;this.form_html=d.form_html;this.tool_errors=d.tool_errors;this.annotation=d.annotation;if("post_job_actions" in d){var f=$.parseJSON(d.post_job_actions);this.post_job_actions=f?f:{}}c.nodeView.renderToolErrors();var g=nodeView.$("div.inputs");var a=nodeView.newInputsDiv();var b={};_.each(d.data_inputs,function(h){var i=c.nodeView.addDataInput(h,a);b[h.name]=i});_.each(_.difference(_.values(nodeView.terminalViews),_.values(b)),function(h){h.el.terminal.destroy()});nodeView.terminalViews=b;if(d.data_outputs.length==1&&"collection_type" in d.data_outputs[0]){nodeView.updateDataOutput(d.data_outputs[0])}g.replaceWith(a);this.markChanged();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},markChanged:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node(f.type,f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if(!$.isArray(h)){h=[h]}$.each(h,function(k,j){var m=wf.nodes[j.id];var n=new Connector();n.connect(m.output_terminals[j.output_name],d.input_terminals[i]);n.redraw()})}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node({element:i});g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+galaxy_config.root+"static/images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<div>").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}function add_node(b,d,a){var c=prebuild_node(b,d,a);workflow.add_node(c);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview();workflow.activate_node(c);return c}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}var NodeView=Backbone.View.extend({initialize:function(a){this.node=a.node;this.output_width=Math.max(150,this.$el.width());this.tool_body=this.$el.find(".toolFormBody");this.tool_body.find("div").remove();this.newInputsDiv().appendTo(this.tool_body);this.terminalViews={};this.outputTerminlViews={}},render:function(){this.renderToolErrors();this.$el.css("width",Math.min(250,Math.max(this.$el.width(),this.output_width)))},renderToolErrors:function(){if(this.node.tool_errors){this.$el.addClass("tool-node-error")}else{this.$el.removeClass("tool-node-error")}},newInputsDiv:function(){return $("<div class='inputs'></div>")},updateMaxWidth:function(a){this.output_width=Math.max(this.output_width,a)},addRule:function(){this.tool_body.append($("<div class='rule'></div>"))},addDataInput:function(i,d){var j=true;if(!d){d=this.$(".inputs");j=false}var f=this.terminalViews[i.name];var h=(i.input_type=="dataset_collection")?InputCollectionTerminalView:InputTerminalView;if(f&&!(f instanceof h)){f.el.terminal.destroy();f=null}if(!f){f=new h({node:this.node,input:i})}else{var g=f.el.terminal;g.update(i);g.destroyInvalidConnections()}this.terminalViews[i.name]=f;var c=f.el;var b=new DataInputView({terminalElement:c,input:i,nodeView:this,skipResize:j});var a=b.$el;d.append(a.prepend(f.terminalElements()));return f},addDataOutput:function(a){var d=(a.collection_type)?OutputCollectionTerminalView:OutputTerminalView;var c=new d({node:this.node,output:a});var b=new DataOutputView({output:a,terminalElement:c.el,nodeView:this,});this.tool_body.append(b.$el.append(c.terminalElements()))},updateDataOutput:function(b){var a=this.node.output_terminals[b.name];a.update(b)}});var DataInputView=Backbone.View.extend({className:"form-row dataRow input-data-row",initialize:function(a){this.input=a.input;this.nodeView=a.nodeView;this.terminalElement=a.terminalElement;this.$el.attr("name",this.input.name).html(this.input.label);if(!a.skipResize){this.$el.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(this.el);this.nodeView.updateMaxWidth(this.$el.outerWidth());this.$el.css({position:"",left:"",top:"",display:""});this.$el.remove()}},});var OutputCalloutView=Backbone.View.extend({tagName:"div",initialize:function(b){this.label=b.label;this.node=b.node;this.output=b.output;var a=this;this.$el.attr("class","callout "+this.label).css({display:"none"}).append($("<div class='buttons'></div>").append($("<img/>").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(a.output.name,a.node.workflow_outputs)!=-1){a.node.workflow_outputs.splice($.inArray(a.output.name,a.node.workflow_outputs),1);a.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{a.node.workflow_outputs.push(a.output.name);a.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});this.$el.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});this.$el.show();this.resetImage()},resetImage:function(){if($.inArray(this.output.name,this.node.workflow_outputs)===-1){this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}},hoverImage:function(){this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")}});var DataOutputView=Backbone.View.extend({className:"form-row dataRow",initialize:function(c){this.output=c.output;this.terminalElement=c.terminalElement;this.nodeView=c.nodeView;var a=this.output;var b=a.name;var f=this.nodeView.node;var d=a.extensions.indexOf("input")>=0||a.extensions.indexOf("input_collection")>=0;if(!d){b=b+" ("+a.extensions.join(", ")+")"}this.$el.html(b);if(f.type=="tool"){var g=new OutputCalloutView({label:b,output:a,node:f,});this.$el.append(g.el);this.$el.hover(function(){g.hoverImage()},function(){g.resetImage()})}this.$el.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(this.el);this.nodeView.updateMaxWidth(this.$el.outerWidth()+17);this.$el.css({position:"",left:"",top:"",display:""}).detach()}});var TerminalView=Backbone.View.extend({setupMappingView:function(b){var c=new this.terminalMappingClass({terminal:b});var a=new this.terminalMappingViewClass({model:c});a.render();b.terminalMappingView=a;this.terminalMappingView=a},terminalElements:function(){if(this.terminalMappingView){return[this.terminalMappingView.el,this.el]}else{return[this.el]}}});var BaseInputTerminalView=TerminalView.extend({className:"terminal input-terminal",initialize:function(c){var f=c.node;var a=c.input;var b=a.name;var d=this.terminalForInput(a);if(!d.multiple){this.setupMappingView(d)}this.el.terminal=d;d.node=f;d.name=b;f.input_terminals[b]=d},events:{dropinit:"onDropInit",dropstart:"onDropStart",dropend:"onDropEnd",drop:"onDrop",hover:"onHover",},onDropInit:function(b,c){var a=this.el.terminal;return $(c.drag).hasClass("output-terminal")&&a.canAccept(c.drag.terminal)},onDropStart:function(a,b){if(b.proxy.terminal){b.proxy.terminal.connectors[0].inner_color="#BBFFBB"}},onDropEnd:function(a,b){if(b.proxy.terminal){b.proxy.terminal.connectors[0].inner_color="#FFFFFF"}},onDrop:function(b,c){var a=this.el.terminal;new Connector(c.drag.terminal,a).redraw()},onHover:function(){var c=this.el;var b=c.terminal;if(b.connectors.length>0){var a=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa fa-times").click(function(){$.each(b.connectors,function(f,d){if(d){d.destroy()}});a.remove()}))).bind("mouseleave",function(){$(this).remove()});a.css({top:$(c).offset().top-2,left:$(c).offset().left-a.width(),"padding-right":$(c).width()}).show()}},});var InputTerminalView=BaseInputTerminalView.extend({terminalMappingClass:InputTerminalMapping,terminalMappingViewClass:InputTerminalMappingView,terminalForInput:function(a){return new InputTerminal({element:this.el,input:a})},});var InputCollectionTerminalView=BaseInputTerminalView.extend({terminalMappingClass:InputCollectionTerminalMapping,terminalMappingViewClass:InputCollectionTerminalMappingView,terminalForInput:function(a){return new InputCollectionTerminal({element:this.el,input:a})},});var BaseOutputTerminalView=TerminalView.extend({className:"terminal output-terminal",initialize:function(c){var f=c.node;var a=c.output;var b=a.name;var d=this.terminalForOutput(a);this.setupMappingView(d);this.el.terminal=d;d.node=f;d.name=b;f.output_terminals[b]=d},events:{drag:"onDrag",dragstart:"onDragStart",dragend:"onDragEnd",},onDrag:function(b,c){var a=function(){var f=$(c.proxy).offsetParent().offset(),d=c.offsetX-f.left,g=c.offsetY-f.top;$(c.proxy).css({left:d,top:g});c.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};a();$("#canvas-container").get(0).scroll_panel.test(b,a)},onDragStart:function(b,f){$(f.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var a=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);a.terminal=new OutputTerminal({element:a});var g=new Connector();g.dragging=true;g.connect(this.el.terminal,a.terminal);return a},onDragEnd:function(b,c){var a=c.proxy.terminal.connectors[0];if(a){a.destroy()}$(c.proxy).remove();$(c.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()}});var OutputTerminalView=BaseOutputTerminalView.extend({terminalMappingClass:OutputTerminalMapping,terminalMappingViewClass:OutputTerminalMappingView,terminalForOutput:function(a){var c=a.extensions;var b=new OutputTerminal({element:this.el,datatypes:c});return b},});var OutputCollectionTerminalView=BaseOutputTerminalView.extend({terminalMappingClass:OutputCollectionTerminalMapping,terminalMappingViewClass:OutputCollectionTerminalMappingView,terminalForOutput:function(a){var c=a.collection_type;var b=new OutputCollectionTerminal({element:this.el,collection_type:c,datatypes:a.extensions});return b},});function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);$.each(workflow.nodes,function(t,q){i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;if(q.tool_errors){i.fillStyle="#FFCCCC";i.strokeStyle="#AA6666"}else{if(q.workflow_outputs!=undefined&&q.workflow_outputs.length>0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
+function CollectionTypeDescription(a){this.collectionType=a;this.isCollection=true;this.rank=a.split(":").length}$.extend(CollectionTypeDescription.prototype,{append:function(a){if(a===NULL_COLLECTION_TYPE_DESCRIPTION){return this}if(a===ANY_COLLECTION_TYPE_DESCRIPTION){return otherCollectionType}return new CollectionTypeDescription(this.collectionType+":"+a.collectionType)},canMatch:function(a){if(a===NULL_COLLECTION_TYPE_DESCRIPTION){return false}if(a===ANY_COLLECTION_TYPE_DESCRIPTION){return true}return a.collectionType==this.collectionType},canMapOver:function(b){if(b===NULL_COLLECTION_TYPE_DESCRIPTION){return false}if(b===ANY_COLLECTION_TYPE_DESCRIPTION){return false}if(this.rank<=b.rank){return false}var a=b.collectionType;return this._endsWith(this.collectionType,a)},effectiveMapOver:function(a){var c=a.collectionType;var b=this.collectionType.substring(0,this.collectionType.length-c.length-1);return new CollectionTypeDescription(b)},equal:function(a){return a.collectionType==this.collectionType},toString:function(){return"CollectionType["+this.collectionType+"]"},_endsWith:function(b,a){return b.indexOf(a,b.length-a.length)!==-1}});NULL_COLLECTION_TYPE_DESCRIPTION={isCollection:false,canMatch:function(a){return false},canMapOver:function(a){return false},toString:function(){return"NullCollectionType[]"},append:function(a){return a},equal:function(a){return a===this}};ANY_COLLECTION_TYPE_DESCRIPTION={isCollection:true,canMatch:function(a){return NULL_COLLECTION_TYPE_DESCRIPTION!==a},canMapOver:function(a){return false},toString:function(){return"AnyCollectionType[]"},append:function(a){throw"Cannot append to ANY_COLLECTION_TYPE_DESCRIPTION"},equal:function(a){return a===this}};var TerminalMapping=Backbone.Model.extend({initialize:function(a){this.mapOver=a.mapOver||NULL_COLLECTION_TYPE_DESCRIPTION;this.terminal=a.terminal;this.terminal.terminalMapping=this},disableMapOver:function(){this.setMapOver(NULL_COLLECTION_TYPE_DESCRIPTION)},setMapOver:function(a){this.mapOver=a;this.trigger("change")}});var TerminalMappingView=Backbone.View.extend({tagName:"div",className:"fa-icon-button fa fa-folder-o",initialize:function(b){var a="Run tool in parallel over collection";this.$el.tooltip({delay:500,title:a});this.model.bind("change",_.bind(this.render,this))},render:function(){if(this.model.mapOver.isCollection){this.$el.show()}else{this.$el.hide()}},});var InputTerminalMappingView=TerminalMappingView.extend({events:{click:"onClick",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",},onMouseEnter:function(b){var a=this.model;if(!a.terminal.connected()&&a.mapOver.isCollection){this.$el.css("color","red")}},onMouseLeave:function(a){this.$el.css("color","black")},onClick:function(b){var a=this.model;if(!a.terminal.connected()&&a.mapOver.isCollection){a.terminal.resetMapping()}},});var InputTerminalMapping=TerminalMapping;var InputCollectionTerminalMapping=TerminalMapping;var OutputTerminalMapping=TerminalMapping;var OutputTerminalMappingView=TerminalMappingView;var InputCollectionTerminalMappingView=InputTerminalMappingView;var OutputCollectionTerminalMapping=TerminalMapping;var OutputCollectionTerminalMappingView=TerminalMappingView;var Terminal=Backbone.Model.extend({initialize:function(a){this.element=a.element;this.connectors=[]},connect:function(a){this.connectors.push(a);if(this.node){this.node.markChanged()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.markChanged();this.resetMappingIfNeeded()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})},destroyInvalidConnections:function(){_.each(this.connectors,function(a){a.destroyIfInvalid()})},setMapOver:function(a){if(this.multiple){return}if(!this.mapOver().equal(a)){this.terminalMapping.setMapOver(a);_.each(this.node.output_terminals,function(b){b.setMapOver(a)})}},mapOver:function(){if(!this.terminalMapping){return NULL_COLLECTION_TYPE_DESCRIPTION}else{return this.terminalMapping.mapOver}},isMappedOver:function(){return this.terminalMapping&&this.terminalMapping.mapOver.isCollection},resetMapping:function(){this.terminalMapping.disableMapOver()},resetMappingIfNeeded:function(){},});var OutputTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.datatypes=a.datatypes},resetMappingIfNeeded:function(){if(!this.node.hasConnectedOutputTerminals()&&!this.node.hasConnectedMappedInputTerminals()){_.each(this.node.mappedInputTerminals(),function(b){b.resetMappingIfNeeded()})}var a=!this.node.hasMappedOverInputTerminals();if(a){this.resetMapping()}},resetMapping:function(){this.terminalMapping.disableMapOver();_.each(this.connectors,function(a){var b=a.handle2;if(b){b.resetMappingIfNeeded();a.destroyIfInvalid()}})}});var BaseInputTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.update(a.input)},canAccept:function(a){if(this._inputFilled()){return false}else{return this.attachable(a)}},resetMappingIfNeeded:function(){var b=this.mapOver();if(!b.isCollection){return}var a=this.node.hasConnectedMappedInputTerminals()||(!this.node.hasConnectedOutputTerminals());if(a){this.resetMapping()}},resetMapping:function(){this.terminalMapping.disableMapOver();if(!this.node.hasMappedOverInputTerminals()){_.each(this.node.output_terminals,function(a){a.resetMapping()})}},connected:function(){return this.connectors.length!==0},_inputFilled:function(){var a;if(!this.connected()){a=false}else{if(this.multiple){if(this._collectionAttached()){inputsFilled=true}else{a=false}}else{a=true}}return a},_collectionAttached:function(){if(!this.connected()){return false}else{var a=this.connectors[0].handle1;if(!a){return false}else{if(a.isDataCollectionInput||a.isMappedOver()||a.datatypes.indexOf("input_collection")>0){return true}else{return false}}}},_mappingConstraints:function(){if(!this.node){return[]}var b=this.mapOver();if(b.isCollection){return[b]}var a=[];if(!this.node.hasConnectedOutputTerminals()){_.each(this.node.connectedMappedInputTerminals(),function(c){a.push(c.mapOver())})}else{a.push(_.first(_.values(this.node.output_terminals)).mapOver())}return a},_producesAcceptableDatatype:function(a){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){var h=f[b];if(h=="input"||h=="input_collection"||issubtype(f[b],this.datatypes[c])){return true}}}return false},_otherCollectionType:function(a){var c=NULL_COLLECTION_TYPE_DESCRIPTION;if(a.isDataCollectionInput){c=a.collectionType}else{var b=a.mapOver();if(b.isCollection){c=b}}return c},});var InputTerminal=BaseInputTerminal.extend({update:function(a){this.datatypes=a.extensions;this.multiple=a.multiple;this.collection=false},connect:function(a){BaseInputTerminal.prototype.connect.call(this,a);var b=a.handle1;if(!b){return}var c=this._otherCollectionType(b);if(c.isCollection){this.setMapOver(c)}},attachable:function(b){var d=this._otherCollectionType(b);var a=this.mapOver();if(d.isCollection){if(this.multiple){if(this.connected()&&!this._collectionAttached()){return false}if(d.rank==1){return this._producesAcceptableDatatype(b)}else{return false}}if(a.isCollection&&a.canMatch(d)){return this._producesAcceptableDatatype(b)}else{var c=this._mappingConstraints();if(c.every(_.bind(d.canMatch,d))){return this._producesAcceptableDatatype(b)}else{return false}}}else{if(a.isCollection){return false}}return this._producesAcceptableDatatype(b)}});var InputCollectionTerminal=BaseInputTerminal.extend({update:function(a){this.multiple=false;this.collection=true;this.datatypes=a.extensions;if(a.collection_type){this.collectionType=new CollectionTypeDescription(a.collection_type)}else{this.collectionType=ANY_COLLECTION_TYPE_DESCRIPTION}},connect:function(b){BaseInputTerminal.prototype.connect.call(this,b);var a=b.handle1;if(!a){return}var c=this._effectiveMapOver(a);this.setMapOver(c)},_effectiveMapOver:function(a){var b=this.collectionType;var c=this._otherCollectionType(a);if(!b.canMatch(c)){return c.effectiveMapOver(b)}else{return NULL_COLLECTION_TYPE_DESCRIPTION}},_effectiveCollectionType:function(){var b=this.collectionType;var a=this.mapOver();return a.append(b)},attachable:function(b){var g=this._otherCollectionType(b);if(g.isCollection){var f=this._effectiveCollectionType();var a=this.mapOver();if(f.canMatch(g)){return this._producesAcceptableDatatype(b)}else{if(a.isCollection){return false}else{if(g.canMapOver(this.collectionType)){var d=this._effectiveMapOver(b);if(!d.isCollection){return false}var c=this._mappingConstraints();if(c.every(d.canMatch)){return this._producesAcceptableDatatype(b)}}}}}return false}});var OutputCollectionTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.datatypes=a.datatypes;this.collectionType=new CollectionTypeDescription(a.collection_type);this.isDataCollectionInput=true},update:function(a){var b=new CollectionTypeDescription(a.collection_type);if(b.collectionType!=this.collectionType.collectionType){_.each(this.connectors,function(c){c.destroy()})}this.collectionType=b}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},destroyIfInvalid:function(){if(this.handle1&&this.handle2&&!this.handle2.attachable(this.handle1)){this.destroy()}},redraw:function(){var f=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}f.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var v=function(c){return $(c).offset().left-f.offset().left};var p=function(c){return $(c).offset().top-f.offset().top};if(!this.handle1||!this.handle2){return}var o=v(this.handle1.element)+5;var n=p(this.handle1.element)+5;var x=v(this.handle2.element)+5;var u=p(this.handle2.element)+5;var k=100;var r=Math.min(o,x);var a=Math.max(o,x);var q=Math.min(n,u);var B=Math.max(n,u);var d=Math.min(Math.max(Math.abs(B-q)/2,100),300);var w=r-k;var A=q-k;var y=a-r+2*k;var s=B-q+2*k;this.canvas.style.left=w+"px";this.canvas.style.top=A+"px";this.canvas.setAttribute("width",y);this.canvas.setAttribute("height",s);o-=w;n-=A;x-=w;u-=A;var z=this.canvas.getContext("2d"),h=null,l=null;var g=1;if(this.handle1&&this.handle1.isMappedOver()){var h=[-6,-3,0,3,6];g=5}else{var h=[0]}if(this.handle2&&this.handle2.isMappedOver()){var l=[-6,-3,0,3,6];g=5}else{var l=[0]}var b=this;for(var t=0;t<g;t++){var m=5,j=7;if(h.length>1||l.length>1){m=1;j=3}b.draw_outlined_curve(o,n,x,u,d,m,j,h[t%h.length],l[t%l.length])}},draw_outlined_curve:function(j,i,l,k,a,b,f,g,d){var g=g||0;var d=d||0;var h=this.canvas.getContext("2d");h.lineCap="round";h.strokeStyle=this.outer_color;h.lineWidth=f;h.beginPath();h.moveTo(j,i+g);h.bezierCurveTo(j+a,i+g,l-a,k+d,l,k+d);h.stroke();h.strokeStyle=this.inner_color;h.lineWidth=b;h.beginPath();h.moveTo(j,i+g);h.bezierCurveTo(j+a,i+g,l-a,k+d,l,k+d);h.stroke()}});var Node=Backbone.Model.extend({initialize:function(a){this.element=a.element;this.input_terminals={};this.output_terminals={};this.tool_errors={}},connectedOutputTerminals:function(){return this._connectedTerminals(this.output_terminals)},_connectedTerminals:function(b){var a=[];$.each(b,function(c,d){if(d.connectors.length>0){a.push(d)}});return a},hasConnectedOutputTerminals:function(){var a=this.output_terminals;for(var b in a){if(a[b].connectors.length>0){return true}}return false},connectedMappedInputTerminals:function(){return this._connectedMappedTerminals(this.input_terminals)},hasConnectedMappedInputTerminals:function(){var c=this.input_terminals;for(var b in c){var a=c[b];if(a.connectors.length>0&&a.isMappedOver()){return true}}return false},_connectedMappedTerminals:function(b){var a=[];$.each(b,function(c,d){var f=d.mapOver();if(f.isCollection){if(d.connectors.length>0){a.push(d)}}});return a},mappedInputTerminals:function(){return this._mappedTerminals(this.input_terminals)},_mappedTerminals:function(b){var a=[];$.each(b,function(c,d){var f=d.mapOver();if(f.isCollection){a.push(d)}});return a},hasMappedOverInputTerminals:function(){var a=false;_.each(this.input_terminals,function(b){var c=b.mapOver();if(c.isCollection){a=true}});return a},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(b){if(b.type){this.type=b.type}this.name=b.name;this.form_html=b.form_html;this.tool_state=b.tool_state;this.tool_errors=b.tool_errors;this.tooltip=b.tooltip?b.tooltip:"";this.annotation=b.annotation;this.post_job_actions=b.post_job_actions?b.post_job_actions:{};this.workflow_outputs=b.workflow_outputs?b.workflow_outputs:[];var a=this;var c=new NodeView({el:this.element[0],node:a,});a.nodeView=c;$.each(b.data_inputs,function(f,d){c.addDataInput(d)});if((b.data_inputs.length>0)&&(b.data_outputs.length>0)){c.addRule()}$.each(b.data_outputs,function(f,d){c.addDataOutput(d)});c.render();workflow.node_changed(this)},update_field_data:function(d){var c=this;nodeView=c.nodeView;this.tool_state=d.tool_state;this.form_html=d.form_html;this.tool_errors=d.tool_errors;this.annotation=d.annotation;if("post_job_actions" in d){var f=$.parseJSON(d.post_job_actions);this.post_job_actions=f?f:{}}c.nodeView.renderToolErrors();var g=nodeView.$("div.inputs");var a=nodeView.newInputsDiv();var b={};_.each(d.data_inputs,function(h){var i=c.nodeView.addDataInput(h,a);b[h.name]=i});_.each(_.difference(_.values(nodeView.terminalViews),_.values(b)),function(h){h.el.terminal.destroy()});nodeView.terminalViews=b;if(d.data_outputs.length==1&&"collection_type" in d.data_outputs[0]){nodeView.updateDataOutput(d.data_outputs[0])}g.replaceWith(a);this.markChanged();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},markChanged:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node(f.type,f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if(!$.isArray(h)){h=[h]}$.each(h,function(k,j){var m=wf.nodes[j.id];var n=new Connector();n.connect(m.output_terminals[j.output_name],d.input_terminals[i]);n.redraw()})}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node({element:i});g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+galaxy_config.root+"static/images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<div>").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}function add_node(b,d,a){var c=prebuild_node(b,d,a);workflow.add_node(c);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview();workflow.activate_node(c);return c}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}var NodeView=Backbone.View.extend({initialize:function(a){this.node=a.node;this.output_width=Math.max(150,this.$el.width());this.tool_body=this.$el.find(".toolFormBody");this.tool_body.find("div").remove();this.newInputsDiv().appendTo(this.tool_body);this.terminalViews={};this.outputTerminlViews={}},render:function(){this.renderToolErrors();this.$el.css("width",Math.min(250,Math.max(this.$el.width(),this.output_width)))},renderToolErrors:function(){if(this.node.tool_errors){this.$el.addClass("tool-node-error")}else{this.$el.removeClass("tool-node-error")}},newInputsDiv:function(){return $("<div class='inputs'></div>")},updateMaxWidth:function(a){this.output_width=Math.max(this.output_width,a)},addRule:function(){this.tool_body.append($("<div class='rule'></div>"))},addDataInput:function(i,d){var j=true;if(!d){d=this.$(".inputs");j=false}var f=this.terminalViews[i.name];var h=(i.input_type=="dataset_collection")?InputCollectionTerminalView:InputTerminalView;if(f&&!(f instanceof h)){f.el.terminal.destroy();f=null}if(!f){f=new h({node:this.node,input:i})}else{var g=f.el.terminal;g.update(i);g.destroyInvalidConnections()}this.terminalViews[i.name]=f;var c=f.el;var b=new DataInputView({terminalElement:c,input:i,nodeView:this,skipResize:j});var a=b.$el;d.append(a.prepend(f.terminalElements()));return f},addDataOutput:function(a){var d=(a.collection_type)?OutputCollectionTerminalView:OutputTerminalView;var c=new d({node:this.node,output:a});var b=new DataOutputView({output:a,terminalElement:c.el,nodeView:this,});this.tool_body.append(b.$el.append(c.terminalElements()))},updateDataOutput:function(b){var a=this.node.output_terminals[b.name];a.update(b)}});var DataInputView=Backbone.View.extend({className:"form-row dataRow input-data-row",initialize:function(a){this.input=a.input;this.nodeView=a.nodeView;this.terminalElement=a.terminalElement;this.$el.attr("name",this.input.name).html(this.input.label);if(!a.skipResize){this.$el.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(this.el);this.nodeView.updateMaxWidth(this.$el.outerWidth());this.$el.css({position:"",left:"",top:"",display:""});this.$el.remove()}},});var OutputCalloutView=Backbone.View.extend({tagName:"div",initialize:function(b){this.label=b.label;this.node=b.node;this.output=b.output;var a=this;this.$el.attr("class","callout "+this.label).css({display:"none"}).append($("<div class='buttons'></div>").append($("<img/>").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(a.output.name,a.node.workflow_outputs)!=-1){a.node.workflow_outputs.splice($.inArray(a.output.name,a.node.workflow_outputs),1);a.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{a.node.workflow_outputs.push(a.output.name);a.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});this.$el.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});this.$el.show();this.resetImage()},resetImage:function(){if($.inArray(this.output.name,this.node.workflow_outputs)===-1){this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}},hoverImage:function(){this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")}});var DataOutputView=Backbone.View.extend({className:"form-row dataRow",initialize:function(c){this.output=c.output;this.terminalElement=c.terminalElement;this.nodeView=c.nodeView;var a=this.output;var b=a.name;var f=this.nodeView.node;var d=a.extensions.indexOf("input")>=0||a.extensions.indexOf("input_collection")>=0;if(!d){b=b+" ("+a.extensions.join(", ")+")"}this.$el.html(b);if(f.type=="tool"){var g=new OutputCalloutView({label:b,output:a,node:f,});this.$el.append(g.el);this.$el.hover(function(){g.hoverImage()},function(){g.resetImage()})}this.$el.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(this.el);this.nodeView.updateMaxWidth(this.$el.outerWidth()+17);this.$el.css({position:"",left:"",top:"",display:""}).detach()}});var TerminalView=Backbone.View.extend({setupMappingView:function(b){var c=new this.terminalMappingClass({terminal:b});var a=new this.terminalMappingViewClass({model:c});a.render();b.terminalMappingView=a;this.terminalMappingView=a},terminalElements:function(){if(this.terminalMappingView){return[this.terminalMappingView.el,this.el]}else{return[this.el]}}});var BaseInputTerminalView=TerminalView.extend({className:"terminal input-terminal",initialize:function(c){var f=c.node;var a=c.input;var b=a.name;var d=this.terminalForInput(a);if(!d.multiple){this.setupMappingView(d)}this.el.terminal=d;d.node=f;d.name=b;f.input_terminals[b]=d},events:{dropinit:"onDropInit",dropstart:"onDropStart",dropend:"onDropEnd",drop:"onDrop",hover:"onHover",},onDropInit:function(b,c){var a=this.el.terminal;return $(c.drag).hasClass("output-terminal")&&a.canAccept(c.drag.terminal)},onDropStart:function(a,b){if(b.proxy.terminal){b.proxy.terminal.connectors[0].inner_color="#BBFFBB"}},onDropEnd:function(a,b){if(b.proxy.terminal){b.proxy.terminal.connectors[0].inner_color="#FFFFFF"}},onDrop:function(b,c){var a=this.el.terminal;new Connector(c.drag.terminal,a).redraw()},onHover:function(){var c=this.el;var b=c.terminal;if(b.connectors.length>0){var a=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa fa-times").click(function(){$.each(b.connectors,function(f,d){if(d){d.destroy()}});a.remove()}))).bind("mouseleave",function(){$(this).remove()});a.css({top:$(c).offset().top-2,left:$(c).offset().left-a.width(),"padding-right":$(c).width()}).show()}},});var InputTerminalView=BaseInputTerminalView.extend({terminalMappingClass:InputTerminalMapping,terminalMappingViewClass:InputTerminalMappingView,terminalForInput:function(a){return new InputTerminal({element:this.el,input:a})},});var InputCollectionTerminalView=BaseInputTerminalView.extend({terminalMappingClass:InputCollectionTerminalMapping,terminalMappingViewClass:InputCollectionTerminalMappingView,terminalForInput:function(a){return new InputCollectionTerminal({element:this.el,input:a})},});var BaseOutputTerminalView=TerminalView.extend({className:"terminal output-terminal",initialize:function(c){var f=c.node;var a=c.output;var b=a.name;var d=this.terminalForOutput(a);this.setupMappingView(d);this.el.terminal=d;d.node=f;d.name=b;f.output_terminals[b]=d},events:{drag:"onDrag",dragstart:"onDragStart",dragend:"onDragEnd",},onDrag:function(b,c){var a=function(){var f=$(c.proxy).offsetParent().offset(),d=c.offsetX-f.left,g=c.offsetY-f.top;$(c.proxy).css({left:d,top:g});c.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};a();$("#canvas-container").get(0).scroll_panel.test(b,a)},onDragStart:function(b,f){$(f.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var a=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);a.terminal=new OutputTerminal({element:a});var g=new Connector();g.dragging=true;g.connect(this.el.terminal,a.terminal);return a},onDragEnd:function(b,c){var a=c.proxy.terminal.connectors[0];if(a){a.destroy()}$(c.proxy).remove();$(c.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()}});var OutputTerminalView=BaseOutputTerminalView.extend({terminalMappingClass:OutputTerminalMapping,terminalMappingViewClass:OutputTerminalMappingView,terminalForOutput:function(a){var c=a.extensions;var b=new OutputTerminal({element:this.el,datatypes:c});return b},});var OutputCollectionTerminalView=BaseOutputTerminalView.extend({terminalMappingClass:OutputCollectionTerminalMapping,terminalMappingViewClass:OutputCollectionTerminalMappingView,terminalForOutput:function(a){var c=a.collection_type;var b=new OutputCollectionTerminal({element:this.el,collection_type:c,datatypes:a.extensions});return b},});function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);$.each(workflow.nodes,function(t,q){i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;if(q.tool_errors){i.fillStyle="#FFCCCC";i.strokeStyle="#AA6666"}else{if(q.workflow_outputs!=undefined&&q.workflow_outputs.length>0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
diff -r d45b4b6ff827386ff3de59bc155e95f2cf2f5656 -r 8e699330dfcd889b02acccb058f16b28c95ac848 test/qunit/tests/workflow_editor_tests.js
--- a/test/qunit/tests/workflow_editor_tests.js
+++ b/test/qunit/tests/workflow_editor_tests.js
@@ -91,7 +91,9 @@
},
test_accept: function( other ) {
other = other || { node: {}, datatypes: [ "txt" ] };
- other.mapOver = function() { return NULL_COLLECTION_TYPE_DESCRIPTION; };
+ if( ! other.mapOver ) {
+ other.mapOver = function() { return NULL_COLLECTION_TYPE_DESCRIPTION; };
+ }
return this.input_terminal.canAccept( other );
},
pja_change_datatype_node: function( output_name, newtype ) {
@@ -230,6 +232,22 @@
ok( self.test_accept() );
} );
+ test( "can accept list collection for empty multiple inputs", function() {
+ var other = { node: {}, datatypes: [ "tabular" ], mapOver: function() { return new CollectionTypeDescription( "list" ) } };
+ var self = this;
+ this.multiple();
+ ok( self.test_accept( other ) );
+ } );
+
+ test( "cannot accept list collection for multiple input if collection already connected", function() {
+ var other = { node: {}, datatypes: [ "tabular" ], mapOver: function() { return new CollectionTypeDescription( "list" ) } };
+ var self = this;
+ this.multiple();
+ this.with_test_connector( function() {
+ ok( ! self.test_accept( other ) );
+ } );
+ } );
+
module( "Connector test", {
} );
@@ -483,6 +501,17 @@
return c;
},
+ connectAttachedMultiInputTerminal: function( inputType, outputType ) {
+ this.view.addDataInput( { name: "TestName", extensions: [ inputType ], multiple: true } );
+ var terminal = this.view.node.input_terminals[ "TestName" ];
+
+ var outputTerminal = new OutputTerminal( { name: "TestOuptut", datatypes: [ "txt" ] } );
+ outputTerminal.node = { markChanged: function() {}, post_job_actions: [], hasMappedOverInputTerminals: function() { return false; }, hasConnectedOutputTerminals: function() { return true; } };
+ outputTerminal.terminalMapping = { disableMapOver: function() {}, mapOver: new CollectionTypeDescription( "list" ) };
+ var c = new Connector( outputTerminal, terminal );
+
+ return c;
+ },
connectAttachedMappedOutput: function( ) {
this.view.addDataInput( { name: "TestName", extensions: [ "txt" ], input_type: "dataset_collection" } );
var terminal = this.view.node.input_terminals[ "TestName" ];
@@ -530,6 +559,14 @@
ok( connector.handle2 === terminal );
} );
+ test( "replacing terminal on data multiple input update preserves collection connections", function() {
+ var connector = this.connectAttachedMultiInputTerminal( "txt", "txt" );
+ var connector_destroy_spy = sinon.spy( connector, "destroy" );
+ var newElement = $("<div class='inputs'></div>");
+ this.view.addDataInput( { name: "TestName", extensions: ["txt"], multiple: true }, newElement );
+ ok( ! connector_destroy_spy.called );
+ } );
+
test( "replacing mapped terminal on data collection input update preserves connections", function() {
var connector = this.connectAttachedMappedOutput();
var newElement = $("<div class='inputs'></div>");
@@ -922,12 +959,11 @@
this.verifyAttachable( inputTerminal1, "list" );
} );
- test( "connected multiple input cannot be connected to collections", function() {
+ test( "multiple input attachable by collections", function() {
var inputTerminal1 = this.newInputTerminal( null, { multiple: true } );
var connectedInput1 = this.addConnectedInput( inputTerminal1 );
this.addConnectedOutput( connectedInput1 );
- // Normally could do this reduction, but cannot because input already connected.
- this.verifyNotAttachable( connectedInput1, "list" );
+ this.verifyAttachable( inputTerminal1, "list" );
} );
test( "unconnected multiple inputs cannot be connected to rank > 1 collections (yet...)", function() {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/21336cf33cee/
Changeset: 21336cf33cee
Branch: stable
User: jmchilton
Date: 2014-09-02 17:20:44
Summary: Fix workflow editor bug related state updates for collections attached to multiple input data parameters.
Detail bug report from Michael Crusoe here : https://trello.com/c/0mdGCx4P.
This also fixes a test case added in 289e48b which was both attempting to assert something wrong and was incorrectly implemented. Augmenting the workflow editor test suite with some actually valid test cases that assert the correct behaviors.
For a longer explaination - workflow input terminals have two related concepts 'canAccept' and 'attachable'. An output terminal is 'attachable' if in the abstract it could be attached to the input regardless of whether the input is already filled or not. 'canAccept' is more stateful in that an output terminal is 'canAccept'able if the input terminal is not filled ('_inputFilled') and it is 'attachable'.
So - the problem was 'attachable' was not correctly defined for a multiple input data parameters. 'attachable' was asserting that any connected input terminal could not be 'attachable' by an collection output terminal - so on these asynchronous node state changes collections attached to multiple input data parameters were being wiped out. The more percise/correct distinction is that if a multiple input data parameter has single inputs connected to it - it cannot also have a collection connected to it (yet anyway). This fixes the mentioned bug.
The problematic test case was conflating 'attachable' and 'canAccept'able - I have fixed the test case to verify the correct 'attachable' logic and added newer, higher level test cases to test the canAccept logic and the actual behavior the end user would observe (of the connector being destroy).
Affected #: 2 files
diff -r 91547729ffde69eb1c1276d634ab642ef7f8a08b -r 21336cf33cee13e223c751a97b6501e40720591d static/scripts/galaxy.workflow_editor.canvas.js
--- a/static/scripts/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/galaxy.workflow_editor.canvas.js
@@ -302,19 +302,12 @@
inputFilled = false;
} else {
if( this.multiple ) {
- if( ! this.connected() ) {
+ if(this._collectionAttached()) {
+ // Can only attach one collection to multiple input
+ // data parameter.
+ inputsFilled = true;
+ } else {
inputFilled = false;
- } else {
- var firstOutput = this.connectors[ 0 ].handle1;
- if( ! firstOutput ){
- inputFilled = false;
- } else {
- if( firstOutput.isDataCollectionInput || firstOutput.isMappedOver() || firstOutput.datatypes.indexOf( "input_collection" ) > 0 ) {
- inputFilled = true;
- } else {
- inputFilled = false;
- }
- }
}
} else {
inputFilled = true;
@@ -322,6 +315,22 @@
}
return inputFilled;
},
+ _collectionAttached: function( ) {
+ if( ! this.connected() ) {
+ return false;
+ } else {
+ var firstOutput = this.connectors[ 0 ].handle1;
+ if( ! firstOutput ){
+ return false;
+ } else {
+ if( firstOutput.isDataCollectionInput || firstOutput.isMappedOver() || firstOutput.datatypes.indexOf( "input_collection" ) > 0 ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ },
_mappingConstraints: function( ) {
// If this is a connected terminal, return list of collection types
// other terminals connected to node are constraining mapping to.
@@ -407,7 +416,9 @@
var thisMapOver = this.mapOver();
if( otherCollectionType.isCollection ) {
if( this.multiple ) {
- if( this.connected() ) {
+ if( this.connected() && ! this._collectionAttached() ) {
+ // if single inputs attached, cannot also attach a
+ // collection (yet...)
return false;
}
if( otherCollectionType.rank == 1 ) {
diff -r 91547729ffde69eb1c1276d634ab642ef7f8a08b -r 21336cf33cee13e223c751a97b6501e40720591d test/qunit/tests/workflow_editor_tests.js
--- a/test/qunit/tests/workflow_editor_tests.js
+++ b/test/qunit/tests/workflow_editor_tests.js
@@ -91,7 +91,9 @@
},
test_accept: function( other ) {
other = other || { node: {}, datatypes: [ "txt" ] };
- other.mapOver = function() { return NULL_COLLECTION_TYPE_DESCRIPTION; };
+ if( ! other.mapOver ) {
+ other.mapOver = function() { return NULL_COLLECTION_TYPE_DESCRIPTION; };
+ }
return this.input_terminal.canAccept( other );
},
pja_change_datatype_node: function( output_name, newtype ) {
@@ -230,6 +232,22 @@
ok( self.test_accept() );
} );
+ test( "can accept list collection for empty multiple inputs", function() {
+ var other = { node: {}, datatypes: [ "tabular" ], mapOver: function() { return new CollectionTypeDescription( "list" ) } };
+ var self = this;
+ this.multiple();
+ ok( self.test_accept( other ) );
+ } );
+
+ test( "cannot accept list collection for multiple input if collection already connected", function() {
+ var other = { node: {}, datatypes: [ "tabular" ], mapOver: function() { return new CollectionTypeDescription( "list" ) } };
+ var self = this;
+ this.multiple();
+ this.with_test_connector( function() {
+ ok( ! self.test_accept( other ) );
+ } );
+ } );
+
module( "Connector test", {
} );
@@ -483,6 +501,17 @@
return c;
},
+ connectAttachedMultiInputTerminal: function( inputType, outputType ) {
+ this.view.addDataInput( { name: "TestName", extensions: [ inputType ], multiple: true } );
+ var terminal = this.view.node.input_terminals[ "TestName" ];
+
+ var outputTerminal = new OutputTerminal( { name: "TestOuptut", datatypes: [ "txt" ] } );
+ outputTerminal.node = { markChanged: function() {}, post_job_actions: [], hasMappedOverInputTerminals: function() { return false; }, hasConnectedOutputTerminals: function() { return true; } };
+ outputTerminal.terminalMapping = { disableMapOver: function() {}, mapOver: new CollectionTypeDescription( "list" ) };
+ var c = new Connector( outputTerminal, terminal );
+
+ return c;
+ },
connectAttachedMappedOutput: function( ) {
this.view.addDataInput( { name: "TestName", extensions: [ "txt" ], input_type: "dataset_collection" } );
var terminal = this.view.node.input_terminals[ "TestName" ];
@@ -530,6 +559,14 @@
ok( connector.handle2 === terminal );
} );
+ test( "replacing terminal on data multiple input update preserves collection connections", function() {
+ var connector = this.connectAttachedMultiInputTerminal( "txt", "txt" );
+ var connector_destroy_spy = sinon.spy( connector, "destroy" );
+ var newElement = $("<div class='inputs'></div>");
+ this.view.addDataInput( { name: "TestName", extensions: ["txt"], multiple: true }, newElement );
+ ok( ! connector_destroy_spy.called );
+ } );
+
test( "replacing mapped terminal on data collection input update preserves connections", function() {
var connector = this.connectAttachedMappedOutput();
var newElement = $("<div class='inputs'></div>");
@@ -922,12 +959,11 @@
this.verifyAttachable( inputTerminal1, "list" );
} );
- test( "connected multiple input cannot be connected to collections", function() {
+ test( "multiple input attachable by collections", function() {
var inputTerminal1 = this.newInputTerminal( null, { multiple: true } );
var connectedInput1 = this.addConnectedInput( inputTerminal1 );
this.addConnectedOutput( connectedInput1 );
- // Normally could do this reduction, but cannot because input already connected.
- this.verifyNotAttachable( connectedInput1, "list" );
+ this.verifyAttachable( inputTerminal1, "list" );
} );
test( "unconnected multiple inputs cannot be connected to rank > 1 collections (yet...)", function() {
https://bitbucket.org/galaxy/galaxy-central/commits/20f4fdf1735a/
Changeset: 20f4fdf1735a
Branch: stable
User: jmchilton
Date: 2014-09-02 17:21:08
Summary: Pack scripts.
Affected #: 1 file
diff -r 21336cf33cee13e223c751a97b6501e40720591d -r 20f4fdf1735aeff23a6e7ab00389781fe3f3142c static/scripts/packed/galaxy.workflow_editor.canvas.js
--- a/static/scripts/packed/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js
@@ -1,1 +1,1 @@
-function CollectionTypeDescription(a){this.collectionType=a;this.isCollection=true;this.rank=a.split(":").length}$.extend(CollectionTypeDescription.prototype,{append:function(a){if(a===NULL_COLLECTION_TYPE_DESCRIPTION){return this}if(a===ANY_COLLECTION_TYPE_DESCRIPTION){return otherCollectionType}return new CollectionTypeDescription(this.collectionType+":"+a.collectionType)},canMatch:function(a){if(a===NULL_COLLECTION_TYPE_DESCRIPTION){return false}if(a===ANY_COLLECTION_TYPE_DESCRIPTION){return true}return a.collectionType==this.collectionType},canMapOver:function(b){if(b===NULL_COLLECTION_TYPE_DESCRIPTION){return false}if(b===ANY_COLLECTION_TYPE_DESCRIPTION){return false}if(this.rank<=b.rank){return false}var a=b.collectionType;return this._endsWith(this.collectionType,a)},effectiveMapOver:function(a){var c=a.collectionType;var b=this.collectionType.substring(0,this.collectionType.length-c.length-1);return new CollectionTypeDescription(b)},equal:function(a){return a.collectionType==this.collectionType},toString:function(){return"CollectionType["+this.collectionType+"]"},_endsWith:function(b,a){return b.indexOf(a,b.length-a.length)!==-1}});NULL_COLLECTION_TYPE_DESCRIPTION={isCollection:false,canMatch:function(a){return false},canMapOver:function(a){return false},toString:function(){return"NullCollectionType[]"},append:function(a){return a},equal:function(a){return a===this}};ANY_COLLECTION_TYPE_DESCRIPTION={isCollection:true,canMatch:function(a){return NULL_COLLECTION_TYPE_DESCRIPTION!==a},canMapOver:function(a){return false},toString:function(){return"AnyCollectionType[]"},append:function(a){throw"Cannot append to ANY_COLLECTION_TYPE_DESCRIPTION"},equal:function(a){return a===this}};var TerminalMapping=Backbone.Model.extend({initialize:function(a){this.mapOver=a.mapOver||NULL_COLLECTION_TYPE_DESCRIPTION;this.terminal=a.terminal;this.terminal.terminalMapping=this},disableMapOver:function(){this.setMapOver(NULL_COLLECTION_TYPE_DESCRIPTION)},setMapOver:function(a){this.mapOver=a;this.trigger("change")}});var TerminalMappingView=Backbone.View.extend({tagName:"div",className:"fa-icon-button fa fa-folder-o",initialize:function(b){var a="Run tool in parallel over collection";this.$el.tooltip({delay:500,title:a});this.model.bind("change",_.bind(this.render,this))},render:function(){if(this.model.mapOver.isCollection){this.$el.show()}else{this.$el.hide()}},});var InputTerminalMappingView=TerminalMappingView.extend({events:{click:"onClick",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",},onMouseEnter:function(b){var a=this.model;if(!a.terminal.connected()&&a.mapOver.isCollection){this.$el.css("color","red")}},onMouseLeave:function(a){this.$el.css("color","black")},onClick:function(b){var a=this.model;if(!a.terminal.connected()&&a.mapOver.isCollection){a.terminal.resetMapping()}},});var InputTerminalMapping=TerminalMapping;var InputCollectionTerminalMapping=TerminalMapping;var OutputTerminalMapping=TerminalMapping;var OutputTerminalMappingView=TerminalMappingView;var InputCollectionTerminalMappingView=InputTerminalMappingView;var OutputCollectionTerminalMapping=TerminalMapping;var OutputCollectionTerminalMappingView=TerminalMappingView;var Terminal=Backbone.Model.extend({initialize:function(a){this.element=a.element;this.connectors=[]},connect:function(a){this.connectors.push(a);if(this.node){this.node.markChanged()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.markChanged();this.resetMappingIfNeeded()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})},destroyInvalidConnections:function(){_.each(this.connectors,function(a){a.destroyIfInvalid()})},setMapOver:function(a){if(this.multiple){return}if(!this.mapOver().equal(a)){this.terminalMapping.setMapOver(a);_.each(this.node.output_terminals,function(b){b.setMapOver(a)})}},mapOver:function(){if(!this.terminalMapping){return NULL_COLLECTION_TYPE_DESCRIPTION}else{return this.terminalMapping.mapOver}},isMappedOver:function(){return this.terminalMapping&&this.terminalMapping.mapOver.isCollection},resetMapping:function(){this.terminalMapping.disableMapOver()},resetMappingIfNeeded:function(){},});var OutputTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.datatypes=a.datatypes},resetMappingIfNeeded:function(){if(!this.node.hasConnectedOutputTerminals()&&!this.node.hasConnectedMappedInputTerminals()){_.each(this.node.mappedInputTerminals(),function(b){b.resetMappingIfNeeded()})}var a=!this.node.hasMappedOverInputTerminals();if(a){this.resetMapping()}},resetMapping:function(){this.terminalMapping.disableMapOver();_.each(this.connectors,function(a){var b=a.handle2;if(b){b.resetMappingIfNeeded();a.destroyIfInvalid()}})}});var BaseInputTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.update(a.input)},canAccept:function(a){if(this._inputFilled()){return false}else{return this.attachable(a)}},resetMappingIfNeeded:function(){var b=this.mapOver();if(!b.isCollection){return}var a=this.node.hasConnectedMappedInputTerminals()||(!this.node.hasConnectedOutputTerminals());if(a){this.resetMapping()}},resetMapping:function(){this.terminalMapping.disableMapOver();if(!this.node.hasMappedOverInputTerminals()){_.each(this.node.output_terminals,function(a){a.resetMapping()})}},connected:function(){return this.connectors.length!==0},_inputFilled:function(){var a;if(!this.connected()){a=false}else{if(this.multiple){if(!this.connected()){a=false}else{var b=this.connectors[0].handle1;if(!b){a=false}else{if(b.isDataCollectionInput||b.isMappedOver()||b.datatypes.indexOf("input_collection")>0){a=true}else{a=false}}}}else{a=true}}return a},_mappingConstraints:function(){if(!this.node){return[]}var b=this.mapOver();if(b.isCollection){return[b]}var a=[];if(!this.node.hasConnectedOutputTerminals()){_.each(this.node.connectedMappedInputTerminals(),function(c){a.push(c.mapOver())})}else{a.push(_.first(_.values(this.node.output_terminals)).mapOver())}return a},_producesAcceptableDatatype:function(a){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){var h=f[b];if(h=="input"||h=="input_collection"||issubtype(f[b],this.datatypes[c])){return true}}}return false},_otherCollectionType:function(a){var c=NULL_COLLECTION_TYPE_DESCRIPTION;if(a.isDataCollectionInput){c=a.collectionType}else{var b=a.mapOver();if(b.isCollection){c=b}}return c},});var InputTerminal=BaseInputTerminal.extend({update:function(a){this.datatypes=a.extensions;this.multiple=a.multiple;this.collection=false},connect:function(a){BaseInputTerminal.prototype.connect.call(this,a);var b=a.handle1;if(!b){return}var c=this._otherCollectionType(b);if(c.isCollection){this.setMapOver(c)}},attachable:function(b){var d=this._otherCollectionType(b);var a=this.mapOver();if(d.isCollection){if(this.multiple){if(this.connected()){return false}if(d.rank==1){return this._producesAcceptableDatatype(b)}else{return false}}if(a.isCollection&&a.canMatch(d)){return this._producesAcceptableDatatype(b)}else{var c=this._mappingConstraints();if(c.every(_.bind(d.canMatch,d))){return this._producesAcceptableDatatype(b)}else{return false}}}else{if(a.isCollection){return false}}return this._producesAcceptableDatatype(b)}});var InputCollectionTerminal=BaseInputTerminal.extend({update:function(a){this.multiple=false;this.collection=true;this.datatypes=a.extensions;if(a.collection_type){this.collectionType=new CollectionTypeDescription(a.collection_type)}else{this.collectionType=ANY_COLLECTION_TYPE_DESCRIPTION}},connect:function(b){BaseInputTerminal.prototype.connect.call(this,b);var a=b.handle1;if(!a){return}var c=this._effectiveMapOver(a);this.setMapOver(c)},_effectiveMapOver:function(a){var b=this.collectionType;var c=this._otherCollectionType(a);if(!b.canMatch(c)){return c.effectiveMapOver(b)}else{return NULL_COLLECTION_TYPE_DESCRIPTION}},_effectiveCollectionType:function(){var b=this.collectionType;var a=this.mapOver();return a.append(b)},attachable:function(b){var g=this._otherCollectionType(b);if(g.isCollection){var f=this._effectiveCollectionType();var a=this.mapOver();if(f.canMatch(g)){return this._producesAcceptableDatatype(b)}else{if(a.isCollection){return false}else{if(g.canMapOver(this.collectionType)){var d=this._effectiveMapOver(b);if(!d.isCollection){return false}var c=this._mappingConstraints();if(c.every(d.canMatch)){return this._producesAcceptableDatatype(b)}}}}}return false}});var OutputCollectionTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.datatypes=a.datatypes;this.collectionType=new CollectionTypeDescription(a.collection_type);this.isDataCollectionInput=true},update:function(a){var b=new CollectionTypeDescription(a.collection_type);if(b.collectionType!=this.collectionType.collectionType){_.each(this.connectors,function(c){c.destroy()})}this.collectionType=b}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},destroyIfInvalid:function(){if(this.handle1&&this.handle2&&!this.handle2.attachable(this.handle1)){this.destroy()}},redraw:function(){var f=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}f.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var v=function(c){return $(c).offset().left-f.offset().left};var p=function(c){return $(c).offset().top-f.offset().top};if(!this.handle1||!this.handle2){return}var o=v(this.handle1.element)+5;var n=p(this.handle1.element)+5;var x=v(this.handle2.element)+5;var u=p(this.handle2.element)+5;var k=100;var r=Math.min(o,x);var a=Math.max(o,x);var q=Math.min(n,u);var B=Math.max(n,u);var d=Math.min(Math.max(Math.abs(B-q)/2,100),300);var w=r-k;var A=q-k;var y=a-r+2*k;var s=B-q+2*k;this.canvas.style.left=w+"px";this.canvas.style.top=A+"px";this.canvas.setAttribute("width",y);this.canvas.setAttribute("height",s);o-=w;n-=A;x-=w;u-=A;var z=this.canvas.getContext("2d"),h=null,l=null;var g=1;if(this.handle1&&this.handle1.isMappedOver()){var h=[-6,-3,0,3,6];g=5}else{var h=[0]}if(this.handle2&&this.handle2.isMappedOver()){var l=[-6,-3,0,3,6];g=5}else{var l=[0]}var b=this;for(var t=0;t<g;t++){var m=5,j=7;if(h.length>1||l.length>1){m=1;j=3}b.draw_outlined_curve(o,n,x,u,d,m,j,h[t%h.length],l[t%l.length])}},draw_outlined_curve:function(j,i,l,k,a,b,f,g,d){var g=g||0;var d=d||0;var h=this.canvas.getContext("2d");h.lineCap="round";h.strokeStyle=this.outer_color;h.lineWidth=f;h.beginPath();h.moveTo(j,i+g);h.bezierCurveTo(j+a,i+g,l-a,k+d,l,k+d);h.stroke();h.strokeStyle=this.inner_color;h.lineWidth=b;h.beginPath();h.moveTo(j,i+g);h.bezierCurveTo(j+a,i+g,l-a,k+d,l,k+d);h.stroke()}});var Node=Backbone.Model.extend({initialize:function(a){this.element=a.element;this.input_terminals={};this.output_terminals={};this.tool_errors={}},connectedOutputTerminals:function(){return this._connectedTerminals(this.output_terminals)},_connectedTerminals:function(b){var a=[];$.each(b,function(c,d){if(d.connectors.length>0){a.push(d)}});return a},hasConnectedOutputTerminals:function(){var a=this.output_terminals;for(var b in a){if(a[b].connectors.length>0){return true}}return false},connectedMappedInputTerminals:function(){return this._connectedMappedTerminals(this.input_terminals)},hasConnectedMappedInputTerminals:function(){var c=this.input_terminals;for(var b in c){var a=c[b];if(a.connectors.length>0&&a.isMappedOver()){return true}}return false},_connectedMappedTerminals:function(b){var a=[];$.each(b,function(c,d){var f=d.mapOver();if(f.isCollection){if(d.connectors.length>0){a.push(d)}}});return a},mappedInputTerminals:function(){return this._mappedTerminals(this.input_terminals)},_mappedTerminals:function(b){var a=[];$.each(b,function(c,d){var f=d.mapOver();if(f.isCollection){a.push(d)}});return a},hasMappedOverInputTerminals:function(){var a=false;_.each(this.input_terminals,function(b){var c=b.mapOver();if(c.isCollection){a=true}});return a},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(b){if(b.type){this.type=b.type}this.name=b.name;this.form_html=b.form_html;this.tool_state=b.tool_state;this.tool_errors=b.tool_errors;this.tooltip=b.tooltip?b.tooltip:"";this.annotation=b.annotation;this.post_job_actions=b.post_job_actions?b.post_job_actions:{};this.workflow_outputs=b.workflow_outputs?b.workflow_outputs:[];var a=this;var c=new NodeView({el:this.element[0],node:a,});a.nodeView=c;$.each(b.data_inputs,function(f,d){c.addDataInput(d)});if((b.data_inputs.length>0)&&(b.data_outputs.length>0)){c.addRule()}$.each(b.data_outputs,function(f,d){c.addDataOutput(d)});c.render();workflow.node_changed(this)},update_field_data:function(d){var c=this;nodeView=c.nodeView;this.tool_state=d.tool_state;this.form_html=d.form_html;this.tool_errors=d.tool_errors;this.annotation=d.annotation;if("post_job_actions" in d){var f=$.parseJSON(d.post_job_actions);this.post_job_actions=f?f:{}}c.nodeView.renderToolErrors();var g=nodeView.$("div.inputs");var a=nodeView.newInputsDiv();var b={};_.each(d.data_inputs,function(h){var i=c.nodeView.addDataInput(h,a);b[h.name]=i});_.each(_.difference(_.values(nodeView.terminalViews),_.values(b)),function(h){h.el.terminal.destroy()});nodeView.terminalViews=b;if(d.data_outputs.length==1&&"collection_type" in d.data_outputs[0]){nodeView.updateDataOutput(d.data_outputs[0])}g.replaceWith(a);this.markChanged();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},markChanged:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node(f.type,f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if(!$.isArray(h)){h=[h]}$.each(h,function(k,j){var m=wf.nodes[j.id];var n=new Connector();n.connect(m.output_terminals[j.output_name],d.input_terminals[i]);n.redraw()})}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node({element:i});g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+galaxy_config.root+"static/images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<div>").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}function add_node(b,d,a){var c=prebuild_node(b,d,a);workflow.add_node(c);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview();workflow.activate_node(c);return c}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}var NodeView=Backbone.View.extend({initialize:function(a){this.node=a.node;this.output_width=Math.max(150,this.$el.width());this.tool_body=this.$el.find(".toolFormBody");this.tool_body.find("div").remove();this.newInputsDiv().appendTo(this.tool_body);this.terminalViews={};this.outputTerminlViews={}},render:function(){this.renderToolErrors();this.$el.css("width",Math.min(250,Math.max(this.$el.width(),this.output_width)))},renderToolErrors:function(){if(this.node.tool_errors){this.$el.addClass("tool-node-error")}else{this.$el.removeClass("tool-node-error")}},newInputsDiv:function(){return $("<div class='inputs'></div>")},updateMaxWidth:function(a){this.output_width=Math.max(this.output_width,a)},addRule:function(){this.tool_body.append($("<div class='rule'></div>"))},addDataInput:function(i,d){var j=true;if(!d){d=this.$(".inputs");j=false}var f=this.terminalViews[i.name];var h=(i.input_type=="dataset_collection")?InputCollectionTerminalView:InputTerminalView;if(f&&!(f instanceof h)){f.el.terminal.destroy();f=null}if(!f){f=new h({node:this.node,input:i})}else{var g=f.el.terminal;g.update(i);g.destroyInvalidConnections()}this.terminalViews[i.name]=f;var c=f.el;var b=new DataInputView({terminalElement:c,input:i,nodeView:this,skipResize:j});var a=b.$el;d.append(a.prepend(f.terminalElements()));return f},addDataOutput:function(a){var d=(a.collection_type)?OutputCollectionTerminalView:OutputTerminalView;var c=new d({node:this.node,output:a});var b=new DataOutputView({output:a,terminalElement:c.el,nodeView:this,});this.tool_body.append(b.$el.append(c.terminalElements()))},updateDataOutput:function(b){var a=this.node.output_terminals[b.name];a.update(b)}});var DataInputView=Backbone.View.extend({className:"form-row dataRow input-data-row",initialize:function(a){this.input=a.input;this.nodeView=a.nodeView;this.terminalElement=a.terminalElement;this.$el.attr("name",this.input.name).html(this.input.label);if(!a.skipResize){this.$el.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(this.el);this.nodeView.updateMaxWidth(this.$el.outerWidth());this.$el.css({position:"",left:"",top:"",display:""});this.$el.remove()}},});var OutputCalloutView=Backbone.View.extend({tagName:"div",initialize:function(b){this.label=b.label;this.node=b.node;this.output=b.output;var a=this;this.$el.attr("class","callout "+this.label).css({display:"none"}).append($("<div class='buttons'></div>").append($("<img/>").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(a.output.name,a.node.workflow_outputs)!=-1){a.node.workflow_outputs.splice($.inArray(a.output.name,a.node.workflow_outputs),1);a.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{a.node.workflow_outputs.push(a.output.name);a.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});this.$el.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});this.$el.show();this.resetImage()},resetImage:function(){if($.inArray(this.output.name,this.node.workflow_outputs)===-1){this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}},hoverImage:function(){this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")}});var DataOutputView=Backbone.View.extend({className:"form-row dataRow",initialize:function(c){this.output=c.output;this.terminalElement=c.terminalElement;this.nodeView=c.nodeView;var a=this.output;var b=a.name;var f=this.nodeView.node;var d=a.extensions.indexOf("input")>=0||a.extensions.indexOf("input_collection")>=0;if(!d){b=b+" ("+a.extensions.join(", ")+")"}this.$el.html(b);if(f.type=="tool"){var g=new OutputCalloutView({label:b,output:a,node:f,});this.$el.append(g.el);this.$el.hover(function(){g.hoverImage()},function(){g.resetImage()})}this.$el.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(this.el);this.nodeView.updateMaxWidth(this.$el.outerWidth()+17);this.$el.css({position:"",left:"",top:"",display:""}).detach()}});var TerminalView=Backbone.View.extend({setupMappingView:function(b){var c=new this.terminalMappingClass({terminal:b});var a=new this.terminalMappingViewClass({model:c});a.render();b.terminalMappingView=a;this.terminalMappingView=a},terminalElements:function(){if(this.terminalMappingView){return[this.terminalMappingView.el,this.el]}else{return[this.el]}}});var BaseInputTerminalView=TerminalView.extend({className:"terminal input-terminal",initialize:function(c){var f=c.node;var a=c.input;var b=a.name;var d=this.terminalForInput(a);if(!d.multiple){this.setupMappingView(d)}this.el.terminal=d;d.node=f;d.name=b;f.input_terminals[b]=d},events:{dropinit:"onDropInit",dropstart:"onDropStart",dropend:"onDropEnd",drop:"onDrop",hover:"onHover",},onDropInit:function(b,c){var a=this.el.terminal;return $(c.drag).hasClass("output-terminal")&&a.canAccept(c.drag.terminal)},onDropStart:function(a,b){if(b.proxy.terminal){b.proxy.terminal.connectors[0].inner_color="#BBFFBB"}},onDropEnd:function(a,b){if(b.proxy.terminal){b.proxy.terminal.connectors[0].inner_color="#FFFFFF"}},onDrop:function(b,c){var a=this.el.terminal;new Connector(c.drag.terminal,a).redraw()},onHover:function(){var c=this.el;var b=c.terminal;if(b.connectors.length>0){var a=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa fa-times").click(function(){$.each(b.connectors,function(f,d){if(d){d.destroy()}});a.remove()}))).bind("mouseleave",function(){$(this).remove()});a.css({top:$(c).offset().top-2,left:$(c).offset().left-a.width(),"padding-right":$(c).width()}).show()}},});var InputTerminalView=BaseInputTerminalView.extend({terminalMappingClass:InputTerminalMapping,terminalMappingViewClass:InputTerminalMappingView,terminalForInput:function(a){return new InputTerminal({element:this.el,input:a})},});var InputCollectionTerminalView=BaseInputTerminalView.extend({terminalMappingClass:InputCollectionTerminalMapping,terminalMappingViewClass:InputCollectionTerminalMappingView,terminalForInput:function(a){return new InputCollectionTerminal({element:this.el,input:a})},});var BaseOutputTerminalView=TerminalView.extend({className:"terminal output-terminal",initialize:function(c){var f=c.node;var a=c.output;var b=a.name;var d=this.terminalForOutput(a);this.setupMappingView(d);this.el.terminal=d;d.node=f;d.name=b;f.output_terminals[b]=d},events:{drag:"onDrag",dragstart:"onDragStart",dragend:"onDragEnd",},onDrag:function(b,c){var a=function(){var f=$(c.proxy).offsetParent().offset(),d=c.offsetX-f.left,g=c.offsetY-f.top;$(c.proxy).css({left:d,top:g});c.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};a();$("#canvas-container").get(0).scroll_panel.test(b,a)},onDragStart:function(b,f){$(f.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var a=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);a.terminal=new OutputTerminal({element:a});var g=new Connector();g.dragging=true;g.connect(this.el.terminal,a.terminal);return a},onDragEnd:function(b,c){var a=c.proxy.terminal.connectors[0];if(a){a.destroy()}$(c.proxy).remove();$(c.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()}});var OutputTerminalView=BaseOutputTerminalView.extend({terminalMappingClass:OutputTerminalMapping,terminalMappingViewClass:OutputTerminalMappingView,terminalForOutput:function(a){var c=a.extensions;var b=new OutputTerminal({element:this.el,datatypes:c});return b},});var OutputCollectionTerminalView=BaseOutputTerminalView.extend({terminalMappingClass:OutputCollectionTerminalMapping,terminalMappingViewClass:OutputCollectionTerminalMappingView,terminalForOutput:function(a){var c=a.collection_type;var b=new OutputCollectionTerminal({element:this.el,collection_type:c,datatypes:a.extensions});return b},});function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);$.each(workflow.nodes,function(t,q){i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;if(q.tool_errors){i.fillStyle="#FFCCCC";i.strokeStyle="#AA6666"}else{if(q.workflow_outputs!=undefined&&q.workflow_outputs.length>0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
+function CollectionTypeDescription(a){this.collectionType=a;this.isCollection=true;this.rank=a.split(":").length}$.extend(CollectionTypeDescription.prototype,{append:function(a){if(a===NULL_COLLECTION_TYPE_DESCRIPTION){return this}if(a===ANY_COLLECTION_TYPE_DESCRIPTION){return otherCollectionType}return new CollectionTypeDescription(this.collectionType+":"+a.collectionType)},canMatch:function(a){if(a===NULL_COLLECTION_TYPE_DESCRIPTION){return false}if(a===ANY_COLLECTION_TYPE_DESCRIPTION){return true}return a.collectionType==this.collectionType},canMapOver:function(b){if(b===NULL_COLLECTION_TYPE_DESCRIPTION){return false}if(b===ANY_COLLECTION_TYPE_DESCRIPTION){return false}if(this.rank<=b.rank){return false}var a=b.collectionType;return this._endsWith(this.collectionType,a)},effectiveMapOver:function(a){var c=a.collectionType;var b=this.collectionType.substring(0,this.collectionType.length-c.length-1);return new CollectionTypeDescription(b)},equal:function(a){return a.collectionType==this.collectionType},toString:function(){return"CollectionType["+this.collectionType+"]"},_endsWith:function(b,a){return b.indexOf(a,b.length-a.length)!==-1}});NULL_COLLECTION_TYPE_DESCRIPTION={isCollection:false,canMatch:function(a){return false},canMapOver:function(a){return false},toString:function(){return"NullCollectionType[]"},append:function(a){return a},equal:function(a){return a===this}};ANY_COLLECTION_TYPE_DESCRIPTION={isCollection:true,canMatch:function(a){return NULL_COLLECTION_TYPE_DESCRIPTION!==a},canMapOver:function(a){return false},toString:function(){return"AnyCollectionType[]"},append:function(a){throw"Cannot append to ANY_COLLECTION_TYPE_DESCRIPTION"},equal:function(a){return a===this}};var TerminalMapping=Backbone.Model.extend({initialize:function(a){this.mapOver=a.mapOver||NULL_COLLECTION_TYPE_DESCRIPTION;this.terminal=a.terminal;this.terminal.terminalMapping=this},disableMapOver:function(){this.setMapOver(NULL_COLLECTION_TYPE_DESCRIPTION)},setMapOver:function(a){this.mapOver=a;this.trigger("change")}});var TerminalMappingView=Backbone.View.extend({tagName:"div",className:"fa-icon-button fa fa-folder-o",initialize:function(b){var a="Run tool in parallel over collection";this.$el.tooltip({delay:500,title:a});this.model.bind("change",_.bind(this.render,this))},render:function(){if(this.model.mapOver.isCollection){this.$el.show()}else{this.$el.hide()}},});var InputTerminalMappingView=TerminalMappingView.extend({events:{click:"onClick",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",},onMouseEnter:function(b){var a=this.model;if(!a.terminal.connected()&&a.mapOver.isCollection){this.$el.css("color","red")}},onMouseLeave:function(a){this.$el.css("color","black")},onClick:function(b){var a=this.model;if(!a.terminal.connected()&&a.mapOver.isCollection){a.terminal.resetMapping()}},});var InputTerminalMapping=TerminalMapping;var InputCollectionTerminalMapping=TerminalMapping;var OutputTerminalMapping=TerminalMapping;var OutputTerminalMappingView=TerminalMappingView;var InputCollectionTerminalMappingView=InputTerminalMappingView;var OutputCollectionTerminalMapping=TerminalMapping;var OutputCollectionTerminalMappingView=TerminalMappingView;var Terminal=Backbone.Model.extend({initialize:function(a){this.element=a.element;this.connectors=[]},connect:function(a){this.connectors.push(a);if(this.node){this.node.markChanged()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.markChanged();this.resetMappingIfNeeded()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})},destroyInvalidConnections:function(){_.each(this.connectors,function(a){a.destroyIfInvalid()})},setMapOver:function(a){if(this.multiple){return}if(!this.mapOver().equal(a)){this.terminalMapping.setMapOver(a);_.each(this.node.output_terminals,function(b){b.setMapOver(a)})}},mapOver:function(){if(!this.terminalMapping){return NULL_COLLECTION_TYPE_DESCRIPTION}else{return this.terminalMapping.mapOver}},isMappedOver:function(){return this.terminalMapping&&this.terminalMapping.mapOver.isCollection},resetMapping:function(){this.terminalMapping.disableMapOver()},resetMappingIfNeeded:function(){},});var OutputTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.datatypes=a.datatypes},resetMappingIfNeeded:function(){if(!this.node.hasConnectedOutputTerminals()&&!this.node.hasConnectedMappedInputTerminals()){_.each(this.node.mappedInputTerminals(),function(b){b.resetMappingIfNeeded()})}var a=!this.node.hasMappedOverInputTerminals();if(a){this.resetMapping()}},resetMapping:function(){this.terminalMapping.disableMapOver();_.each(this.connectors,function(a){var b=a.handle2;if(b){b.resetMappingIfNeeded();a.destroyIfInvalid()}})}});var BaseInputTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.update(a.input)},canAccept:function(a){if(this._inputFilled()){return false}else{return this.attachable(a)}},resetMappingIfNeeded:function(){var b=this.mapOver();if(!b.isCollection){return}var a=this.node.hasConnectedMappedInputTerminals()||(!this.node.hasConnectedOutputTerminals());if(a){this.resetMapping()}},resetMapping:function(){this.terminalMapping.disableMapOver();if(!this.node.hasMappedOverInputTerminals()){_.each(this.node.output_terminals,function(a){a.resetMapping()})}},connected:function(){return this.connectors.length!==0},_inputFilled:function(){var a;if(!this.connected()){a=false}else{if(this.multiple){if(this._collectionAttached()){inputsFilled=true}else{a=false}}else{a=true}}return a},_collectionAttached:function(){if(!this.connected()){return false}else{var a=this.connectors[0].handle1;if(!a){return false}else{if(a.isDataCollectionInput||a.isMappedOver()||a.datatypes.indexOf("input_collection")>0){return true}else{return false}}}},_mappingConstraints:function(){if(!this.node){return[]}var b=this.mapOver();if(b.isCollection){return[b]}var a=[];if(!this.node.hasConnectedOutputTerminals()){_.each(this.node.connectedMappedInputTerminals(),function(c){a.push(c.mapOver())})}else{a.push(_.first(_.values(this.node.output_terminals)).mapOver())}return a},_producesAcceptableDatatype:function(a){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){var h=f[b];if(h=="input"||h=="input_collection"||issubtype(f[b],this.datatypes[c])){return true}}}return false},_otherCollectionType:function(a){var c=NULL_COLLECTION_TYPE_DESCRIPTION;if(a.isDataCollectionInput){c=a.collectionType}else{var b=a.mapOver();if(b.isCollection){c=b}}return c},});var InputTerminal=BaseInputTerminal.extend({update:function(a){this.datatypes=a.extensions;this.multiple=a.multiple;this.collection=false},connect:function(a){BaseInputTerminal.prototype.connect.call(this,a);var b=a.handle1;if(!b){return}var c=this._otherCollectionType(b);if(c.isCollection){this.setMapOver(c)}},attachable:function(b){var d=this._otherCollectionType(b);var a=this.mapOver();if(d.isCollection){if(this.multiple){if(this.connected()&&!this._collectionAttached()){return false}if(d.rank==1){return this._producesAcceptableDatatype(b)}else{return false}}if(a.isCollection&&a.canMatch(d)){return this._producesAcceptableDatatype(b)}else{var c=this._mappingConstraints();if(c.every(_.bind(d.canMatch,d))){return this._producesAcceptableDatatype(b)}else{return false}}}else{if(a.isCollection){return false}}return this._producesAcceptableDatatype(b)}});var InputCollectionTerminal=BaseInputTerminal.extend({update:function(a){this.multiple=false;this.collection=true;this.datatypes=a.extensions;if(a.collection_type){this.collectionType=new CollectionTypeDescription(a.collection_type)}else{this.collectionType=ANY_COLLECTION_TYPE_DESCRIPTION}},connect:function(b){BaseInputTerminal.prototype.connect.call(this,b);var a=b.handle1;if(!a){return}var c=this._effectiveMapOver(a);this.setMapOver(c)},_effectiveMapOver:function(a){var b=this.collectionType;var c=this._otherCollectionType(a);if(!b.canMatch(c)){return c.effectiveMapOver(b)}else{return NULL_COLLECTION_TYPE_DESCRIPTION}},_effectiveCollectionType:function(){var b=this.collectionType;var a=this.mapOver();return a.append(b)},attachable:function(b){var g=this._otherCollectionType(b);if(g.isCollection){var f=this._effectiveCollectionType();var a=this.mapOver();if(f.canMatch(g)){return this._producesAcceptableDatatype(b)}else{if(a.isCollection){return false}else{if(g.canMapOver(this.collectionType)){var d=this._effectiveMapOver(b);if(!d.isCollection){return false}var c=this._mappingConstraints();if(c.every(d.canMatch)){return this._producesAcceptableDatatype(b)}}}}}return false}});var OutputCollectionTerminal=Terminal.extend({initialize:function(a){Terminal.prototype.initialize.call(this,a);this.datatypes=a.datatypes;this.collectionType=new CollectionTypeDescription(a.collection_type);this.isDataCollectionInput=true},update:function(a){var b=new CollectionTypeDescription(a.collection_type);if(b.collectionType!=this.collectionType.collectionType){_.each(this.connectors,function(c){c.destroy()})}this.collectionType=b}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},destroyIfInvalid:function(){if(this.handle1&&this.handle2&&!this.handle2.attachable(this.handle1)){this.destroy()}},redraw:function(){var f=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}f.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var v=function(c){return $(c).offset().left-f.offset().left};var p=function(c){return $(c).offset().top-f.offset().top};if(!this.handle1||!this.handle2){return}var o=v(this.handle1.element)+5;var n=p(this.handle1.element)+5;var x=v(this.handle2.element)+5;var u=p(this.handle2.element)+5;var k=100;var r=Math.min(o,x);var a=Math.max(o,x);var q=Math.min(n,u);var B=Math.max(n,u);var d=Math.min(Math.max(Math.abs(B-q)/2,100),300);var w=r-k;var A=q-k;var y=a-r+2*k;var s=B-q+2*k;this.canvas.style.left=w+"px";this.canvas.style.top=A+"px";this.canvas.setAttribute("width",y);this.canvas.setAttribute("height",s);o-=w;n-=A;x-=w;u-=A;var z=this.canvas.getContext("2d"),h=null,l=null;var g=1;if(this.handle1&&this.handle1.isMappedOver()){var h=[-6,-3,0,3,6];g=5}else{var h=[0]}if(this.handle2&&this.handle2.isMappedOver()){var l=[-6,-3,0,3,6];g=5}else{var l=[0]}var b=this;for(var t=0;t<g;t++){var m=5,j=7;if(h.length>1||l.length>1){m=1;j=3}b.draw_outlined_curve(o,n,x,u,d,m,j,h[t%h.length],l[t%l.length])}},draw_outlined_curve:function(j,i,l,k,a,b,f,g,d){var g=g||0;var d=d||0;var h=this.canvas.getContext("2d");h.lineCap="round";h.strokeStyle=this.outer_color;h.lineWidth=f;h.beginPath();h.moveTo(j,i+g);h.bezierCurveTo(j+a,i+g,l-a,k+d,l,k+d);h.stroke();h.strokeStyle=this.inner_color;h.lineWidth=b;h.beginPath();h.moveTo(j,i+g);h.bezierCurveTo(j+a,i+g,l-a,k+d,l,k+d);h.stroke()}});var Node=Backbone.Model.extend({initialize:function(a){this.element=a.element;this.input_terminals={};this.output_terminals={};this.tool_errors={}},connectedOutputTerminals:function(){return this._connectedTerminals(this.output_terminals)},_connectedTerminals:function(b){var a=[];$.each(b,function(c,d){if(d.connectors.length>0){a.push(d)}});return a},hasConnectedOutputTerminals:function(){var a=this.output_terminals;for(var b in a){if(a[b].connectors.length>0){return true}}return false},connectedMappedInputTerminals:function(){return this._connectedMappedTerminals(this.input_terminals)},hasConnectedMappedInputTerminals:function(){var c=this.input_terminals;for(var b in c){var a=c[b];if(a.connectors.length>0&&a.isMappedOver()){return true}}return false},_connectedMappedTerminals:function(b){var a=[];$.each(b,function(c,d){var f=d.mapOver();if(f.isCollection){if(d.connectors.length>0){a.push(d)}}});return a},mappedInputTerminals:function(){return this._mappedTerminals(this.input_terminals)},_mappedTerminals:function(b){var a=[];$.each(b,function(c,d){var f=d.mapOver();if(f.isCollection){a.push(d)}});return a},hasMappedOverInputTerminals:function(){var a=false;_.each(this.input_terminals,function(b){var c=b.mapOver();if(c.isCollection){a=true}});return a},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(b){if(b.type){this.type=b.type}this.name=b.name;this.form_html=b.form_html;this.tool_state=b.tool_state;this.tool_errors=b.tool_errors;this.tooltip=b.tooltip?b.tooltip:"";this.annotation=b.annotation;this.post_job_actions=b.post_job_actions?b.post_job_actions:{};this.workflow_outputs=b.workflow_outputs?b.workflow_outputs:[];var a=this;var c=new NodeView({el:this.element[0],node:a,});a.nodeView=c;$.each(b.data_inputs,function(f,d){c.addDataInput(d)});if((b.data_inputs.length>0)&&(b.data_outputs.length>0)){c.addRule()}$.each(b.data_outputs,function(f,d){c.addDataOutput(d)});c.render();workflow.node_changed(this)},update_field_data:function(d){var c=this;nodeView=c.nodeView;this.tool_state=d.tool_state;this.form_html=d.form_html;this.tool_errors=d.tool_errors;this.annotation=d.annotation;if("post_job_actions" in d){var f=$.parseJSON(d.post_job_actions);this.post_job_actions=f?f:{}}c.nodeView.renderToolErrors();var g=nodeView.$("div.inputs");var a=nodeView.newInputsDiv();var b={};_.each(d.data_inputs,function(h){var i=c.nodeView.addDataInput(h,a);b[h.name]=i});_.each(_.difference(_.values(nodeView.terminalViews),_.values(b)),function(h){h.el.terminal.destroy()});nodeView.terminalViews=b;if(d.data_outputs.length==1&&"collection_type" in d.data_outputs[0]){nodeView.updateDataOutput(d.data_outputs[0])}g.replaceWith(a);this.markChanged();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},markChanged:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node(f.type,f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if(!$.isArray(h)){h=[h]}$.each(h,function(k,j){var m=wf.nodes[j.id];var n=new Connector();n.connect(m.output_terminals[j.output_name],d.input_terminals[i]);n.redraw()})}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node({element:i});g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+galaxy_config.root+"static/images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<div>").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}function add_node(b,d,a){var c=prebuild_node(b,d,a);workflow.add_node(c);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview();workflow.activate_node(c);return c}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}var NodeView=Backbone.View.extend({initialize:function(a){this.node=a.node;this.output_width=Math.max(150,this.$el.width());this.tool_body=this.$el.find(".toolFormBody");this.tool_body.find("div").remove();this.newInputsDiv().appendTo(this.tool_body);this.terminalViews={};this.outputTerminlViews={}},render:function(){this.renderToolErrors();this.$el.css("width",Math.min(250,Math.max(this.$el.width(),this.output_width)))},renderToolErrors:function(){if(this.node.tool_errors){this.$el.addClass("tool-node-error")}else{this.$el.removeClass("tool-node-error")}},newInputsDiv:function(){return $("<div class='inputs'></div>")},updateMaxWidth:function(a){this.output_width=Math.max(this.output_width,a)},addRule:function(){this.tool_body.append($("<div class='rule'></div>"))},addDataInput:function(i,d){var j=true;if(!d){d=this.$(".inputs");j=false}var f=this.terminalViews[i.name];var h=(i.input_type=="dataset_collection")?InputCollectionTerminalView:InputTerminalView;if(f&&!(f instanceof h)){f.el.terminal.destroy();f=null}if(!f){f=new h({node:this.node,input:i})}else{var g=f.el.terminal;g.update(i);g.destroyInvalidConnections()}this.terminalViews[i.name]=f;var c=f.el;var b=new DataInputView({terminalElement:c,input:i,nodeView:this,skipResize:j});var a=b.$el;d.append(a.prepend(f.terminalElements()));return f},addDataOutput:function(a){var d=(a.collection_type)?OutputCollectionTerminalView:OutputTerminalView;var c=new d({node:this.node,output:a});var b=new DataOutputView({output:a,terminalElement:c.el,nodeView:this,});this.tool_body.append(b.$el.append(c.terminalElements()))},updateDataOutput:function(b){var a=this.node.output_terminals[b.name];a.update(b)}});var DataInputView=Backbone.View.extend({className:"form-row dataRow input-data-row",initialize:function(a){this.input=a.input;this.nodeView=a.nodeView;this.terminalElement=a.terminalElement;this.$el.attr("name",this.input.name).html(this.input.label);if(!a.skipResize){this.$el.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(this.el);this.nodeView.updateMaxWidth(this.$el.outerWidth());this.$el.css({position:"",left:"",top:"",display:""});this.$el.remove()}},});var OutputCalloutView=Backbone.View.extend({tagName:"div",initialize:function(b){this.label=b.label;this.node=b.node;this.output=b.output;var a=this;this.$el.attr("class","callout "+this.label).css({display:"none"}).append($("<div class='buttons'></div>").append($("<img/>").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(a.output.name,a.node.workflow_outputs)!=-1){a.node.workflow_outputs.splice($.inArray(a.output.name,a.node.workflow_outputs),1);a.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{a.node.workflow_outputs.push(a.output.name);a.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});this.$el.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});this.$el.show();this.resetImage()},resetImage:function(){if($.inArray(this.output.name,this.node.workflow_outputs)===-1){this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}},hoverImage:function(){this.$("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")}});var DataOutputView=Backbone.View.extend({className:"form-row dataRow",initialize:function(c){this.output=c.output;this.terminalElement=c.terminalElement;this.nodeView=c.nodeView;var a=this.output;var b=a.name;var f=this.nodeView.node;var d=a.extensions.indexOf("input")>=0||a.extensions.indexOf("input_collection")>=0;if(!d){b=b+" ("+a.extensions.join(", ")+")"}this.$el.html(b);if(f.type=="tool"){var g=new OutputCalloutView({label:b,output:a,node:f,});this.$el.append(g.el);this.$el.hover(function(){g.hoverImage()},function(){g.resetImage()})}this.$el.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(this.el);this.nodeView.updateMaxWidth(this.$el.outerWidth()+17);this.$el.css({position:"",left:"",top:"",display:""}).detach()}});var TerminalView=Backbone.View.extend({setupMappingView:function(b){var c=new this.terminalMappingClass({terminal:b});var a=new this.terminalMappingViewClass({model:c});a.render();b.terminalMappingView=a;this.terminalMappingView=a},terminalElements:function(){if(this.terminalMappingView){return[this.terminalMappingView.el,this.el]}else{return[this.el]}}});var BaseInputTerminalView=TerminalView.extend({className:"terminal input-terminal",initialize:function(c){var f=c.node;var a=c.input;var b=a.name;var d=this.terminalForInput(a);if(!d.multiple){this.setupMappingView(d)}this.el.terminal=d;d.node=f;d.name=b;f.input_terminals[b]=d},events:{dropinit:"onDropInit",dropstart:"onDropStart",dropend:"onDropEnd",drop:"onDrop",hover:"onHover",},onDropInit:function(b,c){var a=this.el.terminal;return $(c.drag).hasClass("output-terminal")&&a.canAccept(c.drag.terminal)},onDropStart:function(a,b){if(b.proxy.terminal){b.proxy.terminal.connectors[0].inner_color="#BBFFBB"}},onDropEnd:function(a,b){if(b.proxy.terminal){b.proxy.terminal.connectors[0].inner_color="#FFFFFF"}},onDrop:function(b,c){var a=this.el.terminal;new Connector(c.drag.terminal,a).redraw()},onHover:function(){var c=this.el;var b=c.terminal;if(b.connectors.length>0){var a=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa fa-times").click(function(){$.each(b.connectors,function(f,d){if(d){d.destroy()}});a.remove()}))).bind("mouseleave",function(){$(this).remove()});a.css({top:$(c).offset().top-2,left:$(c).offset().left-a.width(),"padding-right":$(c).width()}).show()}},});var InputTerminalView=BaseInputTerminalView.extend({terminalMappingClass:InputTerminalMapping,terminalMappingViewClass:InputTerminalMappingView,terminalForInput:function(a){return new InputTerminal({element:this.el,input:a})},});var InputCollectionTerminalView=BaseInputTerminalView.extend({terminalMappingClass:InputCollectionTerminalMapping,terminalMappingViewClass:InputCollectionTerminalMappingView,terminalForInput:function(a){return new InputCollectionTerminal({element:this.el,input:a})},});var BaseOutputTerminalView=TerminalView.extend({className:"terminal output-terminal",initialize:function(c){var f=c.node;var a=c.output;var b=a.name;var d=this.terminalForOutput(a);this.setupMappingView(d);this.el.terminal=d;d.node=f;d.name=b;f.output_terminals[b]=d},events:{drag:"onDrag",dragstart:"onDragStart",dragend:"onDragEnd",},onDrag:function(b,c){var a=function(){var f=$(c.proxy).offsetParent().offset(),d=c.offsetX-f.left,g=c.offsetY-f.top;$(c.proxy).css({left:d,top:g});c.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};a();$("#canvas-container").get(0).scroll_panel.test(b,a)},onDragStart:function(b,f){$(f.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var a=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);a.terminal=new OutputTerminal({element:a});var g=new Connector();g.dragging=true;g.connect(this.el.terminal,a.terminal);return a},onDragEnd:function(b,c){var a=c.proxy.terminal.connectors[0];if(a){a.destroy()}$(c.proxy).remove();$(c.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()}});var OutputTerminalView=BaseOutputTerminalView.extend({terminalMappingClass:OutputTerminalMapping,terminalMappingViewClass:OutputTerminalMappingView,terminalForOutput:function(a){var c=a.extensions;var b=new OutputTerminal({element:this.el,datatypes:c});return b},});var OutputCollectionTerminalView=BaseOutputTerminalView.extend({terminalMappingClass:OutputCollectionTerminalMapping,terminalMappingViewClass:OutputCollectionTerminalMappingView,terminalForOutput:function(a){var c=a.collection_type;var b=new OutputCollectionTerminal({element:this.el,collection_type:c,datatypes:a.extensions});return b},});function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);$.each(workflow.nodes,function(t,q){i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;if(q.tool_errors){i.fillStyle="#FFCCCC";i.strokeStyle="#AA6666"}else{if(q.workflow_outputs!=undefined&&q.workflow_outputs.length>0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: davebgx: Remove call to send_control_task that should not have been added to admin.package_tool in the first place.
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d45b4b6ff827/
Changeset: d45b4b6ff827
User: davebgx
Date: 2014-09-02 22:05:45
Summary: Remove call to send_control_task that should not have been added to admin.package_tool in the first place.
Affected #: 1 file
diff -r e8ab30c9e3471de1b874e580663560f6a4a7f143 -r d45b4b6ff827386ff3de59bc155e95f2cf2f5656 lib/galaxy/web/base/controllers/admin.py
--- a/lib/galaxy/web/base/controllers/admin.py
+++ b/lib/galaxy/web/base/controllers/admin.py
@@ -67,7 +67,6 @@
tool_id = None
if params.get( 'package_tool_button', False ):
tool_id = params.get('tool_id', None)
- galaxy.queue_worker.send_control_task(trans, 'package_tool', noop_self=True, kwargs={'tool_id': tool_id} )
tool_tarball, success, message = trans.app.toolbox.package_tool( trans, tool_id )
if success:
trans.response.set_content_type( 'application/x-gzip' )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: ToolForm: Add sliders, radio buttons for boolean and integer fields, Ui: Update frames
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e8ab30c9e347/
Changeset: e8ab30c9e347
User: guerler
Date: 2014-09-02 22:06:35
Summary: ToolForm: Add sliders, radio buttons for boolean and integer fields, Ui: Update frames
Affected #: 10 files
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/mvc/tools/tools-section.js
--- a/static/scripts/mvc/tools/tools-section.js
+++ b/static/scripts/mvc/tools/tools-section.js
@@ -19,7 +19,7 @@
// add table class for tr tag
// this assist in transforming the form into a json structure
- options.cls_tr = 'form-row';
+ options.cls_tr = 'section-row';
// create table
this.table = new Table.View(options);
@@ -230,12 +230,21 @@
case 'hidden':
field = this._field_hidden(input_def, data);
break;
- }
-
- // check if field type was detected
- if (!field) {
- console.debug('tools-form::_addRow() : Unmatched field type (' + field_type + ').');
- return;
+
+ // integer field
+ case 'integer':
+ field = this._field_integer(input_def, data);
+ break;
+
+ // boolean field
+ case 'boolean':
+ field = this._field_radiobutton(input_def, data);
+ break;
+
+ // default
+ default:
+ field = this._field_text(input_def, data);
+ console.debug('tools-form::_addRow() : Unmatched field type (' + field_type + ').');
}
// set value
@@ -449,6 +458,18 @@
});
},
+ // integer field
+ _field_integer: function(input_def, data) {
+ var id = input_def.id;
+ return new Ui.Slider.View({
+ id : 'field-' + id,
+ value : data.get(id),
+ onchange : function(value) {
+ data.set(id, value);
+ }
+ });
+ },
+
// text area
_field_textarea : function(input_def, data) {
var id = input_def.id;
@@ -480,6 +501,25 @@
id : 'field-' + id,
value : data.get(id)
});
+ },
+
+ // hidden field
+ _field_radiobutton : function(input_def, data) {
+ var id = input_def.id;
+ return new Ui.RadioButton.View({
+ id : 'field-' + id,
+ value : data.get(id),
+ data : [
+ {
+ label : 'Yes',
+ value : 'true'
+ },
+ {
+ label : 'No',
+ value : 'false'
+ }
+ ]
+ });
}
});
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/mvc/tools/tools-tree.js
--- a/static/scripts/mvc/tools/tools-tree.js
+++ b/static/scripts/mvc/tools/tools-tree.js
@@ -39,7 +39,7 @@
var id = $(child).attr('id');
// create new branch
- if ($(child).hasClass('form-row') || $(child).hasClass('tab-pane')) {
+ if ($(child).hasClass('section-row') || $(child).hasClass('tab-pane')) {
// create sub dictionary
dict[id] = {};
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/mvc/ui/ui-frames.js
--- a/static/scripts/mvc/ui/ui-frames.js
+++ b/static/scripts/mvc/ui/ui-frames.js
@@ -2,14 +2,11 @@
define([], function() {
// frame manager
-var View = Backbone.View.extend(
-{
+var View = Backbone.View.extend({
// defaults inputs
- options:
- {
+ options: {
// default frame size
- frame:
- {
+ frame: {
cols : 6,
rows : 3
},
@@ -67,14 +64,14 @@
visible: null,
// initialize
- initialize : function(options)
- {
+ initialize : function(options) {
// add to masthead menu
var self = this;
// read in defaults
- if (options)
+ if (options) {
this.options = _.defaults(options, this.options);
+ }
// set visibility
this.visible = this.options.visible;
@@ -129,8 +126,7 @@
// catch window resize event
var self = this;
- $(window).resize(function ()
- {
+ $(window).resize(function () {
if (self.visible)
self._panel_refresh();
});
@@ -145,11 +141,9 @@
* argument that is the frame's content DOM element
* content: the content to be loaded into the frame.
*/
- add: function(options)
- {
+ add: function(options) {
// frame default options
- var frameOptions =
- {
+ var frameOptions = {
title: '',
content: null,
target: '',
@@ -157,18 +151,19 @@
}
// read in defaults
- if (options)
+ if (options) {
options = _.defaults(options, frameOptions);
- else
+ } else {
options = frameOptions;
+ }
// check for content
- if(!options.content)
+ if(!options.content) {
return;
+ }
// check for number of frames
- if (this.frame_counter >= this.options.frame_max)
- {
+ if (this.frame_counter >= this.options.frame_max) {
alert("You have reached the maximum number of allowed frames (" + this.options.frame_max + ").");
return;
}
@@ -177,8 +172,7 @@
var frame_id = '#frame-' + (this.frame_counter_id++);
// check if frame exists
- if ($(frame_id).length !== 0)
- {
+ if ($(frame_id).length !== 0) {
alert("This frame already exists. This page might contain multiple frame managers.");
return;
}
@@ -190,8 +184,7 @@
var $frame_el = null;
if (options.type === 'url') {
$frame_el = $(this._template_frame_url(frame_id.substring(1), options.title, options.content));
- }
- else if (options.type === 'other') {
+ } else if (options.type === 'other') {
$frame_el = $(this._template_frame(frame_id.substring(1), options.title));
// Load content into frame.
@@ -234,13 +227,13 @@
this._frame_insert(frame, {top: 0, left: 0}, true);
// show frames if hidden
- if (!this.visible)
+ if (!this.visible) {
this.show();
+ }
},
// show panel
- show: function()
- {
+ show: function() {
// show
this.visible = true;
@@ -261,8 +254,7 @@
},
// hide panel
- hide: function()
- {
+ hide: function() {
// make sure that no event is currently processing
if (this.event.type !== null)
return;
@@ -298,16 +290,14 @@
*/
// event
- event:
- {
+ event: {
type : null,
target : null,
xy : null
},
// events
- events:
- {
+ events: {
// global frame events
'mousemove' : '_event_frame_mouse_move',
'mouseup' : '_event_frame_mouse_up',
@@ -325,24 +315,26 @@
},
// drag start
- _event_frame_mouse_down: function (e)
- {
+ _event_frame_mouse_down: function (e) {
// skip if event is already active
- if (this.event.type !== null)
+ if (this.event.type !== null) {
return;
+ }
// check for drag event
- if ($(e.target).hasClass('f-header') ||
- $(e.target).hasClass('f-title'))
+ if ($(e.target).hasClass('f-header') || $(e.target).hasClass('f-title')) {
this.event.type = 'drag';
+ }
// check for resize event
- if ($(e.target).hasClass('f-resize'))
+ if ($(e.target).hasClass('f-resize')) {
this.event.type = 'resize';
+ }
// skip if no event has to be handled
- if (this.event.type === null)
+ if (this.event.type === null) {
return;
+ }
// prevent
e.preventDefault();
@@ -351,32 +343,36 @@
this.event.target = this._frame_identify(e.target);
// check if frame is locked
- if (this.event.target.grid_lock)
- {
+ if (this.event.target.grid_lock) {
this.event.type = null;
return;
}
// backup event details
- this.event.xy = {x: e.originalEvent.pageX, y: e.originalEvent.pageY};
+ this.event.xy = {
+ x: e.originalEvent.pageX,
+ y: e.originalEvent.pageY
+ };
// prepare drag/resize
this._frame_drag_start(this.event.target);
},
// mouse move event
- _event_frame_mouse_move: function (e)
- {
+ _event_frame_mouse_move: function (e) {
// check
- if (this.event.type != 'drag' && this.event.type != 'resize')
+ if (this.event.type != 'drag' && this.event.type != 'resize') {
return;
+ }
// current position
- var event_xy_new = {x: e.originalEvent.pageX , y: e.originalEvent.pageY};
+ var event_xy_new = {
+ x : e.originalEvent.pageX,
+ y : e.originalEvent.pageY
+ };
// position delta
- var event_xy_delta =
- {
+ var event_xy_delta = {
x : event_xy_new.x - this.event.xy.x,
y : event_xy_new.y - this.event.xy.y
};
@@ -388,8 +384,7 @@
var p = this._frame_screen (this.event.target);
// resize event
- if (this.event.type == 'resize')
- {
+ if (this.event.type == 'resize') {
// update
p.width += event_xy_delta.x;
p.height += event_xy_delta.y;
@@ -421,8 +416,7 @@
}
// drag event
- if (this.event.type == 'drag')
- {
+ if (this.event.type == 'drag') {
// update
p.left += event_xy_delta.x;
p.top += event_xy_delta.y;
@@ -437,8 +431,9 @@
};
// increase priority of current frame
- if (l.left !== 0)
+ if (l.left !== 0) {
l.left++;
+ }
// fix position
this._frame_insert(this.frame_shadow, l);
@@ -446,11 +441,11 @@
},
// mouse up
- _event_frame_mouse_up: function (e)
- {
+ _event_frame_mouse_up: function (e) {
// check
- if (this.event.type != 'drag' && this.event.type != 'resize')
+ if (this.event.type != 'drag' && this.event.type != 'resize') {
return;
+ }
// stop
this._frame_drag_stop(this.event.target);
@@ -460,11 +455,11 @@
},
// drag start
- _event_frame_close: function (e)
- {
+ _event_frame_close: function (e) {
// check
- if (this.event.type !== null)
+ if (this.event.type !== null) {
return;
+ }
// prevent
e.preventDefault();
@@ -474,8 +469,7 @@
var self = this;
// fade out
- $(frame.id).fadeOut('fast', function()
- {
+ $(frame.id).fadeOut('fast', function() {
// remove element
$(frame.id).remove();
@@ -498,11 +492,11 @@
},
// drag start
- _event_frame_lock: function (e)
- {
+ _event_frame_lock: function (e) {
// check
- if (this.event.type !== null)
+ if (this.event.type !== null) {
return;
+ }
// prevent
e.preventDefault();
@@ -511,8 +505,7 @@
var frame = this._frame_identify(e.target);
// check
- if (frame.grid_lock)
- {
+ if (frame.grid_lock) {
// unlock
frame.grid_lock = false;
@@ -536,11 +529,11 @@
},
// show/hide panel
- _event_hide: function (e)
- {
+ _event_hide: function (e) {
// check
- if (this.event.type !== null)
+ if (this.event.type !== null) {
return;
+ }
// hide panel
this.hide();
@@ -549,11 +542,11 @@
/**
* Fired when scrolling occurs on panel.
*/
- _event_panel_scroll: function(e)
- {
+ _event_panel_scroll: function(e) {
// check
- if (this.event.type !== null || !this.visible)
+ if (this.event.type !== null || !this.visible) {
return;
+ }
// Stop propagation if scrolling is happening inside a frame.
// TODO: could propagate scrolling if at top/bottom of frame.
@@ -574,8 +567,7 @@
},
// scroll up
- _event_panel_scroll_up: function(e)
- {
+ _event_panel_scroll_up: function(e) {
// check
if (this.event.type !== null)
return;
@@ -588,8 +580,7 @@
},
// scroll down
- _event_panel_scroll_down: function(e)
- {
+ _event_panel_scroll_down: function(e) {
// check
if (this.event.type !== null)
return;
@@ -606,14 +597,12 @@
*/
// identify
- _frame_identify: function(target)
- {
+ _frame_identify: function(target) {
return this.frame_list['#' + $(target).closest('.frame').attr('id')];
},
// drag start
- _frame_drag_start : function (frame)
- {
+ _frame_drag_start : function (frame) {
// set focus
this._frame_focus(frame, true);
@@ -635,8 +624,7 @@
},
// drag stop
- _frame_drag_stop : function (frame)
- {
+ _frame_drag_stop : function (frame) {
// remove focus
this._frame_focus(frame, false);
@@ -665,8 +653,7 @@
*/
// converts a pixel coordinate to grids
- _to_grid_coord: function (type, px)
- {
+ _to_grid_coord: function (type, px) {
// determine sign
var sign = (type == 'width' || type == 'height') ? 1 : -1;
@@ -677,8 +664,7 @@
},
// converts a grid coordinate to pixels
- _to_pixel_coord: function (type, g)
- {
+ _to_pixel_coord: function (type, g) {
// determine sign
var sign = (type == 'width' || type == 'height') ? 1 : -1;
@@ -691,8 +677,7 @@
},
// get grid coordinates
- _to_grid: function (px)
- {
+ _to_grid: function (px) {
// full set
return {
top : this._to_grid_coord('top', px.top),
@@ -703,8 +688,7 @@
},
// get pixel coordinates
- _to_pixel: function(g)
- {
+ _to_pixel: function(g) {
return {
top : this._to_pixel_coord('top', g.top),
left : this._to_pixel_coord('left', g.left),
@@ -718,18 +702,15 @@
*/
// check collision
- _is_collision: function(g)
- {
+ _is_collision: function(g) {
// is collision pair
- function is_collision_pair (a, b)
- {
+ function is_collision_pair (a, b) {
return !(a.left > b.left + b.width - 1 || a.left + a.width - 1 < b.left ||
a.top > b.top + b.height - 1 || a.top + a.height - 1 < b.top);
}
// search
- for (var i in this.frame_list)
- {
+ for (var i in this.frame_list) {
// get frame
var frame = this.frame_list[i];
@@ -747,8 +728,7 @@
},
// location/grid rank
- _location_rank: function(loc)
- {
+ _location_rank: function(loc) {
return (loc.top * this.cols) + loc.left;
},
@@ -757,8 +737,7 @@
*/
// update frame counter
- _menu_refresh: function()
- {
+ _menu_refresh: function() {
// scroll up possible?
if (this.visible) {
if (this.top == this.options.top_min)
@@ -784,15 +763,13 @@
*/
// panel on animation complete / frames not moving
- _panel_animation_complete: function()
- {
+ _panel_animation_complete: function() {
var self = this;
$(".frame").promise().done(function() {self._panel_scroll(0, true)});
},
// refresh panel
- _panel_refresh: function(animate)
- {
+ _panel_refresh: function(animate) {
// get current size
this.cols = parseInt($(window).width() / this.options.cell, 10) + 1;
@@ -801,8 +778,7 @@
},
// update scroll
- _panel_scroll: function(delta, animate)
- {
+ _panel_scroll: function(delta, animate) {
// new top value
var top_new = this.top - this.options.scroll * delta;
@@ -811,17 +787,14 @@
top_new = Math.min(top_new, this.options.top_min);
// update screen if necessary
- if (this.top != top_new)
- {
+ if (this.top != top_new) {
// update screen
- for (var i in this.frame_list)
- {
+ for (var i in this.frame_list) {
// get frame
var frame = this.frame_list[i];
// skip
- if (frame.grid_location !== null)
- {
+ if (frame.grid_location !== null) {
var screen_location = {
top : frame.screen_location.top - (this.top - top_new),
left : frame.screen_location.left
@@ -843,14 +816,12 @@
*/
// frame insert at given location
- _frame_insert: function(frame, new_loc, animate)
- {
+ _frame_insert: function(frame, new_loc, animate) {
// define
var place_list = [];
// frame to place
- if (frame)
- {
+ if (frame) {
// reset grid location
frame.grid_location = null;
@@ -860,14 +831,12 @@
// search
var i = null;
- for (i in this.frame_list)
- {
+ for (i in this.frame_list) {
// get frame
var f = this.frame_list[i];
// check
- if (f.grid_location !== null && !f.grid_lock)
- {
+ if (f.grid_location !== null && !f.grid_lock) {
// reset grid location
f.grid_location = null;
@@ -877,21 +846,20 @@
}
// sort place list by rank
- place_list.sort(function(a, b)
- {
+ place_list.sort(function(a, b) {
var i = a[1];
var j = b[1];
return i < j ? -1 : (i > j ? 1 : 0);
});
// place
- for (i = 0; i < place_list.length; i++)
+ for (i = 0; i < place_list.length; i++) {
this._frame_place(place_list[i][0], animate);
+ }
// identify maximum viewport size
this.top_max = 0;
- for (var i in this.frame_list)
- {
+ for (var i in this.frame_list) {
// get frame
var frame = this.frame_list[i];
@@ -911,8 +879,7 @@
},
// naive frame place
- _frame_place: function(frame, animate)
- {
+ _frame_place: function(frame, animate) {
// reset grid location
frame.grid_location = null;
@@ -921,38 +888,36 @@
// try grid coordinates
var done = false;
- for (var i = 0; i < this.options.rows; i++)
- {
+ for (var i = 0; i < this.options.rows; i++) {
// ensure that the first grid column is checked despite limited window space
- for (var j = 0; j < Math.max(1, this.cols - g.width); j++)
- {
+ for (var j = 0; j < Math.max(1, this.cols - g.width); j++) {
// coordinates
g.top = i;
g.left = j;
// no collision
- if (!this._is_collision(g))
- {
+ if (!this._is_collision(g)) {
done = true;
break;
}
}
// break
- if (done)
+ if (done) {
break;
+ }
}
// check if valid spot was found
- if (done)
+ if (done) {
this._frame_grid(frame, g, animate);
- else
+ } else {
console.log("Grid dimensions exceeded.");
+ }
},
// focus
- _frame_focus: function(frame, has_focus)
- {
+ _frame_focus: function(frame, has_focus) {
// get new z-value
var z = this.frame_z + (has_focus ? 1 : 0);
@@ -961,15 +926,13 @@
},
// new left/top position frame
- _frame_offset: function(frame, p, animate)
- {
+ _frame_offset: function(frame, p, animate) {
// update screen location
frame.screen_location.left = p.left;
frame.screen_location.top = p.top;
// animate
- if (animate)
- {
+ if (animate) {
// set focus on animated
this._frame_focus(frame, true);
@@ -988,8 +951,7 @@
},
// resize frame
- _frame_resize: function(frame, p)
- {
+ _frame_resize: function(frame, p) {
// update css
$(frame.id).css({width: p.width, height: p.height});
@@ -999,8 +961,7 @@
},
// new grid location
- _frame_grid: function (frame, l, animate)
- {
+ _frame_grid: function (frame, l, animate) {
// update grid location
frame.grid_location = l;
@@ -1012,8 +973,7 @@
},
// get frame dimensions
- _frame_screen: function(frame)
- {
+ _frame_screen: function(frame) {
var p = frame.screen_location;
return {top: p.top, left: p.left, width: p.width, height: p.height};
},
@@ -1023,14 +983,12 @@
*/
// main element
- _template: function()
- {
+ _template: function() {
return '<div class="galaxy-frame"></div>';
},
// fill regular frame template
- _template_frame: function(id, title)
- {
+ _template_frame: function(id, title) {
// check title
if (!title)
title = '';
@@ -1050,8 +1008,7 @@
},
// fill regular frame template
- _template_frame_url: function(id, title, url)
- {
+ _template_frame_url: function(id, title, url) {
// url
if (url.indexOf('?') == -1)
url += '?';
@@ -1068,20 +1025,17 @@
},
// fill shadow template
- _template_shadow: function(id)
- {
+ _template_shadow: function(id) {
return '<div id="' + id + '" class="frame-shadow corner"></div>';
},
// fill background template in order to cover underlying iframes
- _template_background: function()
- {
+ _template_background: function() {
return '<div class="frame-background"></div>';
},
// fill menu button template
- _template_menu: function()
- {
+ _template_menu: function() {
return '<div class="frame-scroll-up frame-menu fa fa-chevron-up fa-2x"></div>' +
'<div class="frame-scroll-down frame-menu fa fa-chevron-down fa-2x"></div>';
}
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/mvc/ui/ui-misc.js
--- a/static/scripts/mvc/ui/ui-misc.js
+++ b/static/scripts/mvc/ui/ui-misc.js
@@ -1,6 +1,6 @@
// dependencies
-define(['utils/utils', 'mvc/ui/ui-select-default', 'mvc/ui/ui-checkbox', 'mvc/ui/ui-radiobutton', 'mvc/ui/ui-button-menu', 'mvc/ui/ui-modal'],
- function(Utils, Select, Checkbox, RadioButton, ButtonMenu, Modal) {
+define(['utils/utils', 'mvc/ui/ui-select-default', 'mvc/ui/ui-slider', 'mvc/ui/ui-checkbox', 'mvc/ui/ui-radiobutton', 'mvc/ui/ui-button-menu', 'mvc/ui/ui-modal'],
+ function(Utils, Select, Slider, Checkbox, RadioButton, ButtonMenu, Modal) {
/**
* This class contains backbone wrappers for basic ui elements such as Images, Labels, Buttons, Input fields etc.
@@ -456,6 +456,7 @@
Searchbox : Searchbox,
Select : Select,
Textarea : Textarea,
- Hidden : Hidden
+ Hidden : Hidden,
+ Slider : Slider
}
});
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/mvc/ui/ui-slider.js
--- /dev/null
+++ b/static/scripts/mvc/ui/ui-slider.js
@@ -0,0 +1,85 @@
+// dependencies
+define(['utils/utils'], function(Utils) {
+
+// plugin
+var View = Backbone.View.extend({
+ // options
+ optionsDefault: {
+ value : '',
+ min : 1,
+ max : 100
+ },
+
+ // initialize
+ initialize : function(options) {
+ // link this
+ var self = this;
+
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this._template(this.options));
+
+ // backup slider
+ this.$slider = this.$el.find('#slider');
+
+ // backup integer field
+ this.$text = this.$el.find('#text');
+
+ // load slider plugin
+ this.$slider.slider(this.options);
+
+ // add text field event
+ this.$text.on('change', function () {
+ self.value($(this).val());
+ });
+
+ // add text field event
+ this.$text.on('keydown', function (event) {
+ var v = event.which;
+ if (!(v == 13 || v == 8 || v == 189 || (v >= 48 && v <= 57))) {
+ event.preventDefault();
+ }
+ });
+
+ // add slider event
+ this.$slider.on('slide', function (event, ui) {
+ self.value(ui.value);
+ });
+ },
+
+ // value
+ value : function (new_val) {
+ if (new_val !== undefined) {
+ // limit
+ new_val = Math.max(Math.min(new_val, this.options.max), this.options.min);
+
+ // trigger on change event
+ if (this.options.onchange) {
+ this.options.onchange(new_val);
+ }
+
+ // set values
+ this.$slider.slider('value', new_val);
+ this.$text.val(new_val);
+ }
+
+ // return current value
+ return this.$text.val();
+ },
+
+ // element
+ _template: function(options) {
+ return '<div id="' + options.id + '" style="">' +
+ '<input id="text" type="text" class="ui-input" style="width: 50px; float: left"/>' +
+ '<div id="slider" style="width: calc(100% - 60px); float: left; top: 8px; left: 10px;"/>' +
+ '</div>';
+ }
+});
+
+return {
+ View : View
+};
+
+});
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/packed/mvc/tools/tools-section.js
--- a/static/scripts/packed/mvc/tools/tools-section.js
+++ b/static/scripts/packed/mvc/tools/tools-section.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;this.datasets=g.datasets;this.data=g.data;f.cls_tr="form-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f],this.data)}},_add:function(h,j){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f,j);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f,j)}},_addConditional:function(f,j){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f,j);for(var h in f.cases){var g=f.id+"-section-"+h;var k=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(k.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(i,f,g){var k=f.id;var h=null;switch(i){case"text":h=this._field_text(f,g);break;case"select":h=this._field_select(f,g);break;case"radiobutton":h=this._field_radio(f,g);break;case"data":h=this._field_data(f,g);break;case"data_column":h=this._field_column(f,g);break;case"textarea":h=this._field_textarea(f,g);break;case"conditional":h=this._field_conditional(f,g);break;case"hidden":h=this._field_hidden(f,g);break}if(!h){console.debug("tools-form::_addRow() : Unmatched field type ("+i+").");return}if(!g.get(k)){g.set(k,f.value)}h.value(g.get(k));this.app.field_list[k]=h;var j=$("<div/>");j.append(h.$el);if(f.help){j.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(j);this.table.append(k)},_field_conditional:function(f,l){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}var m=f.id;return new e.Select.View({id:"field-"+m,data:h,value:l.get(m),onchange:function(u){l.set(m,u);for(var s in f.cases){var o=f.cases[s];var r=f.id+"-section-"+s;var n=g.table.get(r);var q=false;for(var p in o.inputs){var t=o.inputs[p].type;if(t&&t!=="hidden"){q=true;break}}if(o.value==u&&q){n.fadeIn("fast")}else{n.hide()}}}})},_field_data:function(f,l){var g=this;var m=f.id;var k=this.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+m,data:h,value:h[0].value,onchange:function(s){l.set(m,s);var o=g.app.tree.findReferences(m);var u=g.datasets.filter(s);if(u&&o.length>0){console.debug("tool-form::field_data() - Selected dataset "+s+".");var t=u.get("metadata_column_types");if(!t){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+s+".")}var r=[];for(var q in t){r.push({label:"Column: "+(parseInt(q)+1)+" ["+t[q]+"]",value:q})}for(var p in o){var n=g.app.field_list[o[p]];if(n){n.update(r);if(!n.exists(n.value())){n.value(n.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+s+".")}}})},_field_column:function(f,g){var h=f.id;return new e.Select.View({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_select:function(f,l){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;if(f.display=="checkboxes"){k=e.Checkbox}var m=f.id;return new k.View({id:"field-"+m,data:g,value:l.get(m),onchange:function(i){l.set(m,i)}})},_field_text:function(f,g){var h=f.id;return new e.Input({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_textarea:function(f,g){var h=f.id;return new e.Textarea({id:"field-"+h,onchange:function(){g.set(h,field.value())}})},_field_radio:function(f,g){var h=f.id;return new e.RadioButton({id:"field-"+h,data:f.data,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_hidden:function(f,g){var h=f.id;return new e.Hidden({id:"field-"+h,value:g.get(h)})}});return{View:d}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;this.datasets=g.datasets;this.data=g.data;f.cls_tr="section-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f],this.data)}},_add:function(h,j){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f,j);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f,j)}},_addConditional:function(f,j){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f,j);for(var h in f.cases){var g=f.id+"-section-"+h;var k=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(k.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(i,f,g){var k=f.id;var h=null;switch(i){case"text":h=this._field_text(f,g);break;case"select":h=this._field_select(f,g);break;case"radiobutton":h=this._field_radio(f,g);break;case"data":h=this._field_data(f,g);break;case"data_column":h=this._field_column(f,g);break;case"textarea":h=this._field_textarea(f,g);break;case"conditional":h=this._field_conditional(f,g);break;case"hidden":h=this._field_hidden(f,g);break;case"integer":h=this._field_integer(f,g);break;case"boolean":h=this._field_radiobutton(f,g);break;default:h=this._field_text(f,g);console.debug("tools-form::_addRow() : Unmatched field type ("+i+").")}if(!g.get(k)){g.set(k,f.value)}h.value(g.get(k));this.app.field_list[k]=h;var j=$("<div/>");j.append(h.$el);if(f.help){j.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(j);this.table.append(k)},_field_conditional:function(f,l){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}var m=f.id;return new e.Select.View({id:"field-"+m,data:h,value:l.get(m),onchange:function(u){l.set(m,u);for(var s in f.cases){var o=f.cases[s];var r=f.id+"-section-"+s;var n=g.table.get(r);var q=false;for(var p in o.inputs){var t=o.inputs[p].type;if(t&&t!=="hidden"){q=true;break}}if(o.value==u&&q){n.fadeIn("fast")}else{n.hide()}}}})},_field_data:function(f,l){var g=this;var m=f.id;var k=this.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+m,data:h,value:h[0].value,onchange:function(s){l.set(m,s);var o=g.app.tree.findReferences(m);var u=g.datasets.filter(s);if(u&&o.length>0){console.debug("tool-form::field_data() - Selected dataset "+s+".");var t=u.get("metadata_column_types");if(!t){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+s+".")}var r=[];for(var q in t){r.push({label:"Column: "+(parseInt(q)+1)+" ["+t[q]+"]",value:q})}for(var p in o){var n=g.app.field_list[o[p]];if(n){n.update(r);if(!n.exists(n.value())){n.value(n.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+s+".")}}})},_field_column:function(f,g){var h=f.id;return new e.Select.View({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_select:function(f,l){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;if(f.display=="checkboxes"){k=e.Checkbox}var m=f.id;return new k.View({id:"field-"+m,data:g,value:l.get(m),onchange:function(i){l.set(m,i)}})},_field_text:function(f,g){var h=f.id;return new e.Input({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_integer:function(f,g){var h=f.id;return new e.Slider.View({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_textarea:function(f,g){var h=f.id;return new e.Textarea({id:"field-"+h,onchange:function(){g.set(h,field.value())}})},_field_radio:function(f,g){var h=f.id;return new e.RadioButton({id:"field-"+h,data:f.data,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_hidden:function(f,g){var h=f.id;return new e.Hidden({id:"field-"+h,value:g.get(h)})},_field_radiobutton:function(f,g){var h=f.id;return new e.RadioButton.View({id:"field-"+h,value:g.get(h),data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]})}});return{View:d}});
\ No newline at end of file
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/packed/mvc/tools/tools-tree.js
--- a/static/scripts/packed/mvc/tools/tools-tree.js
+++ b/static/scripts/packed/mvc/tools/tools-tree.js
@@ -1,1 +1,1 @@
-define([],function(){return Backbone.Model.extend({initialize:function(a){this.app=a},refresh:function(){if(!this.app.section){return{}}this.dict={};this.xml=$("<div/>");this._iterate(this.app.section.$el,this.dict,this.xml)},_iterate:function(d,e,b){var a=this;var c=$(d).children();c.each(function(){var i=this;var h=$(i).attr("id");if($(i).hasClass("form-row")||$(i).hasClass("tab-pane")){e[h]={};var f=a.app.input_list[h];if(f){e[h]={input:f}}var g=$('<div id="'+h+'"/>');b.append(g);a._iterate(i,e[h],g)}else{a._iterate(i,e,b)}})},findReferences:function(c){var f=[];var b=this;function d(g,i){var h=$(i).children();var k=[];var j=false;h.each(function(){var n=this;var m=$(n).attr("id");if(m!==c){var l=b.app.input_list[m];if(l){if(l.name==g){j=true;return false}if(l.data_ref==g){k.push(m)}}}});if(!j){f=f.concat(k);h.each(function(){d(g,this)})}}var e=this.xml.find("#"+c);if(e.length>0){var a=this.app.input_list[c];if(a){d(a.name,e.parent())}}return f}})});
\ No newline at end of file
+define([],function(){return Backbone.Model.extend({initialize:function(a){this.app=a},refresh:function(){if(!this.app.section){return{}}this.dict={};this.xml=$("<div/>");this._iterate(this.app.section.$el,this.dict,this.xml)},_iterate:function(d,e,b){var a=this;var c=$(d).children();c.each(function(){var i=this;var h=$(i).attr("id");if($(i).hasClass("section-row")||$(i).hasClass("tab-pane")){e[h]={};var f=a.app.input_list[h];if(f){e[h]={input:f}}var g=$('<div id="'+h+'"/>');b.append(g);a._iterate(i,e[h],g)}else{a._iterate(i,e,b)}})},findReferences:function(c){var f=[];var b=this;function d(g,i){var h=$(i).children();var k=[];var j=false;h.each(function(){var n=this;var m=$(n).attr("id");if(m!==c){var l=b.app.input_list[m];if(l){if(l.name==g){j=true;return false}if(l.data_ref==g){k.push(m)}}}});if(!j){f=f.concat(k);h.each(function(){d(g,this)})}}var e=this.xml.find("#"+c);if(e.length>0){var a=this.app.input_list[c];if(a){d(a.name,e.parent())}}return f}})});
\ No newline at end of file
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/packed/mvc/ui/ui-misc.js
--- a/static/scripts/packed/mvc/ui/ui-misc.js
+++ b/static/scripts/packed/mvc/ui/ui-misc.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-checkbox","mvc/ui/ui-radiobutton","mvc/ui/ui-button-menu","mvc/ui/ui-modal"],function(l,b,e,m,q,n){var d=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(r){return'<img class="ui-image '+r.cls+'" src="'+r.url+'"/>'}});var k=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},title:function(r){this.$el.html(r)},_template:function(r){return'<label class="ui-label '+r.cls+'">'+r.title+"</label>"},value:function(){return options.title}});var c=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){return'<div><span class="fa '+r.icon+'" class="ui-icon"/> '+r.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"btn btn-default",icon:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick);$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){var s='<button id="'+r.id+'" type="submit" style="float: '+r.floating+';" type="button" class="ui-button '+r.cls+'">';if(r.icon){s+='<i class="icon fa '+r.icon+'"></i> '}s+=r.title+"</button>";return s}});var h=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"icon-btn",icon:"",tooltip:"",onclick:null},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick);$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){var s="";if(r.title){s="width: auto;"}var t='<div id="'+r.id+'" style="float: '+r.floating+"; "+s+'" class="ui-button-icon '+r.cls+'">';if(r.title){t+='<div class="button"><i class="icon fa '+r.icon+'"/> <span class="title">'+r.title+"</span></div>"}else{t+='<i class="icon fa '+r.icon+'"/>'}t+="</div>";return t}});var f=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick)},_template:function(r){return'<div><a href="javascript:void(0)" class="ui-anchor '+r.cls+'">'+r.title+"</a></div>"}});var o=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:false},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement("<div></div>")},update:function(s){this.options=l.merge(s,this.optionsDefault);if(s.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(s.message);this.$el.fadeIn();if(!s.persistent){var r=this;window.setTimeout(function(){if(r.$el.is(":visible")){r.$el.fadeOut()}else{r.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(r){return'<div class="ui-message alert alert-'+r.status+'"/>'}});var a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(s){this.options=l.merge(s,this.optionsDefault);this.setElement(this._template(this.options));var r=this;if(this.options.onclick){this.$el.on("submit",function(u){var t=r.$el.find("#search");r.options.onclick(t.val())})}},_template:function(r){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+r.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var j=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(s){this.options=l.merge(s,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var r=this;this.$el.on("input",function(){if(r.options.onchange){r.options.onchange(r.$el.val())}})},value:function(r){if(r!==undefined){this.$el.val(r)}return this.$el.val()},_template:function(r){return'<input id="'+r.id+'" type="'+r.type+'" value="'+r.value+'" placeholder="'+r.placeholder+'" class="ui-input '+r.cls+'">'}});var i=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(s){this.options=l.merge(s,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var r=this;this.$el.on("input",function(){if(r.options.onchange){r.options.onchange(r.$el.val())}})},value:function(r){if(r!==undefined){this.$el.val(r)}return this.$el.val()},_template:function(r){return'<textarea id="'+r.id+'" class="ui-textarea '+r.cls+'" rows="5"></textarea>'}});var p=Backbone.View.extend({optionsDefault:{value:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},value:function(r){if(r!==undefined){this.$el.val(r)}return this.$el.val()},_template:function(r){return'<hidden id="'+r.id+'" value="'+r.value+'"/>'}});return{Anchor:f,Button:g,ButtonIcon:h,ButtonMenu:q,Icon:c,Image:d,Input:j,Label:k,Message:o,Modal:n,RadioButton:m,Checkbox:e,Searchbox:a,Select:b,Textarea:i,Hidden:p}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-checkbox","mvc/ui/ui-radiobutton","mvc/ui/ui-button-menu","mvc/ui/ui-modal"],function(e,h,k,i,b,r,c){var q=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(s){return'<img class="ui-image '+s.cls+'" src="'+s.url+'"/>'}});var l=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},title:function(s){this.$el.html(s)},_template:function(s){return'<label class="ui-label '+s.cls+'">'+s.title+"</label>"},value:function(){return options.title}});var d=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){return'<div><span class="fa '+s.icon+'" class="ui-icon"/> '+s.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"btn btn-default",icon:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick);$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t='<button id="'+s.id+'" type="submit" style="float: '+s.floating+';" type="button" class="ui-button '+s.cls+'">';if(s.icon){t+='<i class="icon fa '+s.icon+'"></i> '}t+=s.title+"</button>";return t}});var o=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"icon-btn",icon:"",tooltip:"",onclick:null},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick);$(this.el).tooltip({title:s.tooltip,placement:"bottom"})},_template:function(s){var t="";if(s.title){t="width: auto;"}var u='<div id="'+s.id+'" style="float: '+s.floating+"; "+t+'" class="ui-button-icon '+s.cls+'">';if(s.title){u+='<div class="button"><i class="icon fa '+s.icon+'"/> <span class="title">'+s.title+"</span></div>"}else{u+='<i class="icon fa '+s.icon+'"/>'}u+="</div>";return u}});var p=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",s.onclick)},_template:function(s){return'<div><a href="javascript:void(0)" class="ui-anchor '+s.cls+'">'+s.title+"</a></div>"}});var a=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:false},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(t.message);this.$el.fadeIn();if(!t.persistent){var s=this;window.setTimeout(function(){if(s.$el.is(":visible")){s.$el.fadeOut()}else{s.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(s){return'<div class="ui-message alert alert-'+s.status+'"/>'}});var f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));var s=this;if(this.options.onclick){this.$el.on("submit",function(v){var u=s.$el.find("#search");s.options.onclick(u.val())})}},_template:function(s){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+s.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var n=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<input id="'+s.id+'" type="'+s.type+'" value="'+s.value+'" placeholder="'+s.placeholder+'" class="ui-input '+s.cls+'">'}});var j=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var s=this;this.$el.on("input",function(){if(s.options.onchange){s.options.onchange(s.$el.val())}})},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<textarea id="'+s.id+'" class="ui-textarea '+s.cls+'" rows="5"></textarea>'}});var m=Backbone.View.extend({optionsDefault:{value:""},initialize:function(s){this.options=e.merge(s,this.optionsDefault);this.setElement(this._template(this.options))},value:function(s){if(s!==undefined){this.$el.val(s)}return this.$el.val()},_template:function(s){return'<hidden id="'+s.id+'" value="'+s.value+'"/>'}});return{Anchor:p,Button:g,ButtonIcon:o,ButtonMenu:r,Icon:d,Image:q,Input:n,Label:l,Message:a,Modal:c,RadioButton:b,Checkbox:i,Searchbox:f,Select:h,Textarea:j,Hidden:m,Slider:k}});
\ No newline at end of file
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 static/scripts/packed/mvc/ui/ui-slider.js
--- /dev/null
+++ b/static/scripts/packed/mvc/ui/ui-slider.js
@@ -0,0 +1,1 @@
+define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{value:"",min:1,max:100},initialize:function(d){var c=this;this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.$slider=this.$el.find("#slider");this.$text=this.$el.find("#text");this.$slider.slider(this.options);this.$text.on("change",function(){c.value($(this).val())});this.$text.on("keydown",function(f){var e=f.which;if(!(e==13||e==8||e==189||(e>=48&&e<=57))){f.preventDefault()}});this.$slider.on("slide",function(e,f){c.value(f.value)})},value:function(c){if(c!==undefined){c=Math.max(Math.min(c,this.options.max),this.options.min);if(this.options.onchange){this.options.onchange(c)}this.$slider.slider("value",c);this.$text.val(c)}return this.$text.val()},_template:function(c){return'<div id="'+c.id+'" style=""><input id="text" type="text" class="ui-input" style="width: 50px; float: left"/><div id="slider" style="width: calc(100% - 60px); float: left; top: 8px; left: 10px;"/></div>'}});return{View:b}});
\ No newline at end of file
diff -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 -r e8ab30c9e3471de1b874e580663560f6a4a7f143 templates/webapps/galaxy/tool_form.api.mako
--- a/templates/webapps/galaxy/tool_form.api.mako
+++ b/templates/webapps/galaxy/tool_form.api.mako
@@ -29,7 +29,8 @@
'citations' : tool_citations
}
%>
-${h.js( "libs/bibtex" )}
+${h.js( "libs/bibtex", "libs/jquery/jquery-ui" )}
+${h.css( 'base', 'jquery-ui/smoothness/jquery-ui')}
<script>
require(['mvc/tools/tools-form'], function(ToolsForm){
$(function(){
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/36327228fe4f/
Changeset: 36327228fe4f
User: martenson
Date: 2014-09-02 21:46:24
Summary: missing import
Affected #: 1 file
diff -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d -r 36327228fe4f1f648e4fabe783d446c8dd6c1f73 lib/galaxy/managers/libraries.py
--- a/lib/galaxy/managers/libraries.py
+++ b/lib/galaxy/managers/libraries.py
@@ -6,6 +6,7 @@
from galaxy import exceptions
from galaxy.model import orm
from galaxy.managers import base as manager_base
+from galaxy.model.orm import and_, not_, or_
from sqlalchemy.orm.exc import MultipleResultsFound
from sqlalchemy.orm.exc import NoResultFound
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Test fixes for 5ce55f9; correct spaceghost.stderr to use system.stderr (thanks, John); correct api-workflow-tests (which I completely forgot *I* had made) and add test-data
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ec989f77c079/
Changeset: ec989f77c079
User: carlfeberhard
Date: 2014-09-02 21:35:56
Summary: Test fixes for 5ce55f9; correct spaceghost.stderr to use system.stderr (thanks, John); correct api-workflow-tests (which I completely forgot *I* had made) and add test-data
Affected #: 10 files
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/api-anon-history-permission-tests.js
--- a/test/casperjs/api-anon-history-permission-tests.js
+++ b/test/casperjs/api-anon-history-permission-tests.js
@@ -25,9 +25,9 @@
// create three histories: make the 2nd importable (via the API), and the third published
// make the current the inaccessible one
- inaccessibleHistory = this.api.histories.show( 'current' );
+ inaccessibleHistory = this.api.histories.index()[0];
this.api.histories.update( inaccessibleHistory.id, { name: 'inaccessible' });
- inaccessibleHistory = this.api.histories.show( 'current' );
+ inaccessibleHistory = this.api.histories.index()[0];
accessibleHistory = this.api.histories.create({ name: 'accessible' });
var returned = this.api.histories.update( accessibleHistory.id, {
@@ -83,7 +83,7 @@
this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
+ ' should work from accessible history: ' + history.name );
- this.api.hdas.create( this.api.histories.show( 'current' ).id, {
+ this.api.hdas.create( this.api.histories.index()[0].id, {
source : 'hda',
content : hdas[0].id
});
@@ -114,7 +114,7 @@
this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
+ ' from an inaccessible history should fail for: ' + history.name );
this.api.assertRaises( function(){
- var returned = this.api.hdas.create( this.api.histories.show( 'current' ).id, {
+ var returned = this.api.hdas.create( this.api.histories.index()[0].id, {
source : 'hda',
content : hdas[0].id
});
@@ -134,10 +134,6 @@
this.api.assertRaises( function(){
this.api.histories.delete_( history.id );
}, 403, 'API authentication required for this request', 'delete authentication required' );
- this.test.comment( 'set_as_current should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.set_as_current( history.id );
- }, 403, 'API authentication required for this request', 'set_as_current failed with error' );
this.test.comment( 'hda updating should fail for history: ' + history.name );
this.api.assertRaises( function(){
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/api-anon-history-tests.js
--- a/test/casperjs/api-anon-history-tests.js
+++ b/test/casperjs/api-anon-history-tests.js
@@ -23,12 +23,6 @@
this.test.assert( historyShow.id === index[0].id, 'Is the first history' );
this.test.assert( this.hasKeys( historyShow, [ 'id', 'name', 'user_id' ] ) );
- this.test.comment( 'Calling show with "current" should return the current history' );
- var current = this.api.histories.show( 'current' );
- //this.debug( this.jsonStr( current ) );
- this.test.assert( current.id === index[0].id, 'Is the first history' );
- this.test.assert( current.id === historyShow.id, 'current returned same id' );
-
// ------------------------------------------------------------------------------------------- anon forbidden
//TODO: why not return the current history?
@@ -36,35 +30,30 @@
var recent = this.api.histories.show( 'most_recently_used' );
this.test.assert( recent === null, 'most_recently_used returned None' );
- this.test.comment( 'Calling set_as_current should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.histories.set_as_current( current.id );
- }, 403, 'API authentication required for this request', 'set_as_current failed with error' );
-
this.test.comment( 'Calling create should fail for an anonymous user' );
this.api.assertRaises( function(){
- this.api.histories.create({ current: true });
+ this.api.histories.create({ name: 'new' });
}, 403, 'API authentication required for this request', 'create failed with error' );
this.test.comment( 'Calling delete should fail for an anonymous user' );
this.api.assertRaises( function(){
- this.api.histories.delete_( current.id );
+ this.api.histories.delete_( historyShow.id );
}, 403, 'API authentication required for this request', 'create failed with error' );
this.test.comment( 'Calling update should fail for an anonymous user' );
this.api.assertRaises( function(){
- this.api.histories.update( current.id, {} );
+ this.api.histories.update( historyShow.id, {} );
}, 403, 'API authentication required for this request', 'update failed with error' );
//TODO: need these two in api.js
//this.test.comment( 'Calling archive_import should fail for an anonymous user' );
//this.api.assertRaises( function(){
- // this.api.histories.archive_import( current.id, {} );
+ // this.api.histories.archive_import( historyShow.id, {} );
//}, 403, 'API authentication required for this request', 'archive_import failed with error' );
//this.test.comment( 'Calling archive_download should fail for an anonymous user' );
//this.api.assertRaises( function(){
- // this.api.histories.archive_download( current.id, {} );
+ // this.api.histories.archive_download( historyShow.id, {} );
//}, 403, 'API authentication required for this request', 'archive_download failed with error' );
// test server bad id protection
@@ -77,12 +66,6 @@
// ------------------------------------------------------------------------------------------- hdas
spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( '.history-name' );
-//TODO: can't use this - get a 400 when tools checks for history: 'logged in to manage'
-//spaceghost.then( function(){
-// this.api.tools.thenUpload( spaceghost.api.histories.show( 'current' ).id, {
-// filepath: '../../test-data/1.sam'
-// });
-//});
spaceghost.then( function(){
spaceghost.tools.uploadFile( '../../test-data/1.sam', function( uploadInfo ){
this.test.assert( uploadInfo.hdaElement !== null, "Convenience function produced hda" );
@@ -92,7 +75,7 @@
});
spaceghost.then( function(){
- var current = this.api.histories.show( 'current' );
+ var current = this.api.histories.index()[0];
// ------------------------------------------------------------------------------------------- anon allowed
this.test.comment( 'anonymous users can index hdas in their current history' );
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/api-hda-tests.js
--- a/test/casperjs/api-hda-tests.js
+++ b/test/casperjs/api-hda-tests.js
@@ -18,7 +18,7 @@
spaceghost.thenOpen( spaceghost.baseUrl, function(){
this.test.comment( '(logged in as ' + this.user.loggedInAs() + ')' );
- this.api.tools.thenUpload( spaceghost.api.histories.show( 'current' ).id, {
+ this.api.tools.thenUpload( spaceghost.api.histories.index()[0].id, {
filepath: '../../test-data/1.sam'
});
});
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/api-history-permission-tests.js
--- a/test/casperjs/api-history-permission-tests.js
+++ b/test/casperjs/api-history-permission-tests.js
@@ -35,7 +35,7 @@
this.test.comment( 'importable, slug, and published should all be returned by show and initially off' );
// make the current the inaccessible one
- inaccessibleHistory = this.api.histories.show( 'current' );
+ inaccessibleHistory = this.api.histories.show( this.api.histories.index()[0].id );
this.test.assert( this.hasKeys( inaccessibleHistory, [ 'id', 'name', 'slug', 'importable', 'published' ] ),
'Has the proper keys' );
this.test.assert( inaccessibleHistory.slug === null,
@@ -45,7 +45,7 @@
this.test.assert( inaccessibleHistory.published === false,
'initial published is false: ' + inaccessibleHistory.published );
this.api.histories.update( inaccessibleHistory.id, { name: 'inaccessible' });
- inaccessibleHistory = this.api.histories.show( 'current' );
+ inaccessibleHistory = this.api.histories.show( inaccessibleHistory.id );
this.test.comment( 'Setting importable to true should create a slug, username_and_slug, and importable === true' );
accessibleHistory = this.api.histories.create({ name: 'accessible' });
@@ -129,7 +129,7 @@
this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
+ ' should work from accessible history: ' + history.name );
- returned = this.api.hdas.create( this.api.histories.show( 'current' ).id, {
+ returned = this.api.hdas.create( this.api.histories.index()[0].id, {
source : 'hda',
content : hdas[0].id
});
@@ -161,7 +161,7 @@
this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
+ ' from an inaccessible history should fail for: ' + history.name );
this.api.assertRaises( function(){
- var returned = this.api.hdas.create( this.api.histories.show( 'current' ).id, {
+ var returned = this.api.hdas.create( this.api.histories.index()[0].id, {
source : 'hda',
content : hdas[0].id
});
@@ -181,10 +181,6 @@
this.api.assertRaises( function(){
this.api.histories.delete_( history.id );
}, 403, 'History is not owned by the current user', 'delete failed with error' );
- this.test.comment( 'set_as_current should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.set_as_current( history.id );
- }, 403, 'History is not owned by the current user', 'set_as_current failed with error' );
this.test.comment( 'hda updating should fail for history: ' + history.name );
this.api.assertRaises( function(){
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/api-history-tests.js
--- a/test/casperjs/api-history-tests.js
+++ b/test/casperjs/api-history-tests.js
@@ -67,19 +67,13 @@
this.test.assert( this.api.histories.show( this.api.histories.index()[0].id ).id === firstHistory.id,
'combining function calls works' );
- this.test.comment( 'Calling show with "current" should return the current history' );
- this.test.assert( this.api.histories.show( 'current' ).id === historyShow.id, 'current returned same id' );
-
-
// ------------------------------------------------------------------------------------------- CREATE
- this.test.comment( 'Calling create should create a new history and allow setting the name and making it current' );
+ this.test.comment( 'Calling create should create a new history and allow setting the name' );
var newHistoryName = 'Created History',
- createdHistory = this.api.histories.create({ name: newHistoryName, current: true });
+ createdHistory = this.api.histories.create({ name: newHistoryName });
//this.debug( 'returned from create:\n' + this.jsonStr( createdHistory ) );
this.test.assert( createdHistory.name === newHistoryName,
"Name of created history (from create) is correct: " + createdHistory.name );
- this.test.assert( this.api.histories.show( 'current' ).id === createdHistory.id,
- "was made current" );
// check the index
var newFirstHistory = this.api.histories.index()[0];
@@ -123,20 +117,9 @@
this.test.assert( newFirstHistory.id === createdHistory.id,
"Id of last history (from index) DOES appear after undeletion: " + newFirstHistory.id );
-
//TODO: show, deleted flag
//TODO: delete, purge flag
-
- // ------------------------------------------------------------------------------------------- set_as_current
- this.test.comment( 'calling set_as_current on a non-current history will make it current' );
- this.test.assert( this.api.histories.show( 'current' ).id !== historyShow.id, historyShow.id + ' is not current' );
- var returned = this.api.histories.set_as_current( historyShow.id );
- this.debug( this.jsonStr( returned ) );
- this.test.assert( this.api.histories.show( 'current' ).id === historyShow.id, 'made current' );
- this.api.histories.set_as_current( newFirstHistory.id );
-
-
// ------------------------------------------------------------------------------------------- UPDATE
// ........................................................................................... name
this.test.comment( 'update should allow changing the name' );
@@ -300,10 +283,6 @@
this.api.assertRaises( function(){
this.api.histories.update( '1234123412341234', {} );
}, 400, 'unable to decode', 'Bad Request with invalid id: update' );
- spaceghost.test.comment( 'A bad id should throw an error when using set_as_current' );
- this.api.assertRaises( function(){
- this.api.histories.set_as_current( '1234123412341234' );
- }, 400, 'unable to decode', 'Bad Request with invalid id: set_as_current' );
spaceghost.test.comment( 'A bad id should throw an error when using delete' );
this.api.assertRaises( function(){
this.api.histories.delete_( '1234123412341234' );
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/api-workflow-tests.js
--- a/test/casperjs/api-workflow-tests.js
+++ b/test/casperjs/api-workflow-tests.js
@@ -17,7 +17,7 @@
spaceghost.user.loginOrRegisterUser( email, password );
// =================================================================== TESTS
-var workflowJSONFilepath = 'test-data/Bed_interval_lengths.ga',
+var workflowJSONFilepath = 'test-data/simple_test.ga',
workflowModelClass = 'StoredWorkflow',
workflowSummaryKeys = [
'id', 'model_class', 'name', 'published', 'tags', 'url'
@@ -28,7 +28,7 @@
stepKeys = [
'id', 'input_steps', 'tool_id', 'type'
],
- simpleBedFilepath = 'test-data/simple.bed',
+ simpleBedFilepath = '../../test-data/2.bed',
uploadedFile = null,
workflowCreateKeys = [ 'history', 'outputs' ];
@@ -105,13 +105,9 @@
this.test.comment( 'inputs from show should be an object (and, in this case, empty)' );
var inputs = workflowShow.inputs;
- //this.debug( 'inputs:\n' + this.jsonStr( inputs ) );
+ this.debug( 'inputs:\n' + this.jsonStr( inputs ) );
this.test.assert( utils.isObject( workflowShow.inputs ), "inputs is an object" );
- //for( var inputKey in inputs ){
- // if( inputs.hasOwnProperty( inputKey ) ){
- // }
- //}
- this.test.assert( this.countKeys( workflowShow.inputs ) === 0, "inputs is empty" );
+ this.test.assert( this.countKeys( workflowShow.inputs ) !== 0, "inputs has keys" );
this.test.comment( 'steps from show should be an object containing each tool defined as a step' );
var steps = workflowShow.steps;
@@ -141,17 +137,14 @@
this.test.assert( this.hasKeys( step.input_steps, [ 'input' ] ), "input_steps has the proper keys" );
}
- this.test.assert( step.type === 'tool',
- "step type is a tool: " + step.type );
-
- // check for tools in this wf with the api
- this.test.assert( utils.isString( step.tool_id ),
- "step tool_id is a string: " + step.tool_id );
- var tool_used = this.api.tools.show( step.tool_id );
- //this.debug( this.jsonStr( tool_used ) )
- this.test.assert( this.countKeys( step.input_steps ) !== 0, "found tool in api.tools for: " + step.tool_id );
-
- // trace the path through input_steps, source_steps
+ if( step.type === 'tool' ){
+ // check for tools in this wf with the api
+ this.test.assert( utils.isString( step.tool_id ),
+ "step tool_id is a string: " + step.tool_id );
+ var tool_used = this.api.tools.show( step.tool_id.replace( / /g, '+' ) );
+ this.debug( this.jsonStr( tool_used ) );
+ this.test.assert( this.countKeys( tool_used ) !== 0, "found tool in api.tools for: " + step.tool_id );
+ }
}
}
@@ -181,7 +174,7 @@
var step = firstWorkflow.steps[ stepKey ];
if( this.countKeys( step.input_steps ) === 0 ){
input_step = stepKey;
- this.debug( 'input step: ' + this.jsonStr( step ) )
+ this.debug( 'input step: ' + this.jsonStr( step ) );
break;
}
}
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/casperjs_runner.py
--- a/test/casperjs/casperjs_runner.py
+++ b/test/casperjs/casperjs_runner.py
@@ -382,7 +382,7 @@
"""
self.run_js_script( 'history-panel-tests.js' )
- def test_10_anonymous_histories( self ):
+ def test_10_history_options( self ):
"""Test history options button.
"""
self.run_js_script( 'history-options-tests.js' )
@@ -425,7 +425,7 @@
"""
self.run_js_script( 'api-anon-history-tests.js' )
- def test_04_anon_history_api( self ):
+ def test_04_anon_history_permissions_api( self ):
"""Test API permissions for importable, published histories using anonymous user.
"""
self.run_js_script( 'api-anon-history-permission-tests.js' )
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/modules/api.js
--- a/test/casperjs/modules/api.js
+++ b/test/casperjs/modules/api.js
@@ -215,7 +215,6 @@
delete_ : 'api/histories/%s',
undelete: 'api/histories/deleted/%s/undelete',
update : 'api/histories/%s',
- set_as_current : 'api/histories/%s/set_as_current'
};
HistoriesAPI.prototype.index = function index( deleted ){
@@ -282,15 +281,6 @@
});
};
-HistoriesAPI.prototype.set_as_current = function set_as_current( id ){
- this.api.spaceghost.info( 'histories.set_as_current: ' + id );
- id = this.api.ensureId( id );
-
- return this.api._ajax( utils.format( this.urlTpls.set_as_current, id ), {
- type : 'PUT'
- });
-};
-
// =================================================================== HDAS
var HDAAPI = function HDAAPI( api ){
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/spaceghost.js
--- a/test/casperjs/spaceghost.js
+++ b/test/casperjs/spaceghost.js
@@ -34,6 +34,7 @@
// ------------------------------------------------------------------- modules
var require = patchRequire( require ),
Casper = require( 'casper' ).Casper,
+ system = require( 'system' ),
fs = require( 'fs' ),
utils = require( 'utils' );
@@ -1022,7 +1023,7 @@
*/
SpaceGhost.prototype.stderr = function( msg ){
if( msg.trim() ){
- fs.write( '/dev/stderr', msg + '\n', 'w' );
+ system.stderr.writeLine( msg );
}
};
diff -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 -r ec989f77c079f7036c7cb8bb303d1e6bae4a4e4d test/casperjs/test-data/simple_test.ga
--- /dev/null
+++ b/test/casperjs/test-data/simple_test.ga
@@ -0,0 +1,96 @@
+{
+ "a_galaxy_workflow": "true",
+ "annotation": "",
+ "format-version": "0.1",
+ "name": "simple_test",
+ "steps": {
+ "0": {
+ "annotation": "",
+ "id": 0,
+ "input_connections": {},
+ "inputs": [
+ {
+ "description": "",
+ "name": "Input Dataset"
+ }
+ ],
+ "name": "Input dataset",
+ "outputs": [],
+ "position": {
+ "left": 200,
+ "top": 231
+ },
+ "tool_errors": null,
+ "tool_id": null,
+ "tool_state": "{\"name\": \"Input Dataset\"}",
+ "tool_version": null,
+ "type": "data_input",
+ "user_outputs": []
+ },
+ "1": {
+ "annotation": "",
+ "id": 1,
+ "input_connections": {
+ "input": {
+ "id": 0,
+ "output_name": "output"
+ }
+ },
+ "inputs": [],
+ "name": "Select first",
+ "outputs": [
+ {
+ "name": "out_file1",
+ "type": "input"
+ }
+ ],
+ "position": {
+ "left": 409,
+ "top": 365
+ },
+ "post_job_actions": {
+ "HideDatasetActionout_file1": {
+ "action_arguments": {},
+ "action_type": "HideDatasetAction",
+ "output_name": "out_file1"
+ }
+ },
+ "tool_errors": null,
+ "tool_id": "Show beginning1",
+ "tool_state": "{\"__page__\": 0, \"input\": \"null\", \"__rerun_remap_job_id__\": null, \"lineNum\": \"\\\"10\\\"\"}",
+ "tool_version": "1.0.0",
+ "type": "tool",
+ "user_outputs": []
+ },
+ "2": {
+ "annotation": "",
+ "id": 2,
+ "input_connections": {
+ "input": {
+ "id": 1,
+ "output_name": "out_file1"
+ }
+ },
+ "inputs": [],
+ "name": "Select random lines",
+ "outputs": [
+ {
+ "name": "out_file1",
+ "type": "input"
+ }
+ ],
+ "position": {
+ "left": 609.5,
+ "top": 234
+ },
+ "post_job_actions": {},
+ "tool_errors": null,
+ "tool_id": "random_lines1",
+ "tool_state": "{\"input\": \"null\", \"seed_source\": \"{\\\"__current_case__\\\": 0, \\\"seed_source_selector\\\": \\\"no_seed\\\"}\", \"__rerun_remap_job_id__\": null, \"num_lines\": \"\\\"5\\\"\", \"__page__\": 0}",
+ "tool_version": "2.0.1",
+ "type": "tool",
+ "user_outputs": []
+ }
+ },
+ "uuid": "675b4aa8-c885-46d3-b63a-3c52b3bec8c4"
+}
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Make it possible to load dynamic job runner rules from somewhere other than galaxy.jobs.rules.
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9f63d9632d9d/
Changeset: 9f63d9632d9d
User: natefoo
Date: 2014-09-02 21:30:57
Summary: Make it possible to load dynamic job runner rules from somewhere other than galaxy.jobs.rules.
Affected #: 3 files
diff -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 job_conf.xml.sample_advanced
--- a/job_conf.xml.sample_advanced
+++ b/job_conf.xml.sample_advanced
@@ -22,6 +22,17 @@
<plugin id="cli" type="runner" load="galaxy.jobs.runners.cli:ShellJobRunner" /><plugin id="condor" type="runner" load="galaxy.jobs.runners.condor:CondorJobRunner" /><plugin id="slurm" type="runner" load="galaxy.jobs.runners.slurm:SlurmJobRunner" />
+ <plugin id="dynamic" type="runner">
+ <!-- The dynamic runner is not a real job running plugin and is
+ always loaded, so it does not need to be explicitly stated in
+ <plugins>. However, if you wish to change the base module
+ containing your dynamic rules, you can do so.
+
+ The `load` attribute is not required (and ignored if
+ included).
+ -->
+ <param id="rules_module">galaxy.jobs.rules</param>
+ </plugin><!-- Pulsar runners (see more at https://pulsar.readthedocs.org) --><plugin id="pulsar_rest" type="runner" load="galaxy.jobs.runners.pulsar:PulsarRESTJobRunner"><!-- Allow optimized HTTP calls with libcurl (defaults to urllib) -->
diff -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -103,6 +103,7 @@
"""
self.app = app
self.runner_plugins = []
+ self.dynamic_params = None
self.handlers = {}
self.handler_runner_plugins = {}
self.default_handler_id = None
@@ -147,6 +148,10 @@
self.runner_plugins.append(runner_info)
else:
log.error('Unknown plugin type: %s' % plugin.get('type'))
+ for plugin in self.__findall_with_required(plugins, 'plugin', ('id', 'type')):
+ if plugin.get('id') == 'dynamic' and plugin.get('type') == 'runner':
+ self.dynamic_params = self.__get_params(plugin)
+
# Load tasks if configured
if self.app.config.use_tasked_jobs:
self.runner_plugins.append(dict(id='tasks', load='tasks', workers=self.app.config.local_task_queue_workers))
diff -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 -r 9f63d9632d9d690c2d5e353feac3f83f12db3f78 lib/galaxy/jobs/mapper.py
--- a/lib/galaxy/jobs/mapper.py
+++ b/lib/galaxy/jobs/mapper.py
@@ -1,6 +1,7 @@
import logging
import inspect
import os
+import sys
log = logging.getLogger( __name__ )
@@ -49,6 +50,11 @@
self.rules_module = galaxy.jobs.rules
+ if job_config.dynamic_params is not None:
+ rules_module_name = job_config.dynamic_params['rules_module']
+ __import__(rules_module_name)
+ self.rules_module = sys.modules[rules_module_name]
+
def __get_rule_modules( self ):
unsorted_module_names = self.__get_rule_module_names( )
## Load modules in reverse order to allow hierarchical overrides
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: History API: remove set_as_current, api/histories/current, and POST api/histories with current == True (create new current history), replace with controllers/history/set_as_current, current_history_json, and create_new_current (respectively) - all returning json; add exceptions.DeprecatedMethod; pack scripts
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5ce55f9f2923/
Changeset: 5ce55f9f2923
User: carlfeberhard
Date: 2014-09-02 19:26:47
Summary: History API: remove set_as_current, api/histories/current, and POST api/histories with current == True (create new current history), replace with controllers/history/set_as_current, current_history_json, and create_new_current (respectively) - all returning json; add exceptions.DeprecatedMethod; pack scripts
Affected #: 16 files
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 lib/galaxy/exceptions/__init__.py
--- a/lib/galaxy/exceptions/__init__.py
+++ b/lib/galaxy/exceptions/__init__.py
@@ -127,6 +127,14 @@
status_code = 404
err_code = error_codes.USER_OBJECT_NOT_FOUND
+class DeprecatedMethod( MessageException ):
+ """
+ Method (or a particular form/arg signature) has been removed and won't be available later
+ """
+ status_code = 404
+ #TODO:?? 410 Gone?
+ err_code = error_codes.DEPRECATED_API_CALL
+
class Conflict( MessageException ):
status_code = 409
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 lib/galaxy/exceptions/error_codes.json
--- a/lib/galaxy/exceptions/error_codes.json
+++ b/lib/galaxy/exceptions/error_codes.json
@@ -67,7 +67,7 @@
{
"name": "USER_NO_API_KEY",
"code": 403001,
- "message": "API authentication required for this request"
+ "message": "Authentication required for this request"
},
{
"name": "USER_CANNOT_ACCESS_ITEM",
@@ -100,6 +100,11 @@
"message": "No such object found."
},
{
+ "name": "DEPRECATED_API_CALL",
+ "code": 404002,
+ "message": "This API method or call signature has been deprecated and is no longer available"
+ },
+ {
"name": "CONFLICT",
"code": 409001,
"message": "Database conflict prevented fulfilling the request."
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -63,7 +63,10 @@
'hgw8.cse.ucsc.edu',
)
+JSON_CONTENT_TYPE = "application/json"
+
+# ----------------------------------------------------------------------------- web controller decorators
def expose( func ):
"""
Decorator: mark a function as 'exposed' and thus web accessible
@@ -71,28 +74,25 @@
func.exposed = True
return func
-
-def json( func ):
+def json( func, **json_kwargs ):
+ """
+ Format the response as JSON and set the response content type to
+ JSON_CONTENT_TYPE.
+ """
@wraps(func)
- def decorator( self, trans, *args, **kwargs ):
- trans.response.set_content_type( "text/javascript" )
- return to_json_string( func( self, trans, *args, **kwargs ) )
+ def call_and_format( self, trans, *args, **kwargs ):
+ trans.response.set_content_type( JSON_CONTENT_TYPE )
+ return to_json_string( func( self, trans, *args, **kwargs ), **json_kwargs )
if not hasattr(func, '_orig'):
- decorator._orig = func
- decorator.exposed = True
- return decorator
-
+ call_and_format._orig = func
+ call_and_format.exposed = True
+ return call_and_format
def json_pretty( func ):
- @wraps(func)
- def decorator( self, trans, *args, **kwargs ):
- trans.response.set_content_type( "text/javascript" )
- return to_json_string( func( self, trans, *args, **kwargs ), indent=4, sort_keys=True )
- if not hasattr(func, '_orig'):
- decorator._orig = func
- decorator.exposed = True
- return decorator
-
+ """
+ Indent and sort returned JSON.
+ """
+ return json( func, indent=4, sort_keys=True )
def require_login( verb="perform this action", use_panels=False, webapp='galaxy' ):
def argcatcher( func ):
@@ -107,59 +107,26 @@
return decorator
return argcatcher
+def require_admin( func ):
+ @wraps(func)
+ def decorator( self, trans, *args, **kwargs ):
+ if not trans.user_is_admin():
+ msg = "You must be an administrator to access this feature."
+ user = trans.get_user()
+ if not trans.app.config.admin_users_list:
+ msg = "You must be logged in as an administrator to access this feature, but no administrators are set in the Galaxy configuration."
+ elif not user:
+ msg = "You must be logged in as an administrator to access this feature."
+ trans.response.status = 403
+ if trans.response.get_content_type() == 'application/json':
+ return msg
+ else:
+ return trans.show_error_message( msg )
+ return func( self, trans, *args, **kwargs )
+ return decorator
-def __extract_payload_from_request(trans, func, kwargs):
- content_type = trans.request.headers['content-type']
- if content_type.startswith('application/x-www-form-urlencoded') or content_type.startswith('multipart/form-data'):
- # If the content type is a standard type such as multipart/form-data, the wsgi framework parses the request body
- # and loads all field values into kwargs. However, kwargs also contains formal method parameters etc. which
- # are not a part of the request body. This is a problem because it's not possible to differentiate between values
- # which are a part of the request body, and therefore should be a part of the payload, and values which should not be
- # in the payload. Therefore, the decorated method's formal arguments are discovered through reflection and removed from
- # the payload dictionary. This helps to prevent duplicate argument conflicts in downstream methods.
- payload = kwargs.copy()
- named_args, _, _, _ = inspect.getargspec(func)
- for arg in named_args:
- payload.pop(arg, None)
- for k, v in payload.iteritems():
- if isinstance(v, (str, unicode)):
- try:
- payload[k] = from_json_string(v)
- except:
- # may not actually be json, just continue
- pass
- payload = util.recursively_stringify_dictionary_keys( payload )
- else:
- # Assume application/json content type and parse request body manually, since wsgi won't do it. However, the order of this check
- # should ideally be in reverse, with the if clause being a check for application/json and the else clause assuming a standard encoding
- # such as multipart/form-data. Leaving it as is for backward compatibility, just in case.
- payload = util.recursively_stringify_dictionary_keys( from_json_string( trans.request.body ) )
- return payload
-
-def expose_api_raw( func ):
- """
- Expose this function via the API but don't dump the results
- to JSON.
- """
- return expose_api( func, to_json=False )
-
-
-def expose_api_raw_anonymous( func ):
- """
- Expose this function via the API but don't dump the results
- to JSON.
- """
- return expose_api( func, to_json=False, user_required=False )
-
-
-def expose_api_anonymous( func, to_json=True ):
- """
- Expose this function via the API but don't require a set user.
- """
- return expose_api( func, to_json=to_json, user_required=False )
-
-
+# ----------------------------------------------------------------------------- (original) api decorators
def expose_api( func, to_json=True, user_required=True ):
"""
Expose this function via the API.
@@ -219,76 +186,56 @@
decorator.exposed = True
return decorator
-API_RESPONSE_CONTENT_TYPE = "application/json"
+def __extract_payload_from_request(trans, func, kwargs):
+ content_type = trans.request.headers['content-type']
+ if content_type.startswith('application/x-www-form-urlencoded') or content_type.startswith('multipart/form-data'):
+ # If the content type is a standard type such as multipart/form-data, the wsgi framework parses the request body
+ # and loads all field values into kwargs. However, kwargs also contains formal method parameters etc. which
+ # are not a part of the request body. This is a problem because it's not possible to differentiate between values
+ # which are a part of the request body, and therefore should be a part of the payload, and values which should not be
+ # in the payload. Therefore, the decorated method's formal arguments are discovered through reflection and removed from
+ # the payload dictionary. This helps to prevent duplicate argument conflicts in downstream methods.
+ payload = kwargs.copy()
+ named_args, _, _, _ = inspect.getargspec(func)
+ for arg in named_args:
+ payload.pop(arg, None)
+ for k, v in payload.iteritems():
+ if isinstance(v, (str, unicode)):
+ try:
+ payload[k] = from_json_string(v)
+ except:
+ # may not actually be json, just continue
+ pass
+ payload = util.recursively_stringify_dictionary_keys( payload )
+ else:
+ # Assume application/json content type and parse request body manually, since wsgi won't do it. However, the order of this check
+ # should ideally be in reverse, with the if clause being a check for application/json and the else clause assuming a standard encoding
+ # such as multipart/form-data. Leaving it as is for backward compatibility, just in case.
+ payload = util.recursively_stringify_dictionary_keys( from_json_string( trans.request.body ) )
+ return payload
+def expose_api_raw( func ):
+ """
+ Expose this function via the API but don't dump the results
+ to JSON.
+ """
+ return expose_api( func, to_json=False )
-def __api_error_message( trans, **kwds ):
- exception = kwds.get( "exception", None )
- if exception:
- # If we are passed a MessageException use err_msg.
- default_error_code = getattr( exception, "err_code", error_codes.UNKNOWN )
- default_error_message = getattr( exception, "err_msg", default_error_code.default_error_message )
- extra_error_info = getattr( exception, 'extra_error_info', {} )
- if not isinstance( extra_error_info, dict ):
- extra_error_info = {}
- else:
- default_error_message = "Error processing API request."
- default_error_code = error_codes.UNKNOWN
- extra_error_info = {}
- traceback_string = kwds.get( "traceback", "No traceback available." )
- err_msg = kwds.get( "err_msg", default_error_message )
- error_code_object = kwds.get( "err_code", default_error_code )
- try:
- error_code = error_code_object.code
- except AttributeError:
- # Some sort of bad error code sent in, logic failure on part of
- # Galaxy developer.
- error_code = error_codes.UNKNOWN.code
- # Would prefer the terminology of error_code and error_message, but
- # err_msg used a good number of places already. Might as well not change
- # it?
- error_response = dict( err_msg=err_msg, err_code=error_code, **extra_error_info )
- if trans.debug: # TODO: Should admins get to see traceback as well?
- error_response[ "traceback" ] = traceback_string
- return error_response
+def expose_api_raw_anonymous( func ):
+ """
+ Expose this function via the API but don't dump the results
+ to JSON.
+ """
+ return expose_api( func, to_json=False, user_required=False )
-
-def __api_error_response( trans, **kwds ):
- error_dict = __api_error_message( trans, **kwds )
- exception = kwds.get( "exception", None )
- # If we are given an status code directly - use it - otherwise check
- # the exception for a status_code attribute.
- if "status_code" in kwds:
- status_code = int( kwds.get( "status_code" ) )
- elif hasattr( exception, "status_code" ):
- status_code = int( exception.status_code )
- else:
- status_code = 500
- response = trans.response
- if not response.status or str(response.status).startswith("20"):
- # Unset status code appears to be string '200 OK', if anything
- # non-success (i.e. not 200 or 201) has been set, do not override
- # underlying controller.
- response.status = status_code
- return to_json_string( error_dict )
-
-
-# TODO: rename as expose_api and make default.
-def _future_expose_api_anonymous( func, to_json=True ):
+def expose_api_anonymous( func, to_json=True ):
"""
Expose this function via the API but don't require a set user.
"""
- return _future_expose_api( func, to_json=to_json, user_required=False )
+ return expose_api( func, to_json=to_json, user_required=False )
-def _future_expose_api_raw( func ):
- return _future_expose_api( func, to_json=False, user_required=True )
-
-
-def _future_expose_api_raw_anonymous( func ):
- return _future_expose_api( func, to_json=False, user_required=False )
-
-
+# ----------------------------------------------------------------------------- (new) api decorators
# TODO: rename as expose_api and make default.
def _future_expose_api( func, to_json=True, user_required=True ):
"""
@@ -312,7 +259,7 @@
error_code = error_codes.USER_INVALID_JSON
return __api_error_response( trans, status_code=400, err_code=error_code )
- trans.response.set_content_type( API_RESPONSE_CONTENT_TYPE )
+ trans.response.set_content_type( JSON_CONTENT_TYPE )
# send 'do not cache' headers to handle IE's caching of ajax get responses
trans.response.headers[ 'Cache-Control' ] = "max-age=0,no-cache,no-store"
# TODO: Refactor next block out into a helper procedure.
@@ -364,24 +311,72 @@
decorator.exposed = True
return decorator
+def __api_error_message( trans, **kwds ):
+ exception = kwds.get( "exception", None )
+ if exception:
+ # If we are passed a MessageException use err_msg.
+ default_error_code = getattr( exception, "err_code", error_codes.UNKNOWN )
+ default_error_message = getattr( exception, "err_msg", default_error_code.default_error_message )
+ extra_error_info = getattr( exception, 'extra_error_info', {} )
+ if not isinstance( extra_error_info, dict ):
+ extra_error_info = {}
+ else:
+ default_error_message = "Error processing API request."
+ default_error_code = error_codes.UNKNOWN
+ extra_error_info = {}
+ traceback_string = kwds.get( "traceback", "No traceback available." )
+ err_msg = kwds.get( "err_msg", default_error_message )
+ error_code_object = kwds.get( "err_code", default_error_code )
+ try:
+ error_code = error_code_object.code
+ except AttributeError:
+ # Some sort of bad error code sent in, logic failure on part of
+ # Galaxy developer.
+ error_code = error_codes.UNKNOWN.code
+ # Would prefer the terminology of error_code and error_message, but
+ # err_msg used a good number of places already. Might as well not change
+ # it?
+ error_response = dict( err_msg=err_msg, err_code=error_code, **extra_error_info )
+ if trans.debug: # TODO: Should admins get to see traceback as well?
+ error_response[ "traceback" ] = traceback_string
+ return error_response
-def require_admin( func ):
- @wraps(func)
- def decorator( self, trans, *args, **kwargs ):
- if not trans.user_is_admin():
- msg = "You must be an administrator to access this feature."
- user = trans.get_user()
- if not trans.app.config.admin_users_list:
- msg = "You must be logged in as an administrator to access this feature, but no administrators are set in the Galaxy configuration."
- elif not user:
- msg = "You must be logged in as an administrator to access this feature."
- trans.response.status = 403
- if trans.response.get_content_type() == 'application/json':
- return msg
- else:
- return trans.show_error_message( msg )
- return func( self, trans, *args, **kwargs )
- return decorator
+def __api_error_response( trans, **kwds ):
+ error_dict = __api_error_message( trans, **kwds )
+ exception = kwds.get( "exception", None )
+ # If we are given an status code directly - use it - otherwise check
+ # the exception for a status_code attribute.
+ if "status_code" in kwds:
+ status_code = int( kwds.get( "status_code" ) )
+ elif hasattr( exception, "status_code" ):
+ status_code = int( exception.status_code )
+ else:
+ status_code = 500
+ response = trans.response
+ if not response.status or str(response.status).startswith("20"):
+ # Unset status code appears to be string '200 OK', if anything
+ # non-success (i.e. not 200 or 201) has been set, do not override
+ # underlying controller.
+ response.status = status_code
+ return to_json_string( error_dict )
+
+
+# TODO: rename as expose_api and make default.
+def _future_expose_api_anonymous( func, to_json=True ):
+ """
+ Expose this function via the API but don't require a set user.
+ """
+ return _future_expose_api( func, to_json=to_json, user_required=False )
+
+
+def _future_expose_api_raw( func ):
+ return _future_expose_api( func, to_json=False, user_required=True )
+
+
+def _future_expose_api_raw_anonymous( func ):
+ return _future_expose_api( func, to_json=False, user_required=False )
+
+
NOT_SET = object()
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 lib/galaxy/webapps/galaxy/api/histories.py
--- a/lib/galaxy/webapps/galaxy/api/histories.py
+++ b/lib/galaxy/webapps/galaxy/api/histories.py
@@ -84,13 +84,9 @@
return the deleted history with ``id``
* GET /api/histories/most_recently_used:
return the most recently used history
- * GET /api/histories/current:
- return the current (working) history
- .. note:: Anonymous users are allowed to get their current history
:type id: an encoded id string
- :param id: the encoded id of the history to query
- or the string 'most_recently_used' or the string 'current'
+ :param id: the encoded id of the history to query or the string 'most_recently_used'
:type deleted: boolean
:param deleted: if True, allow information on a deleted history to be shown.
@@ -107,9 +103,6 @@
# Most recent active history for user sessions, not deleted
history = trans.user.galaxy_sessions[0].histories[-1].history
- elif history_id == "current":
- history = trans.get_history( create=True )
-
else:
history = self.mgrs.histories.get( trans, self._decode_id( trans, history_id ),
check_ownership=False, check_accessible=True, deleted=deleted )
@@ -133,30 +126,6 @@
return map( lambda citation: citation.to_dict( "bibtex" ), self.citations_manager.citations_for_tool_ids( tool_ids ) )
@expose_api
- def set_as_current( self, trans, id, **kwd ):
- """
- set_as_current( trans, id, **kwd )
- * PUT /api/histories/{id}/set_as_current:
- set the history with ``id`` to the user's current history and return details
-
- :type id: an encoded id string
- :param id: the encoded id of the history to query or the string 'most_recently_used'
-
- :rtype: dictionary
- :returns: detailed history information from
- :func:`galaxy.web.base.controller.UsesHistoryDatasetAssociationMixin.get_history_dict`
- """
- # added as a non-ATOM API call to support the notion of a 'current/working' history
- # - unique to the history resource
- history_id = id
- history = self.mgrs.histories.get( trans, self._decode_id( trans, history_id ),
- check_ownership=True, check_accessible=True )
- trans.history = history
- history_data = self.get_history_dict( trans, history )
- history_data[ 'contents_url' ] = url_for( 'history_contents', history_id=history_id )
- return history_data
-
- @expose_api
def create( self, trans, payload, **kwd ):
"""
create( trans, payload )
@@ -166,8 +135,6 @@
:type payload: dict
:param payload: (optional) dictionary structure containing:
* name: the new history's name
- * current: if passed, set the new history to be the user's
- 'current' history
* history_id: the id of the history to copy
* archive_source: the url that will generate the archive to import
* archive_type: 'url' (default)
@@ -178,8 +145,6 @@
hist_name = None
if payload.get( 'name', None ):
hist_name = restore_text( payload['name'] )
- #TODO: possibly default to True here - but favor explicit for now (and backwards compat)
- set_as_current = string_as_bool( payload[ 'current' ] ) if 'current' in payload else False
copy_this_history_id = payload.get( 'history_id', None )
if "archive_source" in payload:
@@ -202,8 +167,6 @@
trans.sa_session.add( new_history )
trans.sa_session.flush()
- if set_as_current:
- trans.history = new_history
item = {}
item = self.get_history_dict( trans, new_history )
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -197,10 +197,6 @@
controller='page_revisions',
parent_resources=dict( member_name='page', collection_name='pages' ) )
- # add as a non-ATOM API call to support the notion of a 'current/working' history unique to the history resource
- webapp.mapper.connect( "set_as_current", "/api/histories/{id}/set_as_current",
- controller="histories", action="set_as_current", conditions=dict( method=["PUT"] ) )
-
webapp.mapper.connect( "history_archive_export", "/api/histories/{id}/exports",
controller="histories", action="archive_export", conditions=dict( method=[ "PUT" ] ) )
webapp.mapper.connect( "history_archive_download", "/api/histories/{id}/exports/{jeha_id}",
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -1375,13 +1375,50 @@
msg = 'Copied and created %d new histories.' % len( histories )
return trans.show_ok_message( msg )
+
+ # ------------------------------------------------------------------------- current history
@web.expose
@web.require_login( "switch to a history" )
def switch_to_history( self, trans, hist_id=None ):
- history = self.get_history( trans, hist_id )
- trans.set_history( history )
+ """
+ """
+ self.set_as_current( trans, id=hist_id )
return trans.response.send_redirect( url_for( "/" ) )
def get_item( self, trans, id ):
return self.get_history( trans, id )
#TODO: override of base ui controller?
+
+ def history_data( self, trans, history ):
+ """
+ """
+ #TODO: to manager
+ history_data = self.get_history_dict( trans, history )
+ encoded_history_id = trans.security.encode_id( history.id )
+ history_data[ 'contents_url' ] = url_for( 'history_contents', history_id=encoded_history_id )
+ return history_data
+
+ #TODO: combine these next two - poss. with a redirect flag
+ @web.require_login( "switch to a history" )
+ @web.json
+ def set_as_current( self, trans, id=None ):
+ """
+ """
+ history = self.get_history( trans, id )
+ trans.set_history( history )
+ return self.history_data( trans, history )
+
+ @web.json
+ def current_history_json( self, trans ):
+ """
+ """
+ history = trans.get_history( create=True )
+ return self.history_data( trans, history )
+
+ @web.json
+ def create_new_current( self, trans, name=None ):
+ """
+ """
+ return self.history_data( trans, trans.new_history( name ) )
+
+ #TODO: /history/current to do all of the above: if ajax, return json; if post, read id and set to current
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/mvc/history/history-model.js
--- a/static/scripts/mvc/history/history-model.js
+++ b/static/scripts/mvc/history/history-model.js
@@ -234,13 +234,16 @@
options = options || {};
var hdaDetailIds = options.hdaDetailIds || [];
var hdcaDetailIds = options.hdcaDetailIds || [];
- //this.debug( 'getHistoryData:', historyId, options );
+ //console.debug( 'getHistoryData:', historyId, options );
var df = jQuery.Deferred(),
historyJSON = null;
function getHistory( id ){
// get the history data
+ if( historyId === 'current' ){
+ return jQuery.getJSON( galaxy_config.root + 'history/current_history_json' );
+ }
return jQuery.ajax( galaxy_config.root + 'api/histories/' + historyId );
}
function isEmpty( historyData ){
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/mvc/history/history-panel-edit-current.js
--- a/static/scripts/mvc/history/history-panel-edit-current.js
+++ b/static/scripts/mvc/history/history-panel-edit-current.js
@@ -1,9 +1,10 @@
define([
+ "mvc/history/history-model",
"mvc/history/history-panel-edit",
"mvc/collection/collection-panel",
"mvc/base-mvc",
"utils/localization"
-], function( HPANEL_EDIT, DC_PANEL, BASE_MVC, _l ){
+], function( HISTORY_MODEL, HPANEL_EDIT, DC_PANEL, BASE_MVC, _l ){
// ============================================================================
/** session storage for history panel preferences (and to maintain state)
*/
@@ -74,6 +75,7 @@
// ------------------------------------------------------------------------ loading history/hda models
/** (re-)loads the user's current history & hdas w/ details */
loadCurrentHistory : function( attributes ){
+ this.debug( this + '.loadCurrentHistory' );
// implemented as a 'fresh start' or for when there is no model (intial panel render)
var panel = this;
return this.loadHistoryWithHDADetails( 'current', attributes )
@@ -88,10 +90,9 @@
var panel = this,
historyFn = function(){
// make this current and get history data with one call
- return jQuery.ajax({
- url : galaxy_config.root + 'api/histories/' + historyId + '/set_as_current',
- method : 'PUT'
- });
+ return jQuery.getJSON( galaxy_config.root + 'history/set_as_current?id=' + historyId );
+ // method : 'PUT'
+ //});
};
return this.loadHistoryWithHDADetails( historyId, attributes, historyFn )
.then(function( historyData, hdaData ){
@@ -107,9 +108,10 @@
}
var panel = this,
historyFn = function(){
- // get history data from posting a new history (and setting it to current)
- return jQuery.post( galaxy_config.root + 'api/histories', { current: true });
+ // create a new history and save: the server will return the proper JSON
+ return jQuery.getJSON( galaxy_config.root + 'history/create_new_current' );
};
+
// id undefined bc there is no historyId yet - the server will provide
// (no need for details - nothing expanded in new history)
return this.loadHistory( undefined, attributes, historyFn )
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/mvc/history/history-panel.js
--- a/static/scripts/mvc/history/history-panel.js
+++ b/static/scripts/mvc/history/history-panel.js
@@ -273,10 +273,11 @@
//NOTE: all the following fns replace the existing history model with a new model
// (in the following 'details' refers to the full set of hda api data (urls, display_apps, misc_info, etc.)
// - hdas w/o details will have summary data only (name, hid, deleted, visible, state, etc.))
+//TODO: too tangled...
/** loads a history & hdas w/ details (but does not make them the current history) */
loadHistoryWithHDADetails : function( historyId, attributes, historyFn, hdaFn ){
- //this.info( 'loadHistoryWithHDADetails:', historyId, attributes, historyFn, hdaFn );
+ this.info( 'loadHistoryWithHDADetails:', historyId, attributes, historyFn, hdaFn );
var hdaDetailIds = function( historyData ){
// will be called to get hda ids that need details from the api
//TODO: non-visible HDAs are getting details loaded... either stop loading them at all or filter ids thru isVisible
@@ -287,6 +288,7 @@
/** loads a history & hdas w/ NO details (but does not make them the current history) */
loadHistory : function( historyId, attributes, historyFn, hdaFn, hdaDetailIds ){
+ this.info( 'loadHistory:', historyId, attributes, historyFn, hdaFn, hdaDetailIds );
var panel = this;
attributes = attributes || {};
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/mvc/library/library-dataset-view.js
--- a/static/scripts/mvc/library/library-dataset-view.js
+++ b/static/scripts/mvc/library/library-dataset-view.js
@@ -185,11 +185,12 @@
// set the used history as current so user will see the last one
// that he imported into in the history panel on the 'analysis' page
- var set_current_url = '/api/histories/' + history_id + '/set_as_current';
- $.ajax({
- url: set_current_url,
- type: 'PUT'
- });
+ //var set_current_url = '/api/histories/' + history_id + '/set_as_current';
+ //$.ajax({
+ // url: set_current_url,
+ // type: 'PUT'
+ //});
+ jQuery.getJSON( galaxy_config.root + 'history/set_as_current?id=' + history_id );
// save the dataset into selected history
historyItem.save({ content : this.id, source : 'library' }, {
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/mvc/library/library-foldertoolbar-view.js
@@ -80,7 +80,7 @@
},
// shows modal for creating folder
- createFolderFromModal: function(){
+ createFolderFromModal: function( event ){
event.preventDefault();
event.stopPropagation();
@@ -226,11 +226,13 @@
// set the used history as current so user will see the last one
// that he imported into in the history panel on the 'analysis' page
- var set_current_url = '/api/histories/' + history_id + '/set_as_current';
- $.ajax({
- url: set_current_url,
- type: 'PUT'
- });
+ //var set_current_url = '/api/histories/' + history_id + '/set_as_current';
+ //$.ajax({
+ // url: set_current_url,
+ // type: 'PUT'
+ //});
+ jQuery.getJSON( galaxy_config.root + 'history/set_as_current?id=' + historyId );
+
// call the recursive function to call ajax one after each other (request FIFO queue)
this.chainCall(datasets_to_import, history_name);
},
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/packed/mvc/history/history-model.js
--- a/static/scripts/packed/mvc/history/history-model.js
+++ b/static/scripts/packed/mvc/history/history-model.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-contents","mvc/base-mvc","utils/localization"],function(h,i,d){var e=Backbone.Model.extend(i.LoggableMixin).extend({defaults:{model_class:"History",id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:galaxy_config.root+"api/histories",initialize:function(k,l,j){j=j||{};this.logger=j.logger||null;this.log(this+".initialize:",k,l,j);this.log("creating history contents:",l);this.contents=new h.HistoryContents(l||[],{historyId:this.get("id")});this._setUpListeners();this.updateTimeoutId=null},_setUpListeners:function(){this.on("error",function(k,n,j,m,l){this.errorHandler(k,n,j,m,l)});if(this.contents){this.listenTo(this.contents,"error",function(){this.trigger.apply(this,["error:contents"].concat(jQuery.makeArray(arguments)))})}this.on("change:id",function(k,j){if(this.contents){this.contents.historyId=j}},this)},errorHandler:function(k,n,j,m,l){this.clearUpdateTimeout()},ownedByCurrUser:function(){if(!Galaxy||!Galaxy.currUser){return false}if(Galaxy.currUser.isAnonymous()||Galaxy.currUser.id!==this.get("user_id")){return false}return true},contentsCount:function(){return _.reduce(_.values(this.get("state_details")),function(j,k){return j+k},0)},checkForUpdates:function(j){if(this.contents.running().length){this.setUpdateTimeout()}else{this.trigger("ready");if(_.isFunction(j)){j.call(this)}}return this},setUpdateTimeout:function(j){j=j||e.UPDATE_DELAY;var k=this;this.clearUpdateTimeout();this.updateTimeoutId=setTimeout(function(){k.refresh()},j);return this.updateTimeoutId},clearUpdateTimeout:function(){if(this.updateTimeoutId){clearTimeout(this.updateTimeoutId);this.updateTimeoutId=null}},refresh:function(k,j){k=k||[];j=j||{};var l=this;j.data=j.data||{};if(k.length){j.data.details=k.join(",")}var m=this.contents.fetch(j);m.done(function(n){l.checkForUpdates(function(){this.fetch()})});return m},copy:function(m,k){m=(m!==undefined)?(m):(true);if(!this.id){throw new Error("You must set the history ID before copying it.")}var j={history_id:this.id};if(m){j.current=true}if(k){j.name=k}var l=this,n=jQuery.post(this.urlRoot,j);n.done(function(o){l.trigger("copied",l,o)});return n},toString:function(){return"History("+this.get("id")+","+this.get("name")+")"}});e.UPDATE_DELAY=4000;e.getHistoryData=function c(j,v){v=v||{};var p=v.hdaDetailIds||[];var l=v.hdcaDetailIds||[];var r=jQuery.Deferred(),q=null;function k(w){return jQuery.ajax(galaxy_config.root+"api/histories/"+j)}function o(w){return w&&w.empty}function u(x){if(o(x)){return[]}if(_.isFunction(p)){p=p(x)}if(_.isFunction(l)){l=l(x)}var w={};if(p.length){w.dataset_details=p.join(",")}if(l.length){w.dataset_collection_details=l.join(",")}return jQuery.ajax(galaxy_config.root+"api/histories/"+x.id+"/contents",{data:w})}var t=v.historyFn||k,s=v.hdaFn||u;var n=t(j);n.done(function(w){q=w;r.notify({status:"history data retrieved",historyJSON:q})});n.fail(function(y,w,x){r.reject(y,"loading the history")});var m=n.then(s);m.then(function(w){r.notify({status:"dataset data retrieved",historyJSON:q,hdaJSON:w});r.resolve(q,w)});m.fail(function(y,w,x){r.reject(y,"loading the datasets",{history:q})});return r};var f=Backbone.Collection.extend(i.LoggableMixin).extend({model:e,urlRoot:(window.galaxy_config?galaxy_config.root:"/")+"api/histories",initialize:function(k,j){j=j||{};this.log("HistoryCollection.initialize",arguments);this.includeDeleted=j.includeDeleted||false;this.setUpListeners()},setUpListeners:function a(){var j=this;this.on("change:deleted",function(k){this.debug("change:deleted",j.includeDeleted,k.get("deleted"));if(!j.includeDeleted&&k.get("deleted")){j.remove(k)}});this.on("copied",function(k,l){this.unshift(new e(l,[]))})},create:function g(m,k,j,l){var o=this,n=new e(m||{},k||[],j||{});return n.save(l).done(function(p){o.unshift(n)})},toString:function b(){return"HistoryCollection("+this.length+")"}});return{History:e,HistoryCollection:f}});
\ No newline at end of file
+define(["mvc/history/history-contents","mvc/base-mvc","utils/localization"],function(h,i,d){var e=Backbone.Model.extend(i.LoggableMixin).extend({defaults:{model_class:"History",id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:galaxy_config.root+"api/histories",initialize:function(k,l,j){j=j||{};this.logger=j.logger||null;this.log(this+".initialize:",k,l,j);this.log("creating history contents:",l);this.contents=new h.HistoryContents(l||[],{historyId:this.get("id")});this._setUpListeners();this.updateTimeoutId=null},_setUpListeners:function(){this.on("error",function(k,n,j,m,l){this.errorHandler(k,n,j,m,l)});if(this.contents){this.listenTo(this.contents,"error",function(){this.trigger.apply(this,["error:contents"].concat(jQuery.makeArray(arguments)))})}this.on("change:id",function(k,j){if(this.contents){this.contents.historyId=j}},this)},errorHandler:function(k,n,j,m,l){this.clearUpdateTimeout()},ownedByCurrUser:function(){if(!Galaxy||!Galaxy.currUser){return false}if(Galaxy.currUser.isAnonymous()||Galaxy.currUser.id!==this.get("user_id")){return false}return true},contentsCount:function(){return _.reduce(_.values(this.get("state_details")),function(j,k){return j+k},0)},checkForUpdates:function(j){if(this.contents.running().length){this.setUpdateTimeout()}else{this.trigger("ready");if(_.isFunction(j)){j.call(this)}}return this},setUpdateTimeout:function(j){j=j||e.UPDATE_DELAY;var k=this;this.clearUpdateTimeout();this.updateTimeoutId=setTimeout(function(){k.refresh()},j);return this.updateTimeoutId},clearUpdateTimeout:function(){if(this.updateTimeoutId){clearTimeout(this.updateTimeoutId);this.updateTimeoutId=null}},refresh:function(k,j){k=k||[];j=j||{};var l=this;j.data=j.data||{};if(k.length){j.data.details=k.join(",")}var m=this.contents.fetch(j);m.done(function(n){l.checkForUpdates(function(){this.fetch()})});return m},copy:function(m,k){m=(m!==undefined)?(m):(true);if(!this.id){throw new Error("You must set the history ID before copying it.")}var j={history_id:this.id};if(m){j.current=true}if(k){j.name=k}var l=this,n=jQuery.post(this.urlRoot,j);n.done(function(o){l.trigger("copied",l,o)});return n},toString:function(){return"History("+this.get("id")+","+this.get("name")+")"}});e.UPDATE_DELAY=4000;e.getHistoryData=function c(j,v){v=v||{};var p=v.hdaDetailIds||[];var l=v.hdcaDetailIds||[];var r=jQuery.Deferred(),q=null;function k(w){if(j==="current"){return jQuery.getJSON(galaxy_config.root+"history/current_history_json")}return jQuery.ajax(galaxy_config.root+"api/histories/"+j)}function o(w){return w&&w.empty}function u(x){if(o(x)){return[]}if(_.isFunction(p)){p=p(x)}if(_.isFunction(l)){l=l(x)}var w={};if(p.length){w.dataset_details=p.join(",")}if(l.length){w.dataset_collection_details=l.join(",")}return jQuery.ajax(galaxy_config.root+"api/histories/"+x.id+"/contents",{data:w})}var t=v.historyFn||k,s=v.hdaFn||u;var n=t(j);n.done(function(w){q=w;r.notify({status:"history data retrieved",historyJSON:q})});n.fail(function(y,w,x){r.reject(y,"loading the history")});var m=n.then(s);m.then(function(w){r.notify({status:"dataset data retrieved",historyJSON:q,hdaJSON:w});r.resolve(q,w)});m.fail(function(y,w,x){r.reject(y,"loading the datasets",{history:q})});return r};var f=Backbone.Collection.extend(i.LoggableMixin).extend({model:e,urlRoot:(window.galaxy_config?galaxy_config.root:"/")+"api/histories",initialize:function(k,j){j=j||{};this.log("HistoryCollection.initialize",arguments);this.includeDeleted=j.includeDeleted||false;this.setUpListeners()},setUpListeners:function a(){var j=this;this.on("change:deleted",function(k){this.debug("change:deleted",j.includeDeleted,k.get("deleted"));if(!j.includeDeleted&&k.get("deleted")){j.remove(k)}});this.on("copied",function(k,l){this.unshift(new e(l,[]))})},create:function g(m,k,j,l){var o=this,n=new e(m||{},k||[],j||{});return n.save(l).done(function(p){o.unshift(n)})},toString:function b(){return"HistoryCollection("+this.length+")"}});return{History:e,HistoryCollection:f}});
\ No newline at end of file
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/packed/mvc/history/history-panel-edit-current.js
--- a/static/scripts/packed/mvc/history/history-panel-edit-current.js
+++ b/static/scripts/packed/mvc/history/history-panel-edit-current.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-panel-edit","mvc/collection/collection-panel","mvc/base-mvc","utils/localization"],function(g,f,b,d){var c=b.SessionStorageModel.extend({defaults:{searching:false,tagsEditorShown:false,annotationEditorShown:false},toString:function(){return"HistoryPanelPrefs("+JSON.stringify(this.toJSON())+")"}});c.storageKey=function h(){return("history-panel")};var e=g.HistoryPanel;var a=e.extend({emptyMsg:d("This history is empty. Click 'Get Data' on the left tool menu to start"),noneFoundMsg:d("No matching datasets found"),initialize:function(i){i=i||{};this.preferences=new c(_.extend({id:c.storageKey()},_.pick(i,_.keys(c.prototype.defaults))));e.prototype.initialize.call(this,i);this.panelStack=[]},loadCurrentHistory:function(j){var i=this;return this.loadHistoryWithHDADetails("current",j).then(function(l,k){i.trigger("current-history",i)})},switchToHistory:function(l,k){var i=this,j=function(){return jQuery.ajax({url:galaxy_config.root+"api/histories/"+l+"/set_as_current",method:"PUT"})};return this.loadHistoryWithHDADetails(l,k,j).then(function(n,m){i.trigger("switched-history",i)})},createNewHistory:function(k){if(!Galaxy||!Galaxy.currUser||Galaxy.currUser.isAnonymous()){this.displayMessage("error",d("You must be logged in to create histories"));return $.when()}var i=this,j=function(){return jQuery.post(galaxy_config.root+"api/histories",{current:true})};return this.loadHistory(undefined,k,j).then(function(m,l){i.trigger("new-history",i)})},setModel:function(j,i,k){e.prototype.setModel.call(this,j,i,k);if(this.model){this.log("checking for updates");this.model.checkForUpdates()}return this},_setUpModelEventHandlers:function(){e.prototype._setUpModelEventHandlers.call(this);if(Galaxy&&Galaxy.quotaMeter){this.listenTo(this.model,"change:nice_size",function(){Galaxy.quotaMeter.update()})}this.model.contents.on("state:ready",function(j,k,i){if((!j.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(this.hdaViews[j.id])}},this)},render:function(k,l){this.log("render:",k,l);k=(k===undefined)?(this.fxSpeed):(k);var i=this,j;if(this.model){j=this.renderModel()}else{j=this.renderWithoutModel()}$(i).queue("fx",[function(m){if(k&&i.$el.is(":visible")){i.$el.fadeOut(k,m)}else{m()}},function(m){i.$el.empty();if(j){i.$el.append(j.children());i.renderBasedOnPrefs()}m()},function(m){if(k&&!i.$el.is(":visible")){i.$el.fadeIn(k,m)}else{m()}},function(m){if(l){l.call(this)}i.trigger("rendered",this);m()}]);return this},renderBasedOnPrefs:function(){if(this.preferences.get("searching")){this.toggleSearchControls(0,true)}},_renderEmptyMsg:function(k){var j=this,i=j.$emptyMessage(k),l=$(".toolMenuContainer");if((_.isEmpty(j.hdaViews)&&!j.searchFor)&&(Galaxy&&Galaxy.upload&&l.size())){i.empty();i.html([d("This history is empty"),". ",d("You can "),'<a class="uploader-link" href="javascript:void(0)">',d("load your own data"),"</a>",d(" or "),'<a class="get-data-link" href="javascript:void(0)">',d("get data from an external source"),"</a>"].join(""));i.find(".uploader-link").click(function(m){Galaxy.upload._eventShow(m)});i.find(".get-data-link").click(function(m){l.parent().scrollTop(0);l.find('span:contains("Get Data")').click()});i.show()}else{e.prototype._renderEmptyMsg.call(this,k)}return this},toggleSearchControls:function(j,i){var k=e.prototype.toggleSearchControls.call(this,j,i);this.preferences.set("searching",k)},_renderTags:function(i){var j=this;e.prototype._renderTags.call(this,i);if(this.preferences.get("tagsEditorShown")){this.tagsEditor.toggle(true)}this.tagsEditor.on("hiddenUntilActivated:shown hiddenUntilActivated:hidden",function(k){j.preferences.set("tagsEditorShown",k.hidden)})},_renderAnnotation:function(i){var j=this;e.prototype._renderAnnotation.call(this,i);if(this.preferences.get("annotationEditorShown")){this.annotationEditor.toggle(true)}this.annotationEditor.on("hiddenUntilActivated:shown hiddenUntilActivated:hidden",function(k){j.preferences.set("annotationEditorShown",k.hidden)})},_setUpHdaListeners:function(j){e.prototype._setUpHdaListeners.call(this,j);var i=this;if(j instanceof i.HDCAViewClass){j.off("expanded");j.on("expanded",function(k){this.info("expanded",k);i._addCollectionPanel(k)});j.off("collapsed")}},_addCollectionPanel:function(k){var l=this,i=k.model;this.debug("history panel (stack), collectionModel:",i);var j=new (this._getCollectionPanelClass(i))({model:i,HDAViewClass:this.HDAViewClass,parentName:this.model.get("name"),linkTarget:this.linkTarget});l.panelStack.push(j);l.$(".history-controls").add(".datasets-list").hide();l.$el.append(j.$el);j.on("close",function(){l.render();k.collapse();l.panelStack.pop()});if(!j.model.hasDetails()){var m=j.model.fetch();m.done(function(){j.render()})}else{j.render()}},_getCollectionPanelClass:function(i){switch(i.get("collection_type")){case"list":return f.ListCollectionPanel;case"paired":return f.PairCollectionPanel;case"list:paired":return f.ListOfPairsCollectionPanel}throw new TypeError("Uknown collection_type: "+i.get("collection_type"))},addContentView:function(i){if(this.panelStack.length){return this}return e.prototype.addContentView.call(this,i)},connectToQuotaMeter:function(i){if(!i){return this}this.listenTo(i,"quota:over",this.showQuotaMessage);this.listenTo(i,"quota:under",this.hideQuotaMessage);this.on("rendered rendered:initial",function(){if(i&&i.isOverQuota()){this.showQuotaMessage()}});return this},showQuotaMessage:function(){var i=this.$el.find(".quota-message");if(i.is(":hidden")){i.slideDown(this.fxSpeed)}},hideQuotaMessage:function(){var i=this.$el.find(".quota-message");if(!i.is(":hidden")){i.slideUp(this.fxSpeed)}},connectToOptionsMenu:function(i){if(!i){return this}this.on("new-storage",function(k,j){if(i&&k){i.findItemByHtml(d("Include Deleted Datasets")).checked=k.get("show_deleted");i.findItemByHtml(d("Include Hidden Datasets")).checked=k.get("show_hidden")}});return this},toString:function(){return"CurrentHistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});return{CurrentHistoryPanel:a}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/collection/collection-panel","mvc/base-mvc","utils/localization"],function(d,c,a,h,b){var e=h.SessionStorageModel.extend({defaults:{searching:false,tagsEditorShown:false,annotationEditorShown:false},toString:function(){return"HistoryPanelPrefs("+JSON.stringify(this.toJSON())+")"}});e.storageKey=function f(){return("history-panel")};var g=c.HistoryPanel;var i=g.extend({emptyMsg:b("This history is empty. Click 'Get Data' on the left tool menu to start"),noneFoundMsg:b("No matching datasets found"),initialize:function(j){j=j||{};this.preferences=new e(_.extend({id:e.storageKey()},_.pick(j,_.keys(e.prototype.defaults))));g.prototype.initialize.call(this,j);this.panelStack=[]},loadCurrentHistory:function(k){this.debug(this+".loadCurrentHistory");var j=this;return this.loadHistoryWithHDADetails("current",k).then(function(m,l){j.trigger("current-history",j)})},switchToHistory:function(m,l){var j=this,k=function(){return jQuery.getJSON(galaxy_config.root+"history/set_as_current?id="+m)};return this.loadHistoryWithHDADetails(m,l,k).then(function(o,n){j.trigger("switched-history",j)})},createNewHistory:function(l){if(!Galaxy||!Galaxy.currUser||Galaxy.currUser.isAnonymous()){this.displayMessage("error",b("You must be logged in to create histories"));return $.when()}var j=this,k=function(){return jQuery.getJSON(galaxy_config.root+"history/create_new_current")};return this.loadHistory(undefined,l,k).then(function(n,m){j.trigger("new-history",j)})},setModel:function(k,j,l){g.prototype.setModel.call(this,k,j,l);if(this.model){this.log("checking for updates");this.model.checkForUpdates()}return this},_setUpModelEventHandlers:function(){g.prototype._setUpModelEventHandlers.call(this);if(Galaxy&&Galaxy.quotaMeter){this.listenTo(this.model,"change:nice_size",function(){Galaxy.quotaMeter.update()})}this.model.contents.on("state:ready",function(k,l,j){if((!k.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(this.hdaViews[k.id])}},this)},render:function(l,m){this.log("render:",l,m);l=(l===undefined)?(this.fxSpeed):(l);var j=this,k;if(this.model){k=this.renderModel()}else{k=this.renderWithoutModel()}$(j).queue("fx",[function(n){if(l&&j.$el.is(":visible")){j.$el.fadeOut(l,n)}else{n()}},function(n){j.$el.empty();if(k){j.$el.append(k.children());j.renderBasedOnPrefs()}n()},function(n){if(l&&!j.$el.is(":visible")){j.$el.fadeIn(l,n)}else{n()}},function(n){if(m){m.call(this)}j.trigger("rendered",this);n()}]);return this},renderBasedOnPrefs:function(){if(this.preferences.get("searching")){this.toggleSearchControls(0,true)}},_renderEmptyMsg:function(l){var k=this,j=k.$emptyMessage(l),m=$(".toolMenuContainer");if((_.isEmpty(k.hdaViews)&&!k.searchFor)&&(Galaxy&&Galaxy.upload&&m.size())){j.empty();j.html([b("This history is empty"),". ",b("You can "),'<a class="uploader-link" href="javascript:void(0)">',b("load your own data"),"</a>",b(" or "),'<a class="get-data-link" href="javascript:void(0)">',b("get data from an external source"),"</a>"].join(""));j.find(".uploader-link").click(function(n){Galaxy.upload._eventShow(n)});j.find(".get-data-link").click(function(n){m.parent().scrollTop(0);m.find('span:contains("Get Data")').click()});j.show()}else{g.prototype._renderEmptyMsg.call(this,l)}return this},toggleSearchControls:function(k,j){var l=g.prototype.toggleSearchControls.call(this,k,j);this.preferences.set("searching",l)},_renderTags:function(j){var k=this;g.prototype._renderTags.call(this,j);if(this.preferences.get("tagsEditorShown")){this.tagsEditor.toggle(true)}this.tagsEditor.on("hiddenUntilActivated:shown hiddenUntilActivated:hidden",function(l){k.preferences.set("tagsEditorShown",l.hidden)})},_renderAnnotation:function(j){var k=this;g.prototype._renderAnnotation.call(this,j);if(this.preferences.get("annotationEditorShown")){this.annotationEditor.toggle(true)}this.annotationEditor.on("hiddenUntilActivated:shown hiddenUntilActivated:hidden",function(l){k.preferences.set("annotationEditorShown",l.hidden)})},_setUpHdaListeners:function(k){g.prototype._setUpHdaListeners.call(this,k);var j=this;if(k instanceof j.HDCAViewClass){k.off("expanded");k.on("expanded",function(l){this.info("expanded",l);j._addCollectionPanel(l)});k.off("collapsed")}},_addCollectionPanel:function(l){var m=this,j=l.model;this.debug("history panel (stack), collectionModel:",j);var k=new (this._getCollectionPanelClass(j))({model:j,HDAViewClass:this.HDAViewClass,parentName:this.model.get("name"),linkTarget:this.linkTarget});m.panelStack.push(k);m.$(".history-controls").add(".datasets-list").hide();m.$el.append(k.$el);k.on("close",function(){m.render();l.collapse();m.panelStack.pop()});if(!k.model.hasDetails()){var n=k.model.fetch();n.done(function(){k.render()})}else{k.render()}},_getCollectionPanelClass:function(j){switch(j.get("collection_type")){case"list":return a.ListCollectionPanel;case"paired":return a.PairCollectionPanel;case"list:paired":return a.ListOfPairsCollectionPanel}throw new TypeError("Uknown collection_type: "+j.get("collection_type"))},addContentView:function(j){if(this.panelStack.length){return this}return g.prototype.addContentView.call(this,j)},connectToQuotaMeter:function(j){if(!j){return this}this.listenTo(j,"quota:over",this.showQuotaMessage);this.listenTo(j,"quota:under",this.hideQuotaMessage);this.on("rendered rendered:initial",function(){if(j&&j.isOverQuota()){this.showQuotaMessage()}});return this},showQuotaMessage:function(){var j=this.$el.find(".quota-message");if(j.is(":hidden")){j.slideDown(this.fxSpeed)}},hideQuotaMessage:function(){var j=this.$el.find(".quota-message");if(!j.is(":hidden")){j.slideUp(this.fxSpeed)}},connectToOptionsMenu:function(j){if(!j){return this}this.on("new-storage",function(l,k){if(j&&l){j.findItemByHtml(b("Include Deleted Datasets")).checked=l.get("show_deleted");j.findItemByHtml(b("Include Hidden Datasets")).checked=l.get("show_hidden")}});return this},toString:function(){return"CurrentHistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});return{CurrentHistoryPanel:i}});
\ No newline at end of file
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/packed/mvc/history/history-panel.js
--- a/static/scripts/packed/mvc/history/history-panel.js
+++ b/static/scripts/packed/mvc/history/history-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-model","mvc/history/hda-li","mvc/history/hdca-li","mvc/user/user-model","mvc/base-mvc","utils/localization"],function(e,b,a,f,k,d){var i=k.SessionStorageModel.extend({defaults:{expandedHdas:{},show_deleted:false,show_hidden:false},addExpandedHda:function(m){var n="expandedHdas";this.save(n,_.extend(this.get(n),_.object([m.id],[m.get("id")])))},removeExpandedHda:function(m){var n="expandedHdas";this.save(n,_.omit(this.get(n),m.id))},toString:function(){return"HistoryPrefs("+this.id+")"}});i.storageKeyPrefix="history:";i.historyStorageKey=function g(m){if(!m){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+m)}return(i.storageKeyPrefix+m)};i.get=function c(m){return new i({id:i.historyStorageKey(m)})};i.clearAll=function h(n){for(var m in sessionStorage){if(m.indexOf(i.storageKeyPrefix)===0){sessionStorage.removeItem(m)}}};var j=Backbone.View.extend(k.LoggableMixin).extend({HDAViewClass:b.HDAListItemView,HDCAViewClass:a.HDCAListItemView,tagName:"div",className:"history-panel",fxSpeed:"fast",emptyMsg:d("This history is empty"),noneFoundMsg:d("No matching datasets found"),initialize:function(m){m=m||{};if(m.logger){this.logger=m.logger}this.log(this+".initialize:",m);this.linkTarget=m.linkTarget||"_blank";this.fxSpeed=_.has(m,"fxSpeed")?(m.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor="";this.findContainerFn=m.findContainerFn;this.hdaViews={};this.indicator=new LoadingIndicator(this.$el);this._setUpListeners();var n=_.pick(m,"initiallyExpanded","show_deleted","show_hidden");this.setModel(this.model,n,false);if(m.onready){m.onready.call(this)}},_setUpListeners:function(){this.on("error",function(n,q,m,p,o){this.errorHandler(n,q,m,p,o)});this.on("loading-history",function(){this._showLoadingIndicator("loading history...",40)});this.on("loading-done",function(){this._hideLoadingIndicator(40);if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});if(this.logger){this.on("all",function(m){this.log(this+"",arguments)},this)}return this},errorHandler:function(o,r,n,q,p){this.error(o,r,n,q,p);window.xhr=r;if(r&&r.status===0&&r.readyState===0){}else{if(r&&r.status===502){}else{var m=this._parseErrorMessage(o,r,n,q,p);if(!this.$messages().is(":visible")){this.once("rendered",function(){this.displayMessage("error",m.message,m.details)})}else{this.displayMessage("error",m.message,m.details)}}}},_parseErrorMessage:function(q,t,u,o,m,r){var p=Galaxy.currUser,s={message:this._bePolite(o),details:{message:o,raven:(window.Raven)?(Raven.lastEventId()):(undefined),agent:navigator.userAgent,url:(window.Galaxy)?(Galaxy.lastAjax.url):(undefined),data:(window.Galaxy)?(Galaxy.lastAjax.data):(undefined),options:(t)?(_.omit(u,"xhr")):(u),xhr:t,source:(_.isFunction(q.toJSON))?(q.toJSON()):(q+""),user:(p instanceof f.User)?(p.toJSON()):(p+"")}};_.extend(s.details,m||{});if(t&&_.isFunction(t.getAllResponseHeaders)){var n=t.getAllResponseHeaders();n=_.compact(n.split("\n"));n=_.map(n,function(v){return v.split(": ")});s.details.xhr.responseHeaders=_.object(n)}return s},_bePolite:function(m){m=m||d("An error occurred while getting updates from the server");return m+". "+d("Please contact a Galaxy administrator if the problem persists")+"."},loadHistoryWithHDADetails:function(o,n,m,q){var p=function(r){return _.values(i.get(r.id).get("expandedHdas"))};return this.loadHistory(o,n,m,q,p)},loadHistory:function(p,o,n,s,q){var m=this;o=o||{};m.trigger("loading-history",m);var r=e.History.getHistoryData(p,{historyFn:n,hdaFn:s,hdaDetailIds:o.initiallyExpanded||q});return m._loadHistoryFromXHR(r,o).fail(function(v,t,u){m.trigger("error",m,v,o,d("An error was encountered while "+t),{historyId:p,history:u||{}})}).always(function(){m.trigger("loading-done",m)})},_loadHistoryFromXHR:function(o,n){var m=this;o.then(function(p,q){m.JSONToModel(p,q,n)});o.fail(function(q,p){m.render()});return o},JSONToModel:function(p,m,n){this.log("JSONToModel:",p,m,n);n=n||{};var o=new e.History(p,m,n);this.setModel(o);return this},setModel:function(n,m,o){m=m||{};o=(o!==undefined)?(o):(true);this.log("setModel:",n,m,o);this.freeModel();this.selectedHdaIds=[];if(n){this.model=n;if(this.logger){this.model.logger=this.logger}this._setUpWebStorage(m.initiallyExpanded,m.show_deleted,m.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this)}if(o){this.render()}return this},freeModel:function(){if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.contents)}this.freeHdaViews();return this},freeHdaViews:function(){this.hdaViews={};return this},_setUpWebStorage:function(n,m,o){this.storage=new i({id:i.historyStorageKey(this.model.get("id"))});if(_.isObject(n)){this.storage.set("exandedHdas",n)}if(_.isBoolean(m)){this.storage.set("show_deleted",m)}if(_.isBoolean(o)){this.storage.set("show_hidden",o)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get());return this},_setUpModelEventHandlers:function(){this.model.contents.on("add",this.addContentView,this);this.model.on("error error:contents",function(n,p,m,o){this.errorHandler(n,p,m,o)},this);return this},render:function(o,p){this.log("render:",o,p);o=(o===undefined)?(this.fxSpeed):(o);var m=this,n;if(this.model){n=this.renderModel()}else{n=this.renderWithoutModel()}$(m).queue("fx",[function(q){if(o&&m.$el.is(":visible")){m.$el.fadeOut(o,q)}else{q()}},function(q){m.$el.empty();if(n){m.$el.append(n.children())}q()},function(q){if(o&&!m.$el.is(":visible")){m.$el.fadeIn(o,q)}else{q()}},function(q){if(p){p.call(this)}m.trigger("rendered",this);q()}]);return this},renderWithoutModel:function(){var m=$("<div/>"),n=$("<div/>").addClass("message-container").css({margin:"4px"});return m.append(n)},renderModel:function(){var m=$("<div/>");m.append(j.templates.historyPanel(this.model.toJSON()));this.$emptyMessage(m).text(this.emptyMsg);m.find(".history-secondary-actions").prepend(this._renderSearchButton());this._setUpBehaviours(m);this.renderHdas(m);return m},_renderEmptyMsg:function(o){var n=this,m=n.$emptyMessage(o);if(!_.isEmpty(n.hdaViews)){m.hide()}else{if(n.searchFor){m.text(n.noneFoundMsg).show()}else{m.text(n.emptyMsg).show()}}return this},_renderSearchButton:function(m){return faIconButton({title:d("Search datasets"),classes:"history-search-btn",faIcon:"fa-search"})},_setUpBehaviours:function(m){m=m||this.$el;m.find("[title]").tooltip({placement:"bottom"});this._setUpSearchInput(m.find(".history-search-controls .history-search-input"));return this},$container:function(){return(this.findContainerFn)?(this.findContainerFn.call(this)):(this.$el.parent())},$datasetsList:function(m){return(m||this.$el).find(".datasets-list")},$messages:function(m){return(m||this.$el).find(".message-container")},$emptyMessage:function(m){return(m||this.$el).find(".empty-history-message")},renderHdas:function(n){n=n||this.$el;var m=this,p={},o=this.model.contents.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters);this.$datasetsList(n).empty();if(o.length){o.each(function(r){var q=r.id,s=m._createContentView(r);p[q]=s;if(_.contains(m.selectedHdaIds,q)){s.selected=true}m.attachContentView(s.render(),n)})}this.hdaViews=p;this._renderEmptyMsg(n);return this.hdaViews},_createContentView:function(p){var n=this._getContentClass(p),m=_.extend(this._getContentOptions(p),{model:p}),o=new n(m);this._setUpHdaListeners(o);return o},_getContentClass:function(m){var n=m.get("history_content_type");switch(n){case"dataset":return this.HDAViewClass;case"dataset_collection":return this.HDCAViewClass}throw new TypeError("Unknown history_content_type: "+n)},_getContentOptions:function(m){return{linkTarget:this.linkTarget,expanded:!!this.storage.get("expandedHdas")[m.id],hasUser:this.model.ownedByCurrUser(),logger:this.logger}},_setUpHdaListeners:function(n){var m=this;n.on("error",function(p,r,o,q){m.errorHandler(p,r,o,q)});n.on("expanded",function(o){m.storage.addExpandedHda(o.model)});n.on("collapsed",function(o){m.storage.removeExpandedHda(o.model)});return this},attachContentView:function(o,n){n=n||this.$el;var m=this.$datasetsList(n);m.prepend(o.$el);return this},addContentView:function(p){this.log("add."+this,p);var n=this;if(!p.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return n}$({}).queue([function o(r){var q=n.$emptyMessage();if(q.is(":visible")){q.fadeOut(n.fxSpeed,r)}else{r()}},function m(q){var r=n._createContentView(p);n.hdaViews[p.id]=r;r.render().$el.hide();n.scrollToTop();n.attachContentView(r);r.$el.slideDown(n.fxSpeed)}]);return n},views:function(m){var n=this,o=this.model.contents.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters);if(m!==undefined){return n.hdaViews[o.at(m).id]}return o.map(function(p){return n.hdaViews[p.id]})},refreshContents:function(n,m){if(this.model){return this.model.refresh(n,m)}return $.when()},hdaViewRange:function(p,o){if(p===o){return[p]}var m=this,n=false,q=[];this.model.contents.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters).each(function(r){if(n){q.push(m.hdaViews[r.id]);if(r===p.model||r===o.model){n=false}}else{if(r===p.model||r===o.model){n=true;q.push(m.hdaViews[r.id])}}});return q},events:{"click .message-container":"clearMessages","click .history-search-btn":"toggleSearchControls"},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(m){m.collapse()});this.storage.set("expandedHdas",{});return this},toggleShowDeleted:function(m){m=(m!==undefined)?(m):(!this.storage.get("show_deleted"));this.storage.set("show_deleted",m);this.renderHdas();return this.storage.get("show_deleted")},toggleShowHidden:function(m){m=(m!==undefined)?(m):(!this.storage.get("show_hidden"));this.storage.set("show_hidden",m);this.renderHdas();return this.storage.get("show_hidden")},_setUpSearchInput:function(n){var o=this,p=".history-search-input";function m(q){if(o.model.contents.haveDetails()){o.searchHdas(q);return}o.$el.find(p).searchInput("toggle-loading");o.model.contents.fetchAllDetails({silent:true}).always(function(){o.$el.find(p).searchInput("toggle-loading")}).done(function(){o.searchHdas(q)})}n.searchInput({initialVal:o.searchFor,name:"history-search",placeholder:"search datasets",classes:"history-search",onfirstsearch:m,onsearch:_.bind(this.searchHdas,this),onclear:_.bind(this.clearHdaSearch,this)});return n},toggleSearchControls:function(o,m){var n=this.$el.find(".history-search-controls"),p=(jQuery.type(o)==="number")?(o):(this.fxSpeed);m=(m!==undefined)?(m):(!n.is(":visible"));if(m){n.slideDown(p,function(){$(this).find("input").focus()})}else{n.slideUp(p)}return m},searchHdas:function(m){var n=this;this.searchFor=m;this.filters=[function(o){return o.matchesAll(n.searchFor)}];this.trigger("search:searching",m,this);this.renderHdas();return this},clearHdaSearch:function(m){this.searchFor="";this.filters=[];this.trigger("search:clear",this);this.renderHdas();return this},_showLoadingIndicator:function(n,m,o){m=(m!==undefined)?(m):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,o)}else{this.$el.fadeOut(m);this.indicator.show(n,m,o)}},_hideLoadingIndicator:function(m,n){m=(m!==undefined)?(m):(this.fxSpeed);if(this.indicator){this.indicator.hide(m,n)}},displayMessage:function(r,s,q){var o=this;this.scrollToTop();var p=this.$messages(),m=$("<div/>").addClass(r+"message").html(s);if(!_.isEmpty(q)){var n=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(o._messageToModalOptions(r,s,q));return false});m.append(" ",n)}return p.html(m)},_messageToModalOptions:function(q,s,p){var m=this,r=$("<div/>"),o={title:"Details"};function n(t){t=_.omit(t,_.functions(t));return["<table>",_.map(t,function(v,u){v=(_.isObject(v))?(n(v)):(v);return'<tr><td style="vertical-align: top; color: grey">'+u+'</td><td style="padding-left: 8px">'+v+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(p)){o.body=r.append(n(p))}else{o.body=r.html(p)}o.buttons={Ok:function(){Galaxy.modal.hide();m.clearMessages()}};return o},clearMessages:function(){this.$messages().empty();return this},scrollPosition:function(){return this.$container().scrollTop()},scrollTo:function(m){this.$container().scrollTop(m);return this},scrollToTop:function(){this.$container().scrollTop(0);return this},scrollToId:function(n){if((!n)||(!this.hdaViews[n])){return this}var m=this.hdaViews[n];this.scrollTo(m.el.offsetTop);return this},scrollToHid:function(m){var n=this.model.contents.getByHid(m);if(!n){return this}return this.scrollToId(n.id)},print:function(){var m=this;m.debug(this);_.each(this.hdaViews,function(n,o){m.debug("\t "+o,n)})},toString:function(){return"ReadOnlyHistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});var l=['<div class="history-controls">','<div class="history-search-controls">','<div class="history-search-input"></div>',"</div>",'<div class="history-title">',"<% if( history.name ){ %>",'<div class="history-name"><%= history.name %></div>',"<% } %>","</div>",'<div class="history-subtitle clear">',"<% if( history.nice_size ){ %>",'<div class="history-size"><%= history.nice_size %></div>',"<% } %>",'<div class="history-secondary-actions"></div>',"</div>","<% if( history.deleted ){ %>",'<div class="warningmessagesmall"><strong>',d("You are currently viewing a deleted history!"),"</strong></div>","<% } %>",'<div class="message-container">',"<% if( history.message ){ %>",'<div class="<%= history.status %>message"><%= history.message %></div>',"<% } %>","</div>",'<div class="quota-message errormessage">',d("You are over your disk quota"),". ",d("Tool execution is on hold until your disk usage drops below your allocated quota"),".","</div>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="history-dataset-actions">','<div class="btn-group">','<button class="history-select-all-datasets-btn btn btn-default"','data-mode="select">',d("All"),"</button>",'<button class="history-deselect-all-datasets-btn btn btn-default"','data-mode="select">',d("None"),"</button>","</div>",'<button class="history-dataset-action-popup-btn btn btn-default">',d("For all selected"),"...</button>","</div>","</div>",'<div class="datasets-list"></div>','<div class="empty-history-message infomessagesmall">',d("This history is empty"),"</div>"].join("");j.templates={historyPanel:function(m){return _.template(l,m,{variable:"history"})}};return{ReadOnlyHistoryPanel:j}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/history/hda-li","mvc/history/hdca-li","mvc/user/user-model","mvc/base-mvc","utils/localization"],function(e,b,a,f,k,d){var i=k.SessionStorageModel.extend({defaults:{expandedHdas:{},show_deleted:false,show_hidden:false},addExpandedHda:function(m){var n="expandedHdas";this.save(n,_.extend(this.get(n),_.object([m.id],[m.get("id")])))},removeExpandedHda:function(m){var n="expandedHdas";this.save(n,_.omit(this.get(n),m.id))},toString:function(){return"HistoryPrefs("+this.id+")"}});i.storageKeyPrefix="history:";i.historyStorageKey=function g(m){if(!m){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+m)}return(i.storageKeyPrefix+m)};i.get=function c(m){return new i({id:i.historyStorageKey(m)})};i.clearAll=function h(n){for(var m in sessionStorage){if(m.indexOf(i.storageKeyPrefix)===0){sessionStorage.removeItem(m)}}};var j=Backbone.View.extend(k.LoggableMixin).extend({HDAViewClass:b.HDAListItemView,HDCAViewClass:a.HDCAListItemView,tagName:"div",className:"history-panel",fxSpeed:"fast",emptyMsg:d("This history is empty"),noneFoundMsg:d("No matching datasets found"),initialize:function(m){m=m||{};if(m.logger){this.logger=m.logger}this.log(this+".initialize:",m);this.linkTarget=m.linkTarget||"_blank";this.fxSpeed=_.has(m,"fxSpeed")?(m.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor="";this.findContainerFn=m.findContainerFn;this.hdaViews={};this.indicator=new LoadingIndicator(this.$el);this._setUpListeners();var n=_.pick(m,"initiallyExpanded","show_deleted","show_hidden");this.setModel(this.model,n,false);if(m.onready){m.onready.call(this)}},_setUpListeners:function(){this.on("error",function(n,q,m,p,o){this.errorHandler(n,q,m,p,o)});this.on("loading-history",function(){this._showLoadingIndicator("loading history...",40)});this.on("loading-done",function(){this._hideLoadingIndicator(40);if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});if(this.logger){this.on("all",function(m){this.log(this+"",arguments)},this)}return this},errorHandler:function(o,r,n,q,p){this.error(o,r,n,q,p);window.xhr=r;if(r&&r.status===0&&r.readyState===0){}else{if(r&&r.status===502){}else{var m=this._parseErrorMessage(o,r,n,q,p);if(!this.$messages().is(":visible")){this.once("rendered",function(){this.displayMessage("error",m.message,m.details)})}else{this.displayMessage("error",m.message,m.details)}}}},_parseErrorMessage:function(q,t,u,o,m,r){var p=Galaxy.currUser,s={message:this._bePolite(o),details:{message:o,raven:(window.Raven)?(Raven.lastEventId()):(undefined),agent:navigator.userAgent,url:(window.Galaxy)?(Galaxy.lastAjax.url):(undefined),data:(window.Galaxy)?(Galaxy.lastAjax.data):(undefined),options:(t)?(_.omit(u,"xhr")):(u),xhr:t,source:(_.isFunction(q.toJSON))?(q.toJSON()):(q+""),user:(p instanceof f.User)?(p.toJSON()):(p+"")}};_.extend(s.details,m||{});if(t&&_.isFunction(t.getAllResponseHeaders)){var n=t.getAllResponseHeaders();n=_.compact(n.split("\n"));n=_.map(n,function(v){return v.split(": ")});s.details.xhr.responseHeaders=_.object(n)}return s},_bePolite:function(m){m=m||d("An error occurred while getting updates from the server");return m+". "+d("Please contact a Galaxy administrator if the problem persists")+"."},loadHistoryWithHDADetails:function(o,n,m,q){this.info("loadHistoryWithHDADetails:",o,n,m,q);var p=function(r){return _.values(i.get(r.id).get("expandedHdas"))};return this.loadHistory(o,n,m,q,p)},loadHistory:function(p,o,n,s,q){this.info("loadHistory:",p,o,n,s,q);var m=this;o=o||{};m.trigger("loading-history",m);var r=e.History.getHistoryData(p,{historyFn:n,hdaFn:s,hdaDetailIds:o.initiallyExpanded||q});return m._loadHistoryFromXHR(r,o).fail(function(v,t,u){m.trigger("error",m,v,o,d("An error was encountered while "+t),{historyId:p,history:u||{}})}).always(function(){m.trigger("loading-done",m)})},_loadHistoryFromXHR:function(o,n){var m=this;o.then(function(p,q){m.JSONToModel(p,q,n)});o.fail(function(q,p){m.render()});return o},JSONToModel:function(p,m,n){this.log("JSONToModel:",p,m,n);n=n||{};var o=new e.History(p,m,n);this.setModel(o);return this},setModel:function(n,m,o){m=m||{};o=(o!==undefined)?(o):(true);this.log("setModel:",n,m,o);this.freeModel();this.selectedHdaIds=[];if(n){this.model=n;if(this.logger){this.model.logger=this.logger}this._setUpWebStorage(m.initiallyExpanded,m.show_deleted,m.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this)}if(o){this.render()}return this},freeModel:function(){if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.contents)}this.freeHdaViews();return this},freeHdaViews:function(){this.hdaViews={};return this},_setUpWebStorage:function(n,m,o){this.storage=new i({id:i.historyStorageKey(this.model.get("id"))});if(_.isObject(n)){this.storage.set("exandedHdas",n)}if(_.isBoolean(m)){this.storage.set("show_deleted",m)}if(_.isBoolean(o)){this.storage.set("show_hidden",o)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get());return this},_setUpModelEventHandlers:function(){this.model.contents.on("add",this.addContentView,this);this.model.on("error error:contents",function(n,p,m,o){this.errorHandler(n,p,m,o)},this);return this},render:function(o,p){this.log("render:",o,p);o=(o===undefined)?(this.fxSpeed):(o);var m=this,n;if(this.model){n=this.renderModel()}else{n=this.renderWithoutModel()}$(m).queue("fx",[function(q){if(o&&m.$el.is(":visible")){m.$el.fadeOut(o,q)}else{q()}},function(q){m.$el.empty();if(n){m.$el.append(n.children())}q()},function(q){if(o&&!m.$el.is(":visible")){m.$el.fadeIn(o,q)}else{q()}},function(q){if(p){p.call(this)}m.trigger("rendered",this);q()}]);return this},renderWithoutModel:function(){var m=$("<div/>"),n=$("<div/>").addClass("message-container").css({margin:"4px"});return m.append(n)},renderModel:function(){var m=$("<div/>");m.append(j.templates.historyPanel(this.model.toJSON()));this.$emptyMessage(m).text(this.emptyMsg);m.find(".history-secondary-actions").prepend(this._renderSearchButton());this._setUpBehaviours(m);this.renderHdas(m);return m},_renderEmptyMsg:function(o){var n=this,m=n.$emptyMessage(o);if(!_.isEmpty(n.hdaViews)){m.hide()}else{if(n.searchFor){m.text(n.noneFoundMsg).show()}else{m.text(n.emptyMsg).show()}}return this},_renderSearchButton:function(m){return faIconButton({title:d("Search datasets"),classes:"history-search-btn",faIcon:"fa-search"})},_setUpBehaviours:function(m){m=m||this.$el;m.find("[title]").tooltip({placement:"bottom"});this._setUpSearchInput(m.find(".history-search-controls .history-search-input"));return this},$container:function(){return(this.findContainerFn)?(this.findContainerFn.call(this)):(this.$el.parent())},$datasetsList:function(m){return(m||this.$el).find(".datasets-list")},$messages:function(m){return(m||this.$el).find(".message-container")},$emptyMessage:function(m){return(m||this.$el).find(".empty-history-message")},renderHdas:function(n){n=n||this.$el;var m=this,p={},o=this.model.contents.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters);this.$datasetsList(n).empty();if(o.length){o.each(function(r){var q=r.id,s=m._createContentView(r);p[q]=s;if(_.contains(m.selectedHdaIds,q)){s.selected=true}m.attachContentView(s.render(),n)})}this.hdaViews=p;this._renderEmptyMsg(n);return this.hdaViews},_createContentView:function(p){var n=this._getContentClass(p),m=_.extend(this._getContentOptions(p),{model:p}),o=new n(m);this._setUpHdaListeners(o);return o},_getContentClass:function(m){var n=m.get("history_content_type");switch(n){case"dataset":return this.HDAViewClass;case"dataset_collection":return this.HDCAViewClass}throw new TypeError("Unknown history_content_type: "+n)},_getContentOptions:function(m){return{linkTarget:this.linkTarget,expanded:!!this.storage.get("expandedHdas")[m.id],hasUser:this.model.ownedByCurrUser(),logger:this.logger}},_setUpHdaListeners:function(n){var m=this;n.on("error",function(p,r,o,q){m.errorHandler(p,r,o,q)});n.on("expanded",function(o){m.storage.addExpandedHda(o.model)});n.on("collapsed",function(o){m.storage.removeExpandedHda(o.model)});return this},attachContentView:function(o,n){n=n||this.$el;var m=this.$datasetsList(n);m.prepend(o.$el);return this},addContentView:function(p){this.log("add."+this,p);var n=this;if(!p.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return n}$({}).queue([function o(r){var q=n.$emptyMessage();if(q.is(":visible")){q.fadeOut(n.fxSpeed,r)}else{r()}},function m(q){var r=n._createContentView(p);n.hdaViews[p.id]=r;r.render().$el.hide();n.scrollToTop();n.attachContentView(r);r.$el.slideDown(n.fxSpeed)}]);return n},views:function(m){var n=this,o=this.model.contents.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters);if(m!==undefined){return n.hdaViews[o.at(m).id]}return o.map(function(p){return n.hdaViews[p.id]})},refreshContents:function(n,m){if(this.model){return this.model.refresh(n,m)}return $.when()},hdaViewRange:function(p,o){if(p===o){return[p]}var m=this,n=false,q=[];this.model.contents.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters).each(function(r){if(n){q.push(m.hdaViews[r.id]);if(r===p.model||r===o.model){n=false}}else{if(r===p.model||r===o.model){n=true;q.push(m.hdaViews[r.id])}}});return q},events:{"click .message-container":"clearMessages","click .history-search-btn":"toggleSearchControls"},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(m){m.collapse()});this.storage.set("expandedHdas",{});return this},toggleShowDeleted:function(m){m=(m!==undefined)?(m):(!this.storage.get("show_deleted"));this.storage.set("show_deleted",m);this.renderHdas();return this.storage.get("show_deleted")},toggleShowHidden:function(m){m=(m!==undefined)?(m):(!this.storage.get("show_hidden"));this.storage.set("show_hidden",m);this.renderHdas();return this.storage.get("show_hidden")},_setUpSearchInput:function(n){var o=this,p=".history-search-input";function m(q){if(o.model.contents.haveDetails()){o.searchHdas(q);return}o.$el.find(p).searchInput("toggle-loading");o.model.contents.fetchAllDetails({silent:true}).always(function(){o.$el.find(p).searchInput("toggle-loading")}).done(function(){o.searchHdas(q)})}n.searchInput({initialVal:o.searchFor,name:"history-search",placeholder:"search datasets",classes:"history-search",onfirstsearch:m,onsearch:_.bind(this.searchHdas,this),onclear:_.bind(this.clearHdaSearch,this)});return n},toggleSearchControls:function(o,m){var n=this.$el.find(".history-search-controls"),p=(jQuery.type(o)==="number")?(o):(this.fxSpeed);m=(m!==undefined)?(m):(!n.is(":visible"));if(m){n.slideDown(p,function(){$(this).find("input").focus()})}else{n.slideUp(p)}return m},searchHdas:function(m){var n=this;this.searchFor=m;this.filters=[function(o){return o.matchesAll(n.searchFor)}];this.trigger("search:searching",m,this);this.renderHdas();return this},clearHdaSearch:function(m){this.searchFor="";this.filters=[];this.trigger("search:clear",this);this.renderHdas();return this},_showLoadingIndicator:function(n,m,o){m=(m!==undefined)?(m):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,o)}else{this.$el.fadeOut(m);this.indicator.show(n,m,o)}},_hideLoadingIndicator:function(m,n){m=(m!==undefined)?(m):(this.fxSpeed);if(this.indicator){this.indicator.hide(m,n)}},displayMessage:function(r,s,q){var o=this;this.scrollToTop();var p=this.$messages(),m=$("<div/>").addClass(r+"message").html(s);if(!_.isEmpty(q)){var n=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(o._messageToModalOptions(r,s,q));return false});m.append(" ",n)}return p.html(m)},_messageToModalOptions:function(q,s,p){var m=this,r=$("<div/>"),o={title:"Details"};function n(t){t=_.omit(t,_.functions(t));return["<table>",_.map(t,function(v,u){v=(_.isObject(v))?(n(v)):(v);return'<tr><td style="vertical-align: top; color: grey">'+u+'</td><td style="padding-left: 8px">'+v+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(p)){o.body=r.append(n(p))}else{o.body=r.html(p)}o.buttons={Ok:function(){Galaxy.modal.hide();m.clearMessages()}};return o},clearMessages:function(){this.$messages().empty();return this},scrollPosition:function(){return this.$container().scrollTop()},scrollTo:function(m){this.$container().scrollTop(m);return this},scrollToTop:function(){this.$container().scrollTop(0);return this},scrollToId:function(n){if((!n)||(!this.hdaViews[n])){return this}var m=this.hdaViews[n];this.scrollTo(m.el.offsetTop);return this},scrollToHid:function(m){var n=this.model.contents.getByHid(m);if(!n){return this}return this.scrollToId(n.id)},print:function(){var m=this;m.debug(this);_.each(this.hdaViews,function(n,o){m.debug("\t "+o,n)})},toString:function(){return"ReadOnlyHistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});var l=['<div class="history-controls">','<div class="history-search-controls">','<div class="history-search-input"></div>',"</div>",'<div class="history-title">',"<% if( history.name ){ %>",'<div class="history-name"><%= history.name %></div>',"<% } %>","</div>",'<div class="history-subtitle clear">',"<% if( history.nice_size ){ %>",'<div class="history-size"><%= history.nice_size %></div>',"<% } %>",'<div class="history-secondary-actions"></div>',"</div>","<% if( history.deleted ){ %>",'<div class="warningmessagesmall"><strong>',d("You are currently viewing a deleted history!"),"</strong></div>","<% } %>",'<div class="message-container">',"<% if( history.message ){ %>",'<div class="<%= history.status %>message"><%= history.message %></div>',"<% } %>","</div>",'<div class="quota-message errormessage">',d("You are over your disk quota"),". ",d("Tool execution is on hold until your disk usage drops below your allocated quota"),".","</div>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="history-dataset-actions">','<div class="btn-group">','<button class="history-select-all-datasets-btn btn btn-default"','data-mode="select">',d("All"),"</button>",'<button class="history-deselect-all-datasets-btn btn btn-default"','data-mode="select">',d("None"),"</button>","</div>",'<button class="history-dataset-action-popup-btn btn btn-default">',d("For all selected"),"...</button>","</div>","</div>",'<div class="datasets-list"></div>','<div class="empty-history-message infomessagesmall">',d("This history is empty"),"</div>"].join("");j.templates={historyPanel:function(m){return _.template(l,m,{variable:"history"})}};return{ReadOnlyHistoryPanel:j}});
\ No newline at end of file
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/packed/mvc/library/library-dataset-view.js
--- a/static/scripts/packed/mvc/library/library-dataset-view.js
+++ b/static/scripts/packed/mvc/library/library-dataset-view.js
@@ -1,1 +1,1 @@
-define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,b){var a=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_modify_dataset":"enableModification","click .toolbtn_cancel_modifications":"render","click .toolbtn-download-dataset":"downloadDataset","click .toolbtn-import-dataset":"importIntoHistory","click .toolbtn-share-dataset":"shareDataset","click .btn-copy-link-to-clipboard":"copyToClipboard","click .btn-make-private":"makeDatasetPrivate","click .btn-remove-restrictions":"removeDatasetRestrictions","click .toolbtn_save_permissions":"savePermissions","click .toolbtn_save_modifications":"comingSoon",},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchDataset()}},fetchDataset:function(e){this.options=_.extend(this.options,e);this.model=new c.Item({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{if(f.options.show_version){f.fetchVersion()}else{f.render()}}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred :(. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){this.options=_.extend(this.options,e);$(".tooltip").remove();var f=this.templateDataset();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},fetchVersion:function(e){this.options=_.extend(this.options,e);that=this;if(!this.options.ldda_id){this.render();d.error("Library dataset version requested but no id provided.")}else{this.ldda=new c.Ldda({id:this.options.ldda_id});this.ldda.url=this.ldda.urlRoot+this.model.id+"/versions/"+this.ldda.id;this.ldda.fetch({success:function(){that.renderVersion()},error:function(g,f){if(typeof f.responseJSON!=="undefined"){d.error(f.responseJSON.err_msg)}else{d.error("An error ocurred :(")}}})}},renderVersion:function(){$(".tooltip").remove();var e=this.templateVersion();this.$el.html(e({item:this.model,ldda:this.ldda}));$(".peek").html(this.ldda.get("peek"))},enableModification:function(){$(".tooltip").remove();var e=this.templateModifyDataset();this.$el.html(e({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},downloadDataset:function(){var e="/api/libraries/datasets/download/uncompressed";var f={ldda_ids:this.id};this.processDownload(e,f)},processDownload:function(f,g,h){if(f&&g){g=typeof g=="string"?g:$.param(g);var e="";$.each(g.split("&"),function(){var i=this.split("=");e+='<input type="hidden" name="'+i[0]+'" value="'+i[1]+'" />'});$('<form action="'+f+'" method="'+(h||"post")+'">'+e+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon")}},importIntoHistory:function(){this.refreshUserHistoriesList(function(e){var f=e.templateBulkImportInModal();e.modal=Galaxy.modal;e.modal.show({closing_events:true,title:"Import into History",body:f({histories:e.histories.models}),buttons:{Import:function(){e.importCurrentIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})},refreshUserHistoriesList:function(f){var e=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(g){if(g.length===0){d.warning("You have to create history first. Click this to do so.","",{onclick:function(){window.location="/"}})}else{f(e)}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg)}else{d.error("An error ocurred :(")}}})},importCurrentIntoHistory:function(){var f=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();var g=new c.HistoryItem();g.url=g.urlRoot+f+"/contents";var e="/api/histories/"+f+"/set_as_current";$.ajax({url:e,type:"PUT"});g.save({content:this.id,source:"library"},{success:function(){Galaxy.modal.hide();d.success("Dataset imported. Click this to start analysing it.","",{onclick:function(){window.location="/"}})},error:function(i,h){if(typeof h.responseJSON!=="undefined"){d.error("Dataset not imported. "+h.responseJSON.err_msg)}else{d.error("An error occured! Dataset not imported. Please try again.")}}})},shareDataset:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(f){this.options=_.extend(this.options,f);$(".tooltip").remove();if(this.options.fetched_permissions!==undefined){if(this.options.fetched_permissions.access_dataset_roles.length===0){this.model.set({is_unrestricted:true})}else{this.model.set({is_unrestricted:false})}}var h=false;if(Galaxy.currUser){h=Galaxy.currUser.isAdmin()}var g=this.templateDatasetPermissions();this.$el.html(g({item:this.model,is_admin:h}));var e=this;if(this.options.fetched_permissions===undefined){$.get("/api/libraries/datasets/"+e.id+"/permissions?scope=current").done(function(i){e.prepareSelectBoxes({fetched_permissions:i,is_admin:h})}).fail(function(){d.error("An error occurred while fetching dataset permissions. :(")})}else{this.prepareSelectBoxes({is_admin:h})}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},prepareSelectBoxes:function(r){this.options=_.extend(this.options,r);var s=this.options.fetched_permissions;var k=this.options.is_admin;var q=this;var m=[];for(var h=0;h<s.access_dataset_roles.length;h++){m.push(s.access_dataset_roles[h]+":"+s.access_dataset_roles[h])}var f=[];for(var h=0;h<s.modify_item_roles.length;h++){f.push(s.modify_item_roles[h]+":"+s.modify_item_roles[h])}var g=[];for(var h=0;h<s.manage_dataset_roles.length;h++){g.push(s.manage_dataset_roles[h]+":"+s.manage_dataset_roles[h])}if(k){var o={minimumInputLength:0,css:"access_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#access_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:m.join(","),dropdownCssClass:"bigdrop"};var l={minimumInputLength:0,css:"modify_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#modify_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:f.join(","),dropdownCssClass:"bigdrop"};var p={minimumInputLength:0,css:"manage_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#manage_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:g.join(","),dropdownCssClass:"bigdrop"};q.accessSelectObject=new b.View(o);q.modifySelectObject=new b.View(l);q.manageSelectObject=new b.View(p)}else{var n=q.templateAccessSelect();$.get("/api/libraries/datasets/"+q.id+"/permissions?scope=available",function(i){$(".access_perm").html(n({options:i.roles}));q.accessSelectObject=$("#access_select").select2()}).fail(function(){d.error("An error occurred while fetching data with permissions. :(")})}},comingSoon:function(){d.warning("Feature coming soon")},copyToClipboard:function(){var e=Backbone.history.location.href;if(e.lastIndexOf("/permissions")!==-1){e=e.substr(0,e.lastIndexOf("/permissions"))}window.prompt("Copy to clipboard: Ctrl+C, Enter",e)},makeDatasetPrivate:function(){var e=this;$.post("/api/libraries/datasets/"+e.id+"/permissions?action=make_private").done(function(f){e.model.set({is_unrestricted:false});e.showPermissions({fetched_permissions:f});d.success("The dataset is now private to you")}).fail(function(){d.error("An error occurred while making dataset private :(")})},removeDatasetRestrictions:function(){var e=this;$.post("/api/libraries/datasets/"+e.id+"/permissions?action=remove_restrictions").done(function(f){e.model.set({is_unrestricted:true});e.showPermissions({fetched_permissions:f});d.success("Access to this dataset is now unrestricted")}).fail(function(){d.error("An error occurred while making dataset unrestricted :(")})},savePermissions:function(e){var n=this;var k=this.accessSelectObject.$el.select2("data");var f=this.manageSelectObject.$el.select2("data");var m=this.modifySelectObject.$el.select2("data");var g=[];var j=[];var l=[];for(var h=k.length-1;h>=0;h--){g.push(k[h].id)}for(var h=f.length-1;h>=0;h--){j.push(f[h].id)}for(var h=m.length-1;h>=0;h--){l.push(m[h].id)}$.post("/api/libraries/datasets/"+n.id+"/permissions?action=set_permissions",{"access_ids[]":g,"manage_ids[]":j,"modify_ids[]":l,}).done(function(i){n.showPermissions({fetched_permissions:i});d.success("Permissions saved")}).fail(function(){d.error("An error occurred while setting dataset permissions :(")})},templateDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');e.push(' <% if (item.get("can_user_modify")) { %>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library item" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(" <% } %>");e.push(' <% if (item.get("can_user_manage")) { %>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Manage permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push(" <% } %>");e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<% if (item.get("is_unrestricted")) { %>');e.push(' <div class="alert alert-info">');e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"></span> To Clipboard</span></button> ');e.push(" </div>");e.push("<% } %>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push(' <% if (item.get("has_versions")) { %>');e.push(" <div>");e.push(" <h3>Expired versions:</h3>");e.push(" <ul>");e.push(' <% _.each(item.get("expired_versions"), function(version) { %>');e.push(' <li><a title="See details of this version" href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/versions/<%- version[0] %>"><%- version[1] %></a></li>');e.push(" <% }) %>");e.push(" <ul>");e.push(" </div>");e.push(" <% } %>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateVersion:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go to latest dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-caret-left fa-lg"></span> Latest dataset</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push(' <div class="alert alert-warning">This is an expired version of the library dataset: <%= _.escape(item.get("name")) %></div>');e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(ldda.id) %>">Name</th>');e.push(' <td><%= _.escape(ldda.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (ldda.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(ldda.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(ldda.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(ldda.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(ldda.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(ldda.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateModifyDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push('<p>For more editing options please import the dataset to history and use "Edit attributes" on it.</p>');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><input class="input_dataset_name form-control" type="text" placeholder="name" value="<%= _.escape(item.get("name")) %>"></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(' <tr scope="row">');e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <% if (item.get("metadata_comment_lines") === "") { %>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" <% } else { %>");e.push(' <td scope="row">unknown</td>');e.push(" <% } %>");e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" </table>");e.push("<div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push("</div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateDatasetPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to containing folder" class="btn btn-default primary-button" type="button"><span class="fa fa-folder-open-o"></span> Containing Folder</span></button></a>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go back to dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-file-o"></span> Dataset Details</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<h1>Dataset: <%= _.escape(item.get("name")) %></h1>');e.push('<div class="alert alert-warning">');e.push("<% if (is_admin) { %>");e.push("You are logged in as an <strong>administrator</strong> therefore you can manage any dataset on this Galaxy instance. Please make sure you understand the consequences.");e.push("<% } else { %>");e.push("You can assign any number of roles to any of the following permission types. However please read carefully the implications of such actions.");e.push("<% } %>");e.push("</div>");e.push('<div class="dataset_table">');e.push("<h2>Library-related permissions</h2>");e.push("<h4>Roles that can modify the library item</h4>");e.push('<div id="modify_perm" class="modify_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can modify name, metadata, and other information about this library item.</div>');e.push("<hr/>");e.push("<h2>Dataset-related permissions</h2>");e.push('<div class="alert alert-warning">Changes made below will affect <strong>every</strong> library item that was created from this dataset and also every history this dataset is part of.</div>');e.push('<% if (!item.get("is_unrestricted")) { %>');e.push(" <p>You can remove all access restrictions on this dataset. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Everybody will be able to access the dataset." class="btn btn-default btn-remove-restrictions primary-button" type="button">');e.push(' <span class="fa fa-globe"> Remove restrictions</span>');e.push(" </button>");e.push(" </p>");e.push("<% } else { %>");e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page.");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"> To Clipboard</span></button> ');e.push(" <p>You can make this dataset private to you. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Only you will be able to access the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"> Make Private</span></button>');e.push(" </p>");e.push("<% } %>");e.push("<h4>Roles that can access the dataset</h4>");e.push('<div id="access_perm" class="access_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User has to have <strong>all these roles</strong> in order to access this dataset. Users without access permission <strong>cannot</strong> have other permissions on this dataset. If there are no access roles set on the dataset it is considered <strong>unrestricted</strong>.</div>');e.push("<h4>Roles that can manage permissions on the dataset</h4>");e.push('<div id="manage_perm" class="manage_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can manage permissions of this dataset. If you remove yourself you will loose the ability manage this dataset unless you are an admin.</div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications made on this page" class="btn btn-default toolbtn_save_permissions primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateBulkImportInModal:function(){var e=[];e.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');e.push("Select history: ");e.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');e.push(" <% _.each(histories, function(history) { %>");e.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');e.push(" <% }); %>");e.push("</select>");e.push("</span>");return _.template(e.join(""))},templateAccessSelect:function(){var e=[];e.push('<select id="access_select" multiple>');e.push(" <% _.each(options, function(option) { %>");e.push(' <option value="<%- option.name %>"><%- option.name %></option>');e.push(" <% }); %>");e.push("</select>");return _.template(e.join(""))}});return{LibraryDatasetView:a}});
\ No newline at end of file
+define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,b){var a=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_modify_dataset":"enableModification","click .toolbtn_cancel_modifications":"render","click .toolbtn-download-dataset":"downloadDataset","click .toolbtn-import-dataset":"importIntoHistory","click .toolbtn-share-dataset":"shareDataset","click .btn-copy-link-to-clipboard":"copyToClipboard","click .btn-make-private":"makeDatasetPrivate","click .btn-remove-restrictions":"removeDatasetRestrictions","click .toolbtn_save_permissions":"savePermissions","click .toolbtn_save_modifications":"comingSoon",},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchDataset()}},fetchDataset:function(e){this.options=_.extend(this.options,e);this.model=new c.Item({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{if(f.options.show_version){f.fetchVersion()}else{f.render()}}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred :(. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){this.options=_.extend(this.options,e);$(".tooltip").remove();var f=this.templateDataset();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},fetchVersion:function(e){this.options=_.extend(this.options,e);that=this;if(!this.options.ldda_id){this.render();d.error("Library dataset version requested but no id provided.")}else{this.ldda=new c.Ldda({id:this.options.ldda_id});this.ldda.url=this.ldda.urlRoot+this.model.id+"/versions/"+this.ldda.id;this.ldda.fetch({success:function(){that.renderVersion()},error:function(g,f){if(typeof f.responseJSON!=="undefined"){d.error(f.responseJSON.err_msg)}else{d.error("An error ocurred :(")}}})}},renderVersion:function(){$(".tooltip").remove();var e=this.templateVersion();this.$el.html(e({item:this.model,ldda:this.ldda}));$(".peek").html(this.ldda.get("peek"))},enableModification:function(){$(".tooltip").remove();var e=this.templateModifyDataset();this.$el.html(e({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},downloadDataset:function(){var e="/api/libraries/datasets/download/uncompressed";var f={ldda_ids:this.id};this.processDownload(e,f)},processDownload:function(f,g,h){if(f&&g){g=typeof g=="string"?g:$.param(g);var e="";$.each(g.split("&"),function(){var i=this.split("=");e+='<input type="hidden" name="'+i[0]+'" value="'+i[1]+'" />'});$('<form action="'+f+'" method="'+(h||"post")+'">'+e+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon")}},importIntoHistory:function(){this.refreshUserHistoriesList(function(e){var f=e.templateBulkImportInModal();e.modal=Galaxy.modal;e.modal.show({closing_events:true,title:"Import into History",body:f({histories:e.histories.models}),buttons:{Import:function(){e.importCurrentIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})},refreshUserHistoriesList:function(f){var e=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(g){if(g.length===0){d.warning("You have to create history first. Click this to do so.","",{onclick:function(){window.location="/"}})}else{f(e)}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg)}else{d.error("An error ocurred :(")}}})},importCurrentIntoHistory:function(){var e=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();var f=new c.HistoryItem();f.url=f.urlRoot+e+"/contents";jQuery.getJSON(galaxy_config.root+"history/set_as_current?id="+e);f.save({content:this.id,source:"library"},{success:function(){Galaxy.modal.hide();d.success("Dataset imported. Click this to start analysing it.","",{onclick:function(){window.location="/"}})},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error("Dataset not imported. "+g.responseJSON.err_msg)}else{d.error("An error occured! Dataset not imported. Please try again.")}}})},shareDataset:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(f){this.options=_.extend(this.options,f);$(".tooltip").remove();if(this.options.fetched_permissions!==undefined){if(this.options.fetched_permissions.access_dataset_roles.length===0){this.model.set({is_unrestricted:true})}else{this.model.set({is_unrestricted:false})}}var h=false;if(Galaxy.currUser){h=Galaxy.currUser.isAdmin()}var g=this.templateDatasetPermissions();this.$el.html(g({item:this.model,is_admin:h}));var e=this;if(this.options.fetched_permissions===undefined){$.get("/api/libraries/datasets/"+e.id+"/permissions?scope=current").done(function(i){e.prepareSelectBoxes({fetched_permissions:i,is_admin:h})}).fail(function(){d.error("An error occurred while fetching dataset permissions. :(")})}else{this.prepareSelectBoxes({is_admin:h})}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},prepareSelectBoxes:function(r){this.options=_.extend(this.options,r);var s=this.options.fetched_permissions;var k=this.options.is_admin;var q=this;var m=[];for(var h=0;h<s.access_dataset_roles.length;h++){m.push(s.access_dataset_roles[h]+":"+s.access_dataset_roles[h])}var f=[];for(var h=0;h<s.modify_item_roles.length;h++){f.push(s.modify_item_roles[h]+":"+s.modify_item_roles[h])}var g=[];for(var h=0;h<s.manage_dataset_roles.length;h++){g.push(s.manage_dataset_roles[h]+":"+s.manage_dataset_roles[h])}if(k){var o={minimumInputLength:0,css:"access_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#access_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:m.join(","),dropdownCssClass:"bigdrop"};var l={minimumInputLength:0,css:"modify_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#modify_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:f.join(","),dropdownCssClass:"bigdrop"};var p={minimumInputLength:0,css:"manage_perm",multiple:true,placeholder:"Click to select a role",container:q.$el.find("#manage_perm"),ajax:{url:"/api/libraries/datasets/"+q.id+"/permissions?scope=available",dataType:"json",quietMillis:100,data:function(i,t){return{q:i,page_limit:10,page:t}},results:function(u,t){var i=(t*10)<u.total;return{results:u.roles,more:i}}},formatResult:function j(i){return i.name+" type: "+i.type},formatSelection:function e(i){return i.name},initSelection:function(i,u){var t=[];$(i.val().split(",")).each(function(){var v=this.split(":");t.push({id:v[1],name:v[1]})});u(t)},initialData:g.join(","),dropdownCssClass:"bigdrop"};q.accessSelectObject=new b.View(o);q.modifySelectObject=new b.View(l);q.manageSelectObject=new b.View(p)}else{var n=q.templateAccessSelect();$.get("/api/libraries/datasets/"+q.id+"/permissions?scope=available",function(i){$(".access_perm").html(n({options:i.roles}));q.accessSelectObject=$("#access_select").select2()}).fail(function(){d.error("An error occurred while fetching data with permissions. :(")})}},comingSoon:function(){d.warning("Feature coming soon")},copyToClipboard:function(){var e=Backbone.history.location.href;if(e.lastIndexOf("/permissions")!==-1){e=e.substr(0,e.lastIndexOf("/permissions"))}window.prompt("Copy to clipboard: Ctrl+C, Enter",e)},makeDatasetPrivate:function(){var e=this;$.post("/api/libraries/datasets/"+e.id+"/permissions?action=make_private").done(function(f){e.model.set({is_unrestricted:false});e.showPermissions({fetched_permissions:f});d.success("The dataset is now private to you")}).fail(function(){d.error("An error occurred while making dataset private :(")})},removeDatasetRestrictions:function(){var e=this;$.post("/api/libraries/datasets/"+e.id+"/permissions?action=remove_restrictions").done(function(f){e.model.set({is_unrestricted:true});e.showPermissions({fetched_permissions:f});d.success("Access to this dataset is now unrestricted")}).fail(function(){d.error("An error occurred while making dataset unrestricted :(")})},savePermissions:function(e){var n=this;var k=this.accessSelectObject.$el.select2("data");var f=this.manageSelectObject.$el.select2("data");var m=this.modifySelectObject.$el.select2("data");var g=[];var j=[];var l=[];for(var h=k.length-1;h>=0;h--){g.push(k[h].id)}for(var h=f.length-1;h>=0;h--){j.push(f[h].id)}for(var h=m.length-1;h>=0;h--){l.push(m[h].id)}$.post("/api/libraries/datasets/"+n.id+"/permissions?action=set_permissions",{"access_ids[]":g,"manage_ids[]":j,"modify_ids[]":l,}).done(function(i){n.showPermissions({fetched_permissions:i});d.success("Permissions saved")}).fail(function(){d.error("An error occurred while setting dataset permissions :(")})},templateDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');e.push(' <% if (item.get("can_user_modify")) { %>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library item" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(" <% } %>");e.push(' <% if (item.get("can_user_manage")) { %>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Manage permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push(" <% } %>");e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<% if (item.get("is_unrestricted")) { %>');e.push(' <div class="alert alert-info">');e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"></span> To Clipboard</span></button> ');e.push(" </div>");e.push("<% } %>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push(' <% if (item.get("has_versions")) { %>');e.push(" <div>");e.push(" <h3>Expired versions:</h3>");e.push(" <ul>");e.push(' <% _.each(item.get("expired_versions"), function(version) { %>');e.push(' <li><a title="See details of this version" href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/versions/<%- version[0] %>"><%- version[1] %></a></li>');e.push(" <% }) %>");e.push(" <ul>");e.push(" </div>");e.push(" <% } %>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateVersion:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go to latest dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-caret-left fa-lg"></span> Latest dataset</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push(' <div class="alert alert-warning">This is an expired version of the library dataset: <%= _.escape(item.get("name")) %></div>');e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(ldda.id) %>">Name</th>');e.push(' <td><%= _.escape(ldda.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (ldda.get("file_ext")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(ldda.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(ldda.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(ldda.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(ldda.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(ldda.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (ldda.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(ldda.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateModifyDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push('<p>For more editing options please import the dataset to history and use "Edit attributes" on it.</p>');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><input class="input_dataset_name form-control" type="text" placeholder="name" value="<%= _.escape(item.get("name")) %>"></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("file_ext")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(' <tr scope="row">');e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <% if (item.get("metadata_comment_lines") === "") { %>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" <% } else { %>");e.push(' <td scope="row">unknown</td>');e.push(" <% } %>");e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" </table>");e.push("<div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push("</div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateDatasetPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to containing folder" class="btn btn-default primary-button" type="button"><span class="fa fa-folder-open-o"></span> Containing Folder</span></button></a>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go back to dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-file-o"></span> Dataset Details</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<h1>Dataset: <%= _.escape(item.get("name")) %></h1>');e.push('<div class="alert alert-warning">');e.push("<% if (is_admin) { %>");e.push("You are logged in as an <strong>administrator</strong> therefore you can manage any dataset on this Galaxy instance. Please make sure you understand the consequences.");e.push("<% } else { %>");e.push("You can assign any number of roles to any of the following permission types. However please read carefully the implications of such actions.");e.push("<% } %>");e.push("</div>");e.push('<div class="dataset_table">');e.push("<h2>Library-related permissions</h2>");e.push("<h4>Roles that can modify the library item</h4>");e.push('<div id="modify_perm" class="modify_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can modify name, metadata, and other information about this library item.</div>');e.push("<hr/>");e.push("<h2>Dataset-related permissions</h2>");e.push('<div class="alert alert-warning">Changes made below will affect <strong>every</strong> library item that was created from this dataset and also every history this dataset is part of.</div>');e.push('<% if (!item.get("is_unrestricted")) { %>');e.push(" <p>You can remove all access restrictions on this dataset. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Everybody will be able to access the dataset." class="btn btn-default btn-remove-restrictions primary-button" type="button">');e.push(' <span class="fa fa-globe"> Remove restrictions</span>');e.push(" </button>");e.push(" </p>");e.push("<% } else { %>");e.push(" This dataset is unrestricted so everybody can access it. Just share the URL of this page.");e.push(' <button data-toggle="tooltip" data-placement="top" title="Copy to clipboard" class="btn btn-default btn-copy-link-to-clipboard primary-button" type="button"><span class="fa fa-clipboard"> To Clipboard</span></button> ');e.push(" <p>You can make this dataset private to you. ");e.push(' <button data-toggle="tooltip" data-placement="top" title="Only you will be able to access the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"> Make Private</span></button>');e.push(" </p>");e.push("<% } %>");e.push("<h4>Roles that can access the dataset</h4>");e.push('<div id="access_perm" class="access_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User has to have <strong>all these roles</strong> in order to access this dataset. Users without access permission <strong>cannot</strong> have other permissions on this dataset. If there are no access roles set on the dataset it is considered <strong>unrestricted</strong>.</div>');e.push("<h4>Roles that can manage permissions on the dataset</h4>");e.push('<div id="manage_perm" class="manage_perm roles-selection"></div>');e.push('<div class="alert alert-info roles-selection">User with <strong>any</strong> of these roles can manage permissions of this dataset. If you remove yourself you will loose the ability manage this dataset unless you are an admin.</div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications made on this page" class="btn btn-default toolbtn_save_permissions primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateBulkImportInModal:function(){var e=[];e.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');e.push("Select history: ");e.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');e.push(" <% _.each(histories, function(history) { %>");e.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');e.push(" <% }); %>");e.push("</select>");e.push("</span>");return _.template(e.join(""))},templateAccessSelect:function(){var e=[];e.push('<select id="access_select" multiple>');e.push(" <% _.each(options, function(option) { %>");e.push(' <option value="<%- option.name %>"><%- option.name %></option>');e.push(" <% }); %>");e.push("</select>");return _.template(e.join(""))}});return{LibraryDatasetView:a}});
\ No newline at end of file
diff -r b05591d4a9631cb3d62a95e98153edc4c67ab395 -r 5ce55f9f2923dcdf27150cce3addd6e1ff3782d7 static/scripts/packed/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal","click #include_deleted_datasets_chk":"checkIncludeDeleted","click #toolbtn_show_libinfo":"showLibInfo","click #toolbtn_bulk_delete":"deleteSelectedDatasets"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(g){this.options=_.extend(this.options,g);var i=false;var f=true;if(Galaxy.currUser){i=Galaxy.currUser.isAdmin();f=Galaxy.currUser.isAnonymous()}var h=this.templateToolBar();this.$el.html(h({id:this.options.id,admin_user:i,anonym:f}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$(".add-library-items").show()}else{$(".add-library-items").hide()}if(this.options.contains_file===true){if(Galaxy.currUser){if(!Galaxy.currUser.isAnonymous()){$(".logged-dataset-manipulation").show();$(".dataset-manipulation").show()}else{$(".dataset-manipulation").show();$(".logged-dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var k=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=k;var n=$("select[name=dataset_import_bulk] option:selected").text();var p=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){p.push(this.parentElement.parentElement.id)}});var o=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(o({history_name:n}));var l=100/p.length;this.initProgress(l);var f=[];for(var h=p.length-1;h>=0;h--){var j=p[h];var m=new c.HistoryItem();m.url=m.urlRoot+k+"/contents";m.content=j;m.source="library";f.push(m)}this.options.chain_call_control.total_number=f.length;var g="/api/histories/"+k+"/set_as_current";$.ajax({url:g,type:"PUT"});this.chainCall(f,n)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history. Click this to start analysing it.","",{onclick:function(){window.location="/"}})}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history. Click this to see what was imported.","",{onclick:function(){window.location="/"}})}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();var h=f.options.full_path[f.options.full_path.length-1][1];f.modal.show({closing_events:true,title:"Add datasets from history to "+h,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(i){f.fetchAndDisplayHistoryContents(i.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(j,i){if(typeof i.responseJSON!=="undefined"){e.error(i.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},checkIncludeDeleted:function(f){if(f.target.checked){Galaxy.libraries.folderListView.fetchFolder({include_deleted:true})}else{Galaxy.libraries.folderListView.fetchFolder({include_deleted:false})}},deleteSelectedDatasets:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{var j=this.templateDeletingDatasetsProgressBar();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Deleting selected datasets",body:j({}),buttons:{Close:function(){Galaxy.modal.hide()}}});this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var g=[];f.each(function(){if(this.parentElement.parentElement.id!==""){g.push(this.parentElement.parentElement.id)}});this.progressStep=100/g.length;this.progress=0;var l=[];for(var h=g.length-1;h>=0;h--){var k=new c.Item({id:g[h]});l.push(k)}this.options.chain_call_control.total_number=g.length;this.chainCallDeletingHdas(l)}},chainCallDeletingHdas:function(g){var f=this;this.deleted_lddas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets deleted")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were deleted.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be deleted")}}}Galaxy.modal.hide();return this.deleted_lddas}var i=$.when(h.destroy());i.done(function(k){Galaxy.libraries.folderListView.collection.remove(h.id);f.updateProgress();if(Galaxy.libraries.folderListView.options.include_deleted){var j=new c.Item(k);Galaxy.libraries.folderListView.collection.add(j)}f.chainCallDeletingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallDeletingHdas(g)})},showLibInfo:function(){var g=Galaxy.libraries.folderListView.folderContainer.attributes.metadata.parent_library_id;var f=null;var h=this;if(Galaxy.libraries.libraryListView!==null){f=Galaxy.libraries.libraryListView.collection.get(g)}else{f=new c.Library({id:g});f.fetch({success:function(){var i=h.templateLibInfoInModal();h.modal=Galaxy.modal;h.modal.show({closing_events:true,title:"Library Information",body:i({library:f}),buttons:{Close:function(){Galaxy.modal.hide()}}})},error:function(j,i){if(typeof i.responseJSON!=="undefined"){e.error(i.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push(' <div id="library_toolbar">');tmpl_array.push(" <span><strong>DATA LIBRARIES</strong></span>");tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" class="logged-dataset-manipulation" title="Include deleted datasets" style="display:none;"> | <input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"> include deleted | </input></span>');tmpl_array.push(' <div class="btn-group add-library-items" style="display:none;">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button dataset-manipulation" style="margin-left: 0.5em; display:none;" type="button"><span class="fa fa-book"></span> to History</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group dataset-manipulation" style="margin-left: 0.5em; display:none; ">');tmpl_array.push(' <button title="Download selected datasets as archive" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> Download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button logged-dataset-manipulation" style="margin-left: 0.5em; display:none; " type="button"><span class="fa fa-times"></span> Delete</button>');tmpl_array.push(' <button data-id="<%- id %>" data-toggle="tooltip" data-placement="top" title="Show library information" id="toolbtn_show_libinfo" class="primary-button" style="margin-left: 0.5em;" type="button"><span class="fa fa-info-circle"></span> Library Info</button>');tmpl_array.push(' <span class="help-button" data-toggle="tooltip" data-placement="top" title="Visit Libraries Wiki"><a href="https://wiki.galaxyproject.org/DataLibraries/screen/FolderContents" target="_blank"><button class="primary-button btn-xs" type="button"><span class="fa fa-question-circle"></span> Help</button></a></span>');tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateLibInfoInModal:function(){tmpl_array=[];tmpl_array.push('<div id="lif_info_modal">');tmpl_array.push("<h2>Library name:</h2>");tmpl_array.push('<p><%- library.get("name") %></p>');tmpl_array.push("<h3>Library description:</h3>");tmpl_array.push('<p><%- library.get("description") %></p>');tmpl_array.push("<h3>Library synopsis:</h3>");tmpl_array.push('<p><%- library.get("synopsis") %></p>');tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateDeletingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-delete" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal","click #include_deleted_datasets_chk":"checkIncludeDeleted","click #toolbtn_show_libinfo":"showLibInfo","click #toolbtn_bulk_delete":"deleteSelectedDatasets"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(g){this.options=_.extend(this.options,g);var i=false;var f=true;if(Galaxy.currUser){i=Galaxy.currUser.isAdmin();f=Galaxy.currUser.isAnonymous()}var h=this.templateToolBar();this.$el.html(h({id:this.options.id,admin_user:i,anonym:f}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$(".add-library-items").show()}else{$(".add-library-items").hide()}if(this.options.contains_file===true){if(Galaxy.currUser){if(!Galaxy.currUser.isAnonymous()){$(".logged-dataset-manipulation").show();$(".dataset-manipulation").show()}else{$(".dataset-manipulation").show();$(".logged-dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(h){h.preventDefault();h.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var j=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=j;var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){o.push(this.parentElement.parentElement.id)}});var n=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(n({history_name:m}));var k=100/o.length;this.initProgress(k);var f=[];for(var g=o.length-1;g>=0;g--){var h=o[g];var l=new c.HistoryItem();l.url=l.urlRoot+j+"/contents";l.content=h;l.source="library";f.push(l)}this.options.chain_call_control.total_number=f.length;jQuery.getJSON(galaxy_config.root+"history/set_as_current?id="+historyId);this.chainCall(f,m)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history. Click this to start analysing it.","",{onclick:function(){window.location="/"}})}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history. Click this to see what was imported.","",{onclick:function(){window.location="/"}})}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();var h=f.options.full_path[f.options.full_path.length-1][1];f.modal.show({closing_events:true,title:"Add datasets from history to "+h,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(i){f.fetchAndDisplayHistoryContents(i.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(j,i){if(typeof i.responseJSON!=="undefined"){e.error(i.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},checkIncludeDeleted:function(f){if(f.target.checked){Galaxy.libraries.folderListView.fetchFolder({include_deleted:true})}else{Galaxy.libraries.folderListView.fetchFolder({include_deleted:false})}},deleteSelectedDatasets:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{var j=this.templateDeletingDatasetsProgressBar();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Deleting selected datasets",body:j({}),buttons:{Close:function(){Galaxy.modal.hide()}}});this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var g=[];f.each(function(){if(this.parentElement.parentElement.id!==""){g.push(this.parentElement.parentElement.id)}});this.progressStep=100/g.length;this.progress=0;var l=[];for(var h=g.length-1;h>=0;h--){var k=new c.Item({id:g[h]});l.push(k)}this.options.chain_call_control.total_number=g.length;this.chainCallDeletingHdas(l)}},chainCallDeletingHdas:function(g){var f=this;this.deleted_lddas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets deleted")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were deleted.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be deleted")}}}Galaxy.modal.hide();return this.deleted_lddas}var i=$.when(h.destroy());i.done(function(k){Galaxy.libraries.folderListView.collection.remove(h.id);f.updateProgress();if(Galaxy.libraries.folderListView.options.include_deleted){var j=new c.Item(k);Galaxy.libraries.folderListView.collection.add(j)}f.chainCallDeletingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallDeletingHdas(g)})},showLibInfo:function(){var g=Galaxy.libraries.folderListView.folderContainer.attributes.metadata.parent_library_id;var f=null;var h=this;if(Galaxy.libraries.libraryListView!==null){f=Galaxy.libraries.libraryListView.collection.get(g)}else{f=new c.Library({id:g});f.fetch({success:function(){var i=h.templateLibInfoInModal();h.modal=Galaxy.modal;h.modal.show({closing_events:true,title:"Library Information",body:i({library:f}),buttons:{Close:function(){Galaxy.modal.hide()}}})},error:function(j,i){if(typeof i.responseJSON!=="undefined"){e.error(i.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push(' <div id="library_toolbar">');tmpl_array.push(" <span><strong>DATA LIBRARIES</strong></span>");tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" class="logged-dataset-manipulation" title="Include deleted datasets" style="display:none;"> | <input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"> include deleted | </input></span>');tmpl_array.push(' <div class="btn-group add-library-items" style="display:none;">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button dataset-manipulation" style="margin-left: 0.5em; display:none;" type="button"><span class="fa fa-book"></span> to History</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group dataset-manipulation" style="margin-left: 0.5em; display:none; ">');tmpl_array.push(' <button title="Download selected datasets as archive" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> Download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button logged-dataset-manipulation" style="margin-left: 0.5em; display:none; " type="button"><span class="fa fa-times"></span> Delete</button>');tmpl_array.push(' <button data-id="<%- id %>" data-toggle="tooltip" data-placement="top" title="Show library information" id="toolbtn_show_libinfo" class="primary-button" style="margin-left: 0.5em;" type="button"><span class="fa fa-info-circle"></span> Library Info</button>');tmpl_array.push(' <span class="help-button" data-toggle="tooltip" data-placement="top" title="Visit Libraries Wiki"><a href="https://wiki.galaxyproject.org/DataLibraries/screen/FolderContents" target="_blank"><button class="primary-button btn-xs" type="button"><span class="fa fa-question-circle"></span> Help</button></a></span>');tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateLibInfoInModal:function(){tmpl_array=[];tmpl_array.push('<div id="lif_info_modal">');tmpl_array.push("<h2>Library name:</h2>");tmpl_array.push('<p><%- library.get("name") %></p>');tmpl_array.push("<h3>Library description:</h3>");tmpl_array.push('<p><%- library.get("description") %></p>');tmpl_array.push("<h3>Library synopsis:</h3>");tmpl_array.push('<p><%- library.get("synopsis") %></p>');tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateDeletingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-delete" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Quote commandline arguments for extract genomic DNA tool.
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b05591d4a963/
Changeset: b05591d4a963
User: dan
Date: 2014-09-02 19:15:17
Summary: Quote commandline arguments for extract genomic DNA tool.
Affected #: 1 file
diff -r 38f8adbf6a47aa05b64c8dd46ee828c36628df31 -r b05591d4a9631cb3d62a95e98153edc4c67ab395 tools/extract/extract_genomic_dna.xml
--- a/tools/extract/extract_genomic_dna.xml
+++ b/tools/extract/extract_genomic_dna.xml
@@ -1,7 +1,7 @@
<tool id="Extract genomic DNA 1" name="Extract Genomic DNA" version="2.2.3"><description>using coordinates from assembled/unassembled genomes</description><command interpreter="python">
- extract_genomic_dna.py $input $out_file1 -o $out_format -d $dbkey
+ extract_genomic_dna.py "${input}" "${out_file1}" -o "${out_format}" -d "${dbkey}"
#if str( $interpret_features ) == "yes":
-I
@@ -9,17 +9,17 @@
## Columns to use in input file.
#if isinstance( $input.datatype, $__app__.datatypes_registry.get_datatype_by_extension('gff').__class__):
- -1 1,4,5,7 --gff
+ -1 "1,4,5,7" --gff
#else:
- -1 ${input.metadata.chromCol},${input.metadata.startCol},${input.metadata.endCol},${input.metadata.strandCol},${input.metadata.nameCol}
+ -1 "${input.metadata.chromCol},${input.metadata.startCol},${input.metadata.endCol},${input.metadata.strandCol},${input.metadata.nameCol}"
#end if
#if $seq_source.index_source == "cached":
## Genomic data from cache.
- -g ${GALAXY_DATA_INDEX_DIR}
+ -g "${GALAXY_DATA_INDEX_DIR}"
#else:
## Genomic data from history.
- -F $seq_source.ref_file
+ -F "${seq_source.ref_file}"
#end if
</command><inputs>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Fix for custom dbkeys when chrom count dataset has been deleted.
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/38f8adbf6a47/
Changeset: 38f8adbf6a47
User: dan
Date: 2014-09-02 18:50:37
Summary: Fix for custom dbkeys when chrom count dataset has been deleted.
Affected #: 1 file
diff -r d8eccdf88c8090e7237dca11502c5c62b3388bc0 -r 38f8adbf6a47aa05b64c8dd46ee828c36628df31 lib/galaxy/webapps/galaxy/controllers/user.py
--- a/lib/galaxy/webapps/galaxy/controllers/user.py
+++ b/lib/galaxy/webapps/galaxy/controllers/user.py
@@ -1680,9 +1680,12 @@
continue
else:
# Set chrom count.
- chrom_count = int( open( chrom_count_dataset.file_name ).readline() )
- attributes[ 'count' ] = chrom_count
- updated = True
+ try:
+ chrom_count = int( open( chrom_count_dataset.file_name ).readline() )
+ attributes[ 'count' ] = chrom_count
+ updated = True
+ except Exception, e:
+ log.error( "Failed to open chrom count dataset: %s", e )
if updated:
user.preferences['dbkeys'] = to_json_string(dbkeys)
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Small improvements to JavaScript testing with run_tests.sh.
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d8eccdf88c80/
Changeset: d8eccdf88c80
User: jmchilton
Date: 2014-09-02 18:35:33
Summary: Small improvements to JavaScript testing with run_tests.sh.
Add new -j|--casperjs option to run through the casperjs test suite. Ensure grunt is on path before attempting to run qunit tests. A more useful version of this changeset which automatically installed phantomjs, casperjs, grunt, and npm as needed and added the required tools to the tester's path (https://bitbucket.org/jmchilton/galaxy-central-fork-1/commits/0919fc9403933…) proved unpopular because of implementation details - see conversation here https://bitbucket.org/galaxy/galaxy-central/pull-request/461/remove-depreca….
Affected #: 2 files
diff -r 7f729ff2483d6aed19100542e102f14e3f2f11b1 -r d8eccdf88c8090e7237dca11502c5c62b3388bc0 run_tests.sh
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -31,6 +31,19 @@
echo "'${0##*/} -sid ccc' for testing one section with sid 'ccc' ('ccc' is the string after 'section::')"
}
+exists() {
+ type "$1" >/dev/null 2>/dev/null
+}
+
+ensure_grunt() {
+ if ! exists "grunt";
+ then
+ echo "Grunt not on path, cannot run these tests."
+ exit 1
+ fi
+}
+
+
test_script="./scripts/functional_tests.py"
report_file="run_functional_tests.html"
with_framework_test_tools_arg=""
@@ -110,6 +123,12 @@
data_managers_test=1;
shift 1
;;
+ -j|-casperjs|--casperjs)
+ # TODO: Support running casper tests against existing
+ # Galaxy instances.
+ casperjs_test=1;
+ shift
+ ;;
-m|-migrated|--migrated)
migrated_test=1;
shift
@@ -196,6 +215,11 @@
extra_args="$toolshed_script"
elif [ -n "$api_script" ]; then
extra_args="$api_script"
+elif [ -n "$casperjs_test" ]; then
+ # TODO: Ensure specific versions of casperjs and phantomjs are
+ # available. Some option for leveraging npm to automatically
+ # install these dependencies would be nice as well.
+ extra_args="test/casperjs/casperjs_runner.py"
elif [ -n "$section_id" ]; then
extra_args=`python tool_list.py $section_id`
elif [ -n "$test_id" ]; then
@@ -212,6 +236,7 @@
if [ "$driver" = "python" ]; then
python $test_script $coverage_arg -v --with-nosehtml --html-report-file $report_file $with_framework_test_tools_arg $extra_args
else
+ ensure_grunt
if [ -n "$watch" ]; then
grunt_task="watch"
else
diff -r 7f729ff2483d6aed19100542e102f14e3f2f11b1 -r d8eccdf88c8090e7237dca11502c5c62b3388bc0 test/casperjs/casperjs_runner.py
--- a/test/casperjs/casperjs_runner.py
+++ b/test/casperjs/casperjs_runner.py
@@ -6,8 +6,9 @@
* casperjs test mytests.js --url='http://localhost:8080'
* python casperjs_runner.py
* nosetests
-* sh run_functional_tests.sh test/casperjs/casperjs_runner.py
-* sh run_functional_tests.sh
+* sh run_tests.sh -j
+* sh run_tests.sh test/casperjs/casperjs_runner.py
+* sh run_tests.sh
Note: that you can enable (lots of) debugging info using cli options:
* casperjs test api-user-tests.js --url='http://localhost:8080' --verbose=true --logLevel=debug
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6b26b7df6924/
Changeset: 6b26b7df6924
User: jmchilton
Date: 2014-09-02 17:50:43
Summary: Remove deprecated test running scripts.
- run_functional_tests.sh can be replaced with the backward compatible run_tests.sh.
- run_unit_tests.sh can be replaced with `run_tests.sh --unit` (or just -u)
- run_tool_shed_functional_tests.sh can be replaced with `./run_tests.sh -toolshed` (or just -t).
In each case run_tests.sh provides better documentation and superior argument parsing.
Affected #: 3 files
diff -r d3e72ceda152bd813cca2ca676a6ad1f3e7deb5a -r 6b26b7df6924de890ee547f96f939fcd73cfe60b run_functional_tests.sh
--- a/run_functional_tests.sh
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/bin/sh
-
-# A good place to look for nose info: http://somethingaboutorange.com/mrl/projects/nose/
-rm -f run_functional_tests.log
-
-if [ ! $1 ]; then
- python ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html --exclude="^get" functional
-elif [ $1 = 'help' ]; then
- echo "'run_functional_tests.sh' for testing all the tools in functional directory"
- echo "'run_functional_tests.sh aaa' for testing one test case of 'aaa' ('aaa' is the file name with path)"
- echo "'run_functional_tests.sh -id bbb' for testing one tool with id 'bbb' ('bbb' is the tool id)"
- echo "'run_functional_tests.sh -sid ccc' for testing one section with sid 'ccc' ('ccc' is the string after 'section::')"
- echo "'run_functional_tests.sh -api' for running API functional tests"
- echo "'run_functional_tests.sh -list' for listing all the tool ids"
- echo "'run_functional_tests.sh -toolshed' for running all the test scripts in the ./test/tool_shed/functional directory"
- echo "'run_functional_tests.sh -toolshed testscriptname' for running one test script named testscriptname in the .test/tool_shed/functional directory"
- echo "'run_functional_tests.sh -workflow test.xml' for running a workflow test case as defined by supplied workflow xml test file"
- echo "'run_functional_tests.sh -framework' for running through example tool tests testing framework features in test/functional/tools"
- echo "'run_functional_tests.sh -framework -id toolid' for testing one framework tool (in test/functional/tools/) with id 'toolid'"
- echo "'run_functional_tests.sh -data_managers -id data_manager_id' for testing one Data Manager with id 'data_manager_id'"
-elif [ $1 = '-id' ]; then
- python ./scripts/functional_tests.py -v functional.test_toolbox:TestForTool_$2 --with-nosehtml --html-report-file run_functional_tests.html
-elif [ $1 = '-sid' ]; then
- python ./scripts/functional_tests.py --with-nosehtml --html-report-file run_functional_tests.html -v `python tool_list.py $2`
-elif [ $1 = '-list' ]; then
- python tool_list.py
- echo "==========================================================================================================================================="
- echo "'run_functional_tests.sh -id bbb' for testing one tool with id 'bbb' ('bbb' is the tool id)"
- echo "'run_functional_tests.sh -sid ccc' for testing one section with sid 'ccc' ('ccc' is the string after 'section::')"
-elif [ $1 = '-migrated' ]; then
- if [ ! $2 ]; then
- python ./scripts/functional_tests.py -v functional.test_toolbox --with-nosehtml --html-report-file run_functional_tests.html -migrated
- elif [ $2 = '-id' ]; then
- # TODO: This option is not tested...
- python ./scripts/functional_tests.py -v functional.test_toolbox:TestForTool_$3 --with-nosehtml --html-report-file run_functional_tests.html -migrated
- else
- python ./scripts/functional_tests.py -v functional.test_toolbox --with-nosehtml --html-report-file run_functional_tests.html -migrated
- fi
-elif [ $1 = '-installed' ]; then
- if [ ! $2 ]; then
- python ./scripts/functional_tests.py -v functional.test_toolbox --with-nosehtml --html-report-file run_functional_tests.html -installed
- elif [ $2 = '-id' ]; then
- # TODO: This option is not tested...
- python ./scripts/functional_tests.py -v functional.test_toolbox:TestForTool_$3 --with-nosehtml --html-report-file run_functional_tests.html -installed
- else
- python ./scripts/functional_tests.py -v functional.test_toolbox --with-nosehtml --html-report-file run_functional_tests.html -installed
- fi
-elif [ $1 = '-toolshed' ]; then
- if [ ! $2 ]; then
- python ./test/tool_shed/functional_tests.py -v --with-nosehtml --html-report-file ./test/tool_shed/run_functional_tests.html ./test/tool_shed/functional
- else
- python ./test/tool_shed/functional_tests.py -v --with-nosehtml --html-report-file ./test/tool_shed/run_functional_tests.html $2
- fi
-elif [ $1 = '-api' ]; then
- if [ ! $2 ]; then
- python ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_api_tests.html ./test/api
- else
- python ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_api_tests.html $2
- fi
-elif [ $1 = '-workflow' ]; then
- python ./scripts/functional_tests.py -v functional.workflow:WorkflowTestCase --with-nosehtml --html-report-file ./test/tool_shed/run_functional_tests.html -workflow $2
-elif [ $1 = '-data_managers' ]; then
- if [ ! $2 ]; then
- python ./scripts/functional_tests.py -v functional.test_data_managers --with-nosehtml --html-report-file run_functional_tests.html -data_managers
- elif [ $2 = '-id' ]; then
- python ./scripts/functional_tests.py -v functional.test_data_managers:TestForDataManagerTool_$3 --with-nosehtml --html-report-file run_functional_tests.html -data_managers
- else
- python ./scripts/functional_tests.py -v functional.test_data_managers --with-nosehtml --html-report-file run_functional_tests.html -data_managers
- fi
-elif [ $1 = '-framework' ]; then
- if [ ! $2 ]; then
- python ./scripts/functional_tests.py -v functional.test_toolbox --with-nosehtml --html-report-file run_functional_tests.html -framework
- elif [ $2 = '-id' ]; then
- python ./scripts/functional_tests.py -v functional.test_toolbox:TestForTool_$3 --with-nosehtml --html-report-file run_functional_tests.html -framework
- else
- echo "Invalid test option selected, if -framework first argument to $0, optional second argument must be -id followed a tool id."
- fi
-else
- python ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html $1
-fi
-
-echo "'run_functional_tests.sh help' for help"
diff -r d3e72ceda152bd813cca2ca676a6ad1f3e7deb5a -r 6b26b7df6924de890ee547f96f939fcd73cfe60b run_tool_shed_functional_tests.sh
--- a/run_tool_shed_functional_tests.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-# A good place to look for nose info: http://somethingaboutorange.com/mrl/projects/nose/
-#rm -f ./test/tool_shed/run_functional_tests.log
-
-if [ ! $1 ]; then
- python ./test/tool_shed/functional_tests.py -v --with-nosehtml --html-report-file ./test/tool_shed/run_functional_tests.html ./test/tool_shed/functional
-elif [ $1 = 'help' ]; then
- echo "'run_tool_shed_functional_tests.sh' for running all the test scripts in the ./test/tool_shed/functional directory"
- echo "'run_tool_shed_functional_tests.sh testscriptname' for running one test script named testscriptname in the .test/tool_shed/functional directory"
-else
- python ./test/tool_shed/functional_tests.py -v --with-nosehtml --html-report-file ./test/tool_shed/run_functional_tests.html $1
-fi
-
-echo "'sh run_tool_shed_functional_tests.sh help' for help"
diff -r d3e72ceda152bd813cca2ca676a6ad1f3e7deb5a -r 6b26b7df6924de890ee547f96f939fcd73cfe60b run_unit_tests.sh
--- a/run_unit_tests.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-## Excluding controllers due to the problematic genetrack dependency
-## Excluding job runners due to various external dependencies
-
-COVERAGE=`which coverage`
-COVERAGE_ARG=""
-if [ $COVERAGE ]; then
- COVERAGE_ARG="--with-coverage"
-fi
-
-python ./scripts/nosetests.py -v \
- $COVERAGE_ARG \
- --with-nosehtml --html-report-file run_unit_tests.html \
- --with-doctest --exclude=functional --exclude="^get" \
- --exclude=controllers --exclude=runners lib test/unit
https://bitbucket.org/galaxy/galaxy-central/commits/7f729ff2483d/
Changeset: 7f729ff2483d
User: jmchilton
Date: 2014-09-02 17:50:43
Summary: Fixup comments and add README for test/casperjs directory.
Affected #: 2 files
diff -r 6b26b7df6924de890ee547f96f939fcd73cfe60b -r 7f729ff2483d6aed19100542e102f14e3f2f11b1 test/casperjs/README.txt
--- /dev/null
+++ b/test/casperjs/README.txt
@@ -0,0 +1,4 @@
+This directory contains the Galaxy framework written by Carl Eberhard
+for running headless browser tests using CasperJS and PhantomJS.
+
+See notes at the top of casperjs_runner.py for more information.
diff -r 6b26b7df6924de890ee547f96f939fcd73cfe60b -r 7f729ff2483d6aed19100542e102f14e3f2f11b1 test/casperjs/casperjs_runner.py
--- a/test/casperjs/casperjs_runner.py
+++ b/test/casperjs/casperjs_runner.py
@@ -6,16 +6,16 @@
* casperjs test mytests.js --url='http://localhost:8080'
* python casperjs_runner.py
* nosetests
-* sh run_functional_tests.sh test/casperjs/test_runner
+* sh run_functional_tests.sh test/casperjs/casperjs_runner.py
* sh run_functional_tests.sh
Note: that you can enable (lots of) debugging info using cli options:
-* casperjs test usertests.js --url='http://localhost:8080' --verbose=true --logLevel=debug
+* casperjs test api-user-tests.js --url='http://localhost:8080' --verbose=true --logLevel=debug
(see casperjs.org for more information)
-Note: This seems to not work with CasperJS 1.1 (and PhantomJS 1.9) - Casper 1.0.xx and
-PhantomJS 1.8 work for me (John).
+Note: This works with CasperJS 1.1 and PhantomJS 1.9.2 and these libraries seem to break backward
+compatbility a lot.
Note: You can pass in extra data using --data='<some JSON object>'
and it will be available in your script as spaceghost.fixtureData.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: next chunk of API managers - libs, folders, roles
by commits-noreply@bitbucket.org 02 Sep '14
by commits-noreply@bitbucket.org 02 Sep '14
02 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d3e72ceda152/
Changeset: d3e72ceda152
User: martenson
Date: 2014-09-02 16:37:14
Summary: next chunk of API managers - libs, folders, roles
Affected #: 5 files
diff -r 188aa379bd9b25322e8532da73fae6dcece47231 -r d3e72ceda152bd813cca2ca676a6ad1f3e7deb5a lib/galaxy/managers/folders.py
--- a/lib/galaxy/managers/folders.py
+++ b/lib/galaxy/managers/folders.py
@@ -38,9 +38,7 @@
raise exceptions.RequestParameterInvalidException( 'No folder found with the id provided.' )
except Exception, e:
raise exceptions.InternalServerError( 'Error loading from the database.' + str( e ) )
-
folder = self.secure( trans, folder, check_ownership, check_accessible )
-
return folder
def secure( self, trans, folder, check_ownership=True, check_accessible=True ):
@@ -94,7 +92,7 @@
:param folder: folder item
:type folder: LibraryFolder
- :returns: dict with data about the new folder
+ :returns: dict with data about the folder
:rtype: dictionary
"""
@@ -153,8 +151,33 @@
manage_roles = set( trans.app.security_agent.get_roles_for_action( folder, trans.app.security_agent.permitted_actions.LIBRARY_MANAGE ) )
add_roles = set( trans.app.security_agent.get_roles_for_action( folder, trans.app.security_agent.permitted_actions.LIBRARY_ADD ) )
- modify_folder_role_list = [ modify_role.name for modify_role in modify_roles ]
- manage_folder_role_list = [ manage_role.name for manage_role in manage_roles ]
- add_library_item_role_list = [ add_role.name for add_role in add_roles ]
+ modify_folder_role_list = [ ( modify_role.name, trans.security.encode_id( modify_role.id ) ) for modify_role in modify_roles ]
+ manage_folder_role_list = [ ( manage_role.name, trans.security.encode_id( manage_role.id ) ) for manage_role in manage_roles ]
+ add_library_item_role_list = [ ( add_role.name, trans.security.encode_id( add_role.id ) ) for add_role in add_roles ]
+ return dict( modify_folder_role_list=modify_folder_role_list, manage_folder_role_list=manage_folder_role_list, add_library_item_role_list=add_library_item_role_list )
- return dict( modify_folder_role_list=modify_folder_role_list, manage_folder_role_list=manage_folder_role_list, add_library_item_role_list=add_library_item_role_list )
+ def cut_the_prefix( self, encoded_folder_id ):
+ """
+ Remove the prefix from the encoded folder id.
+ """
+ if ( ( len( encoded_folder_id ) % 16 == 1 ) and encoded_folder_id.startswith( 'F' ) ):
+ cut_id = encoded_folder_id[ 1: ]
+ else:
+ raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( encoded_id ) )
+ return cut_id
+
+ def decode_folder_id( self, trans, encoded_folder_id ):
+ """
+ Decode the folder id given that it has already lost the prefixed 'F'.
+ """
+ try:
+ decoded_id = trans.security.decode_id( encoded_folder_id )
+ except ValueError:
+ raise exceptions.MalformedId( "Malformed folder id ( %s ) specified, unable to decode" % ( str( encoded_folder_id ) ) )
+ return decoded_id
+
+ def cut_and_decode( self, trans, encoded_folder_id ):
+ """
+ Cuts the folder prefix (the prepended 'F') and returns the decoded id.
+ """
+ return self.decode_folder_id( trans, self.cut_the_prefix( encoded_folder_id ) )
diff -r 188aa379bd9b25322e8532da73fae6dcece47231 -r d3e72ceda152bd813cca2ca676a6ad1f3e7deb5a lib/galaxy/managers/libraries.py
--- /dev/null
+++ b/lib/galaxy/managers/libraries.py
@@ -0,0 +1,244 @@
+"""
+Manager and Serializer for libraries.
+"""
+
+import galaxy.web
+from galaxy import exceptions
+from galaxy.model import orm
+from galaxy.managers import base as manager_base
+from sqlalchemy.orm.exc import MultipleResultsFound
+from sqlalchemy.orm.exc import NoResultFound
+
+import logging
+log = logging.getLogger( __name__ )
+
+
+# =============================================================================
+class LibraryManager( object ):
+ """
+ Interface/service object for interacting with libraries.
+ """
+
+ def __init__( self, *args, **kwargs ):
+ super( LibraryManager, self ).__init__( *args, **kwargs )
+
+ def get( self, trans, decoded_library_id, check_accessible=True ):
+ """
+ Get the library from the DB.
+
+ :param decoded_library_id: decoded library id
+ :type decoded_library_id: int
+ :param check_accessible: flag whether to check that user can access item
+ :type check_accessible: bool
+
+ :returns: the requested library
+ :rtype: Library
+ """
+ try:
+ library = trans.sa_session.query( trans.app.model.Library ).filter( trans.app.model.Library.table.c.id == decoded_library_id ).one()
+ except MultipleResultsFound:
+ raise exceptions.InconsistentDatabase( 'Multiple libraries found with the same id.' )
+ except NoResultFound:
+ raise exceptions.RequestParameterInvalidException( 'No library found with the id provided.' )
+ except Exception, e:
+ raise exceptions.InternalServerError( 'Error loading from the database.' + str( e ) )
+ library = self.secure( trans, library, check_accessible)
+ return library
+
+ def create( self, trans, name, description='', synopsis=''):
+ """
+ Create a new library.
+ """
+ if not trans.user_is_admin:
+ raise exceptions.ItemAccessibilityException( 'Only administrators can create libraries.' )
+ else:
+ library = trans.app.model.Library( name=name, description=description, synopsis=synopsis )
+ root_folder = trans.app.model.LibraryFolder( name=name, description='' )
+ library.root_folder = root_folder
+ trans.sa_session.add_all( ( library, root_folder ) )
+ trans.sa_session.flush()
+ return library
+
+ def update( self, trans, library, name=None, description=None, synopsis=None ):
+ """
+ Update the given library
+ """
+ changed = False
+ if not trans.user_is_admin():
+ raise exceptions.ItemAccessibilityException( 'Only administrators can update libraries.' )
+ if library.deleted:
+ raise exceptions.RequestParameterInvalidException( 'You cannot modify a deleted library. Undelete it first.' )
+ if name is not None:
+ library.name = name
+ changed = True
+ if description is not None:
+ library.description = description
+ changed = True
+ if synopsis is not None:
+ library.synopsis = synopsis
+ changed = True
+ if changed:
+ trans.sa_session.add( library )
+ trans.sa_session.flush()
+ return library
+
+ def delete( self, trans, library, undelete=False ):
+ """
+ Mark given library deleted/undeleted based on the flag.
+ """
+ if not trans.user_is_admin():
+ raise exceptions.ItemAccessibilityException( 'Only administrators can delete and undelete libraries.' )
+ if undelete:
+ library.deleted = False
+ else:
+ library.deleted = True
+ trans.sa_session.add( library )
+ trans.sa_session.flush()
+ return library
+
+ def list( self, trans, deleted=False ):
+ """
+ Return a list of libraries from the DB.
+
+ :param deleted: if True, show only ``deleted`` libraries, if False show only ``non-deleted``
+ :type deleted: boolean (optional)
+ """
+ is_admin = trans.user_is_admin()
+ query = trans.sa_session.query( trans.app.model.Library )
+
+ if is_admin:
+ if deleted is None:
+ # Flag is not specified, do not filter on it.
+ pass
+ elif deleted:
+ query = query.filter( trans.app.model.Library.table.c.deleted == True )
+ else:
+ query = query.filter( trans.app.model.Library.table.c.deleted == False )
+ else:
+ # Nonadmins can't see deleted libraries
+ current_user_role_ids = [ role.id for role in trans.get_current_user_roles() ]
+ library_access_action = trans.app.security_agent.permitted_actions.LIBRARY_ACCESS.action
+ restricted_library_ids = [ lp.library_id for lp in ( trans.sa_session.query( trans.model.LibraryPermissions )
+ .filter( trans.model.LibraryPermissions.table.c.action == library_access_action )
+ .distinct() ) ]
+ accessible_restricted_library_ids = [ lp.library_id for lp in ( trans.sa_session.query( trans.model.LibraryPermissions )
+ .filter( and_( trans.model.LibraryPermissions.table.c.action == library_access_action,
+ trans.model.LibraryPermissions.table.c.role_id.in_( current_user_role_ids ) ) ) ) ]
+ query = query.filter( or_( not_( trans.model.Library.table.c.id.in_( restricted_library_ids ) ), trans.model.Library.table.c.id.in_( accessible_restricted_library_ids ) ) )
+ return query
+
+ def secure( self, trans, library, check_accessible=True ):
+ """
+ Check if library is accessible to user.
+
+ :param folder: library
+ :type folder: Library
+ :param check_accessible: flag whether to check that user can access library
+ :type check_accessible: bool
+
+ :returns: the original folder
+ :rtype: LibraryFolder
+ """
+ # all libraries are accessible to an admin
+ if trans.user_is_admin():
+ return library
+ if check_accessible:
+ library = self.check_accessible( trans, library )
+ return library
+
+ def check_accessible( self, trans, library ):
+ """
+ Check whether the library is accessible to current user.
+ """
+ if not trans.app.security_agent.can_access_library( trans.get_current_user_roles(), library ):
+ raise exceptions.ObjectNotFound( 'Library with the id provided was not found.' )
+ elif library.deleted:
+ raise exceptions.ObjectNotFound( 'Library with the id provided is deleted.' )
+ else:
+ return library
+
+ def get_library_dict( self, trans, library ):
+ """
+ Return library data in the form of a dictionary.
+
+ :param library: library
+ :type library: Library
+
+ :returns: dict with data about the library
+ :rtype: dictionary
+ """
+ library_dict = library.to_dict( view='element', value_mapper={ 'id': trans.security.encode_id, 'root_folder_id': trans.security.encode_id } )
+ if trans.app.security_agent.library_is_public( library, contents=False ):
+ library_dict[ 'public' ] = True
+ current_user_roles = trans.get_current_user_roles()
+ if not trans.user_is_admin():
+ library_dict[ 'can_user_add' ] = trans.app.security_agent.can_add_library_item( current_user_roles, library )
+ library_dict[ 'can_user_modify' ] = trans.app.security_agent.can_modify_library_item( current_user_roles, library )
+ library_dict[ 'can_user_manage' ] = trans.app.security_agent.can_manage_library_item( current_user_roles, library )
+ else:
+ library_dict[ 'can_user_add' ] = True
+ library_dict[ 'can_user_modify' ] = True
+ library_dict[ 'can_user_manage' ] = True
+ return library_dict
+
+ def get_current_roles( self, trans, library ):
+ """
+ Load all permissions currently related to the given library.
+
+ :param library: the model object
+ :type library: Library
+
+ :rtype: dictionary
+ :returns: dict of current roles for all available permission types
+ """
+ access_library_role_list = [ ( access_role.name, trans.security.encode_id( access_role.id ) ) for access_role in self.get_access_roles( trans, library ) ]
+ modify_library_role_list = [ ( modify_role.name, trans.security.encode_id( modify_role.id ) ) for modify_role in self.get_modify_roles( trans, library ) ]
+ manage_library_role_list = [ ( manage_role.name, trans.security.encode_id( manage_role.id ) ) for manage_role in self.get_manage_roles( trans, library ) ]
+ add_library_item_role_list = [ ( add_role.name, trans.security.encode_id( add_role.id ) ) for add_role in self.get_add_roles( trans, library ) ]
+ return dict( access_library_role_list=access_library_role_list,
+ modify_library_role_list=modify_library_role_list,
+ manage_library_role_list=manage_library_role_list,
+ add_library_item_role_list=add_library_item_role_list )
+
+ def get_access_roles( self, trans, library ):
+ """
+ Load access roles for all library permissions
+ """
+ return set( library.get_access_roles( trans ) )
+
+ def get_modify_roles( self, trans, library ):
+ """
+ Load modify roles for all library permissions
+ """
+ return set( trans.app.security_agent.get_roles_for_action( library, trans.app.security_agent.permitted_actions.LIBRARY_MODIFY ) )
+
+ def get_manage_roles( self, trans, library ):
+ """
+ Load manage roles for all library permissions
+ """
+ return set( trans.app.security_agent.get_roles_for_action( library, trans.app.security_agent.permitted_actions.LIBRARY_MANAGE ) )
+
+ def get_add_roles( self, trans, library ):
+ """
+ Load add roles for all library permissions
+ """
+ return set( trans.app.security_agent.get_roles_for_action( library, trans.app.security_agent.permitted_actions.LIBRARY_ADD ) )
+
+ def set_permission_roles( self, trans, library, access_roles, modify_roles, manage_roles, add_roles ):
+ """
+ Set permissions on the given library.
+ """
+
+ def make_public( self, trans, library ):
+ """
+ Makes the given library public (removes all access roles)
+ """
+ trans.app.security_agent.make_library_public( library )
+ return self.is_public( trans, library )
+
+ def is_public( self, trans, library ):
+ """
+ Return true if lib is public.
+ """
+ return trans.app.security_agent.library_is_public( library )
+
diff -r 188aa379bd9b25322e8532da73fae6dcece47231 -r d3e72ceda152bd813cca2ca676a6ad1f3e7deb5a lib/galaxy/managers/roles.py
--- /dev/null
+++ b/lib/galaxy/managers/roles.py
@@ -0,0 +1,41 @@
+"""
+Manager and Serializer for Roles.
+"""
+
+import galaxy.web
+from galaxy import exceptions
+from galaxy.model import orm
+from sqlalchemy.orm.exc import MultipleResultsFound
+from sqlalchemy.orm.exc import NoResultFound
+
+import logging
+log = logging.getLogger( __name__ )
+
+
+# =============================================================================
+class RoleManager( object ):
+ """
+ Interface/service object for interacting with folders.
+ """
+
+ def get( self, trans, decoded_role_id):
+ """
+ Method loads the role from the DB based on the given role id.
+
+ :param decoded_role_id: id of the role to load from the DB
+ :type decoded_role_id: int
+
+ :returns: the loaded Role object
+ :rtype: Role
+
+ :raises: InconsistentDatabase, RequestParameterInvalidException, InternalServerError
+ """
+ try:
+ role = trans.sa_session.query( trans.app.model.Role ).filter( trans.model.Role.table.c.id == decoded_role_id ).one()
+ except MultipleResultsFound:
+ raise exceptions.InconsistentDatabase( 'Multiple roles found with the same id.' )
+ except NoResultFound:
+ raise exceptions.RequestParameterInvalidException( 'No role found with the id provided.' )
+ except Exception, e:
+ raise exceptions.InternalServerError( 'Error loading from the database.' + str(e) )
+ return role
diff -r 188aa379bd9b25322e8532da73fae6dcece47231 -r d3e72ceda152bd813cca2ca676a6ad1f3e7deb5a lib/galaxy/webapps/galaxy/api/folders.py
--- a/lib/galaxy/webapps/galaxy/api/folders.py
+++ b/lib/galaxy/webapps/galaxy/api/folders.py
@@ -1,5 +1,5 @@
"""
-API operations on library folders
+API operations on library folders.
"""
from galaxy import util
from galaxy import web
@@ -43,7 +43,8 @@
:returns: dictionary including details of the folder
:rtype: dict
"""
- folder = self.folder_manager.get( trans, self.__cut_and_decode( trans, id ), check_ownership=False, check_accessible=True )
+ folder_id = self.folder_manager.cut_and_decode( trans, id )
+ folder = self.folder_manager.get( trans, folder_id, check_ownership=False, check_accessible=True )
return_dict = self.folder_manager.get_folder_dict( trans, folder )
return return_dict
@@ -77,7 +78,7 @@
if name is None:
raise exceptions.RequestParameterMissingException( "Missing required parameter 'name'." )
description = payload.get( 'description', '' )
- decoded_parent_folder_id = self.__cut_and_decode( trans, encoded_parent_folder_id )
+ decoded_parent_folder_id = self.folder_manager.cut_and_decode( trans, encoded_parent_folder_id )
parent_folder = self.folder_manager.get( trans, decoded_parent_folder_id )
new_folder = self.folder_manager.create( trans, parent_folder.id, name, description )
return self.folder_manager.get_folder_dict( trans, new_folder )
@@ -102,8 +103,7 @@
"""
current_user_roles = trans.get_current_user_roles()
is_admin = trans.user_is_admin()
- encoded_folder_id = self.__cut_the_prefix( encoded_folder_id )
- decoded_folder_id = self.__decode_folder_id( trans, encoded_folder_id )
+ decoded_folder_id = self.folder_manager.cut_and_decode( trans, encoded_folder_id )
folder = self.folder_manager.get( trans, decoded_folder_id )
if not ( is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, folder ) ):
@@ -128,7 +128,8 @@
roles, total_roles = trans.app.security_agent.get_valid_roles( trans, folder, query, page, page_limit )
return_roles = []
for role in roles:
- return_roles.append( dict( id=role.name, name=role.name, type=role.type ) )
+ role_id = trans.security.encode_id( role.id )
+ return_roles.append( dict( id=role_id, name=role.name, type=role.type ) )
return dict( roles=return_roles, page=page, page_limit=page_limit, total=total_roles )
else:
raise exceptions.RequestParameterInvalidException( "The value of 'scope' parameter is invalid. Alllowed values: current, available" )
@@ -146,15 +147,15 @@
available actions: set_permissions
:type action: string
- :param add_ids[]: list of Role.name defining roles that should have add item permission on the folder
+ :param add_ids[]: list of Role.id defining roles that should have add item permission on the folder
:type add_ids[]: string or list
- :param manage_ids[]: list of Role.name defining roles that should have manage permission on the folder
+ :param manage_ids[]: list of Role.id defining roles that should have manage permission on the folder
:type manage_ids[]: string or list
- :param modify_ids[]: list of Role.name defining roles that should have modify permission on the folder
+ :param modify_ids[]: list of Role.id defining roles that should have modify permission on the folder
:type modify_ids[]: string or list
:rtype: dictionary
- :returns: dict of current roles for all available permission types
+ :returns: dict of current roles for all available permission types.
:raises: RequestParameterInvalidException, ObjectNotFound, InsufficientPermissionsException, InternalServerError
RequestParameterMissingException
@@ -162,7 +163,7 @@
is_admin = trans.user_is_admin()
current_user_roles = trans.get_current_user_roles()
- decoded_folder_id = self.__decode_folder_id( trans, self.__cut_the_prefix( encoded_folder_id ) )
+ decoded_folder_id = self.folder_manager.decode_folder_id( trans, self.folder_manager.cut_the_prefix( encoded_folder_id ) )
folder = self.folder_manager.get( trans, decoded_folder_id )
if not ( is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, folder ) ):
raise exceptions.InsufficientPermissionsException( 'You do not have proper permission to modify permissions of this folder.' )
@@ -236,32 +237,7 @@
"""
raise exceptions.NotImplemented( 'Updating folder through this endpoint is not implemented yet.' )
- def __cut_the_prefix( self, encoded_id ):
- """
- Remove the prefix from the encoded folder id.
- """
- if ( ( len( encoded_id ) % 16 == 1 ) and encoded_id.startswith( 'F' ) ):
- cut_id = encoded_id[ 1: ]
- else:
- raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( encoded_id ) )
- return cut_id
-
- def __decode_folder_id( self, trans, encoded_id ):
- """
- Decode the folder id given that it has already lost the prefixed 'F'.
- """
- try:
- decoded_id = trans.security.decode_id( encoded_id )
- except ValueError:
- raise exceptions.MalformedId( "Malformed folder id ( %s ) specified, unable to decode" % ( str( encoded_id ) ) )
- return decoded_id
-
- def __cut_and_decode( self, trans, encoded_folder_id ):
- """
- Cuts the prefix (the prepended 'F') and returns the decoded id.
- """
- return self.__decode_folder_id( trans, self.__cut_the_prefix( encoded_folder_id ) )
-
+ # TODO move to Role manager
def _load_role( self, trans, role_name ):
"""
Method loads the role from the DB based on the given role name.
diff -r 188aa379bd9b25322e8532da73fae6dcece47231 -r d3e72ceda152bd813cca2ca676a6ad1f3e7deb5a lib/galaxy/webapps/galaxy/api/libraries.py
--- a/lib/galaxy/webapps/galaxy/api/libraries.py
+++ b/lib/galaxy/webapps/galaxy/api/libraries.py
@@ -3,6 +3,7 @@
"""
from galaxy import util
from galaxy import exceptions
+from galaxy.managers import libraries, folders, roles
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
from galaxy.model.orm import and_, not_, or_
@@ -16,6 +17,12 @@
class LibrariesController( BaseAPIController ):
+ def __init__( self, app ):
+ super( LibrariesController, self ).__init__( app )
+ self.folder_manager = folders.FolderManager()
+ self.library_manager = libraries.LibraryManager()
+ self.role_manager = roles.RoleManager()
+
@expose_api_anonymous
def index( self, trans, **kwd ):
"""
@@ -32,51 +39,25 @@
.. seealso:: :attr:`galaxy.model.Library.dict_collection_visible_keys`
"""
- is_admin = trans.user_is_admin()
- query = trans.sa_session.query( trans.app.model.Library )
- deleted = kwd.get( 'deleted', 'missing' )
- try:
- if not is_admin:
- # non-admins can't see deleted libraries
- deleted = False
- else:
- deleted = util.asbool( deleted )
- if deleted:
- query = query.filter( trans.app.model.Library.table.c.deleted == True )
- else:
- query = query.filter( trans.app.model.Library.table.c.deleted == False )
- except ValueError:
- # given value wasn't true/false but the user is admin so we don't filter on this parameter at all
- pass
-
- if not is_admin:
- # non-admins can see only allowed and public libraries
- current_user_role_ids = [ role.id for role in trans.get_current_user_roles() ]
- library_access_action = trans.app.security_agent.permitted_actions.LIBRARY_ACCESS.action
- restricted_library_ids = [ lp.library_id for lp in ( trans.sa_session.query( trans.model.LibraryPermissions )
- .filter( trans.model.LibraryPermissions.table.c.action == library_access_action )
- .distinct() ) ]
- accessible_restricted_library_ids = [ lp.library_id for lp in ( trans.sa_session.query( trans.model.LibraryPermissions )
- .filter( and_( trans.model.LibraryPermissions.table.c.action == library_access_action,
- trans.model.LibraryPermissions.table.c.role_id.in_( current_user_role_ids ) ) ) ) ]
- query = query.filter( or_( not_( trans.model.Library.table.c.id.in_( restricted_library_ids ) ), trans.model.Library.table.c.id.in_( accessible_restricted_library_ids ) ) )
+ deleted = kwd.get( 'deleted', None )
+ query = self.library_manager.list( trans, deleted )
libraries = []
for library in query:
- item = library.to_dict( view='element', value_mapper={ 'id': trans.security.encode_id, 'root_folder_id': trans.security.encode_id } )
- if trans.app.security_agent.library_is_public( library, contents=False ):
- item[ 'public' ] = True
- current_user_roles = trans.get_current_user_roles()
- if not trans.user_is_admin():
- item['can_user_add'] = trans.app.security_agent.can_add_library_item( current_user_roles, library )
- item['can_user_modify'] = trans.app.security_agent.can_modify_library_item( current_user_roles, library )
- item['can_user_manage'] = trans.app.security_agent.can_manage_library_item( current_user_roles, library )
- else:
- item['can_user_add'] = True
- item['can_user_modify'] = True
- item['can_user_manage'] = True
- libraries.append( item )
+ libraries.append( self.library_manager.get_library_dict( trans, library ) )
return libraries
+ def __decode_id( self, trans, encoded_id, object_name=None ):
+ """
+ Try to decode the id.
+
+ :param object_name: Name of the object the id belongs to. (optional)
+ :type object_name: str
+ """
+ try:
+ return trans.security.decode_id( encoded_id )
+ except TypeError:
+ raise exceptions.MalformedId( 'Malformed %s id specified, unable to decode.' % object_name if object_name is not None else '' )
+
@expose_api_anonymous
def show( self, trans, id, deleted='False', **kwd ):
"""
@@ -98,24 +79,9 @@
:raises: MalformedId, ObjectNotFound
"""
- library_id = id
- deleted = util.string_as_bool( deleted )
- library = self._load_library( trans, library_id, deleted )
- if not library or not ( trans.user_is_admin() or trans.app.security_agent.can_access_library( trans.get_current_user_roles(), library ) ):
- raise exceptions.ObjectNotFound( 'Library with the id provided ( %s ) was not found' % id )
- return library.to_dict( view='element', value_mapper={ 'id': trans.security.encode_id, 'root_folder_id': trans.security.encode_id } )
-
- def _load_library( self, trans, encoded_library_id, deleted=False ):
- try:
- decoded_library_id = trans.security.decode_id( encoded_library_id )
- except TypeError:
- raise exceptions.MalformedId( 'Malformed library id ( %s ) specified, unable to decode.' % id )
- try:
- library = trans.sa_session.query( trans.app.model.Library ).get( decoded_library_id )
- assert library.deleted == deleted
- except Exception:
- library = None
- return library
+ library = self.library_manager.get( trans, self.__decode_id( trans, id, 'library' ) )
+ library_dict = self.library_manager.get_library_dict( trans, library )
+ return library_dict
@expose_api
def create( self, trans, payload, **kwd ):
@@ -137,8 +103,6 @@
:raises: ItemAccessibilityException, RequestParameterMissingException
"""
- if not trans.user_is_admin():
- raise exceptions.ItemAccessibilityException( 'Only administrators can create libraries.' )
params = util.Params( payload )
name = util.restore_text( params.get( 'name', None ) )
if not name:
@@ -147,19 +111,9 @@
synopsis = util.restore_text( params.get( 'synopsis', '' ) )
if synopsis in [ 'None', None ]:
synopsis = ''
- library = trans.app.model.Library( name=name, description=description, synopsis=synopsis )
- root_folder = trans.app.model.LibraryFolder( name=name, description='' )
- library.root_folder = root_folder
- trans.sa_session.add_all( ( library, root_folder ) )
- trans.sa_session.flush()
-
- item = library.to_dict( view='element', value_mapper={ 'id': trans.security.encode_id, 'root_folder_id': trans.security.encode_id } )
- item['can_user_add'] = True
- item['can_user_modify'] = True
- item['can_user_manage'] = True
- if trans.app.security_agent.library_is_public( library, contents=False ):
- item[ 'public' ] = True
- return item
+ library = self.library_manager.create( trans, name, description, synopsis )
+ library_dict = self.library_manager.get_library_dict( trans, library )
+ return library_dict
@expose_api
def update( self, trans, id, **kwd ):
@@ -183,37 +137,21 @@
:raises: ItemAccessibilityException, MalformedId, ObjectNotFound, RequestParameterInvalidException, RequestParameterMissingException
"""
- if not trans.user_is_admin():
- raise exceptions.ItemAccessibilityException( 'Only administrators can update libraries.' )
-
- try:
- decoded_id = trans.security.decode_id( id )
- except Exception:
- raise exceptions.MalformedId( 'Malformed library id ( %s ) specified, unable to decode.' % id )
- library = None
- try:
- library = trans.sa_session.query( trans.app.model.Library ).get( decoded_id )
- except Exception:
- library = None
- if not library:
- raise exceptions.ObjectNotFound( 'Library with the id provided ( %s ) was not found' % id )
- if library.deleted:
- raise exceptions.RequestParameterInvalidException( 'You cannot modify a deleted library. Undelete it first.' )
+ library = self.library_manager.get( trans, self.__decode_id( trans, id, 'library' ) )
payload = kwd.get( 'payload', None )
if payload:
name = payload.get( 'name', None )
if name == '':
raise exceptions.RequestParameterMissingException( "Parameter 'name' of library is required. You cannot remove it." )
- library.name = name
if payload.get( 'description', None ) or payload.get( 'description', None ) == '':
- library.description = payload.get( 'description', None )
+ description = payload.get( 'description', None )
if payload.get( 'synopsis', None ) or payload.get( 'synopsis', None ) == '':
- library.synopsis = payload.get( 'synopsis', None )
+ synopsis = payload.get( 'synopsis', None )
else:
raise exceptions.RequestParameterMissingException( "You did not specify any payload." )
- trans.sa_session.add( library )
- trans.sa_session.flush()
- return library.to_dict( view='element', value_mapper={ 'id': trans.security.encode_id, 'root_folder_id': trans.security.encode_id } )
+ updated_library = self.library_manager.update( trans, library, name, description, synopsis )
+ library_dict = self.library_manager.get_library_dict( trans, updated_library )
+ return library_dict
@expose_api
def delete( self, trans, id, **kwd ):
@@ -237,28 +175,11 @@
:raises: ItemAccessibilityException, MalformedId, ObjectNotFound
"""
+ library = self.library_manager.get( trans, self.__decode_id( trans, id, 'library' ))
undelete = util.string_as_bool( kwd.get( 'undelete', False ) )
- if not trans.user_is_admin():
- raise exceptions.ItemAccessibilityException( 'Only administrators can delete and undelete libraries.' )
- try:
- decoded_id = trans.security.decode_id( id )
- except Exception:
- raise exceptions.MalformedId( 'Malformed library id ( %s ) specified, unable to decode.' % id )
- try:
- library = trans.sa_session.query( trans.app.model.Library ).get( decoded_id )
- except Exception:
- library = None
- if not library:
- raise exceptions.ObjectNotFound( 'Library with the id provided ( %s ) was not found' % id )
-
- if undelete:
- library.deleted = False
- else:
- library.deleted = True
-
- trans.sa_session.add( library )
- trans.sa_session.flush()
- return library.to_dict( view='element', value_mapper={ 'id': trans.security.encode_id, 'root_folder_id': trans.security.encode_id } )
+ library = self.library_manager.delete( trans, library, undelete )
+ library_dict = self.library_manager.get_library_dict( trans, library )
+ return library_dict
@expose_api
def get_permissions( self, trans, encoded_library_id, **kwd ):
@@ -283,9 +204,7 @@
"""
current_user_roles = trans.get_current_user_roles()
is_admin = trans.user_is_admin()
- library = self._load_library( trans, encoded_library_id )
- if not library or not ( is_admin or trans.app.security_agent.can_access_library( current_user_roles, library ) ):
- raise exceptions.ObjectNotFound( 'Library with the id provided ( %s ) was not found' % id )
+ library = self.library_manager.get( trans, self.__decode_id( trans, encoded_library_id, 'library' ) )
if not ( is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, library ) ):
raise exceptions.InsufficientPermissionsException( 'You do not have proper permission to access permissions of this library.' )
@@ -293,7 +212,8 @@
is_library_access = util.string_as_bool( kwd.get( 'is_library_access', False ) )
if scope == 'current' or scope is None:
- return self._get_current_roles( trans, library )
+ roles = self.library_manager.get_current_roles( trans, library )
+ return roles
# Return roles that are available to select.
elif scope == 'available':
@@ -315,34 +235,12 @@
return_roles = []
for role in roles:
- return_roles.append( dict( id=role.name, name=role.name, type=role.type ) )
+ role_id = trans.security.encode_id ( role.id )
+ return_roles.append( dict( id=role_id, name=role.name, type=role.type ) )
return dict( roles=return_roles, page=page, page_limit=page_limit, total=total_roles )
else:
raise exceptions.RequestParameterInvalidException( "The value of 'scope' parameter is invalid. Alllowed values: current, available" )
- def _load_role( self, trans, role_name ):
- """
- Method loads the role from the DB based on the given role name.
-
- :param role_name: name of the role to load from the DB
- :type role_name: string
-
- :rtype: Role
- :returns: the loaded Role object
-
- :raises: InconsistentDatabase, RequestParameterInvalidException, InternalServerError
- """
- try:
- role = trans.sa_session.query( trans.app.model.Role ).filter( trans.model.Role.table.c.name == role_name ).one()
- except MultipleResultsFound:
- raise exceptions.InconsistentDatabase( 'Multiple roles found with the same name. Name: ' + str( role_name ) )
- except NoResultFound:
- raise exceptions.RequestParameterInvalidException( 'No role found with the name provided. Name: ' + str( role_name ) )
- except Exception, e:
- raise exceptions.InternalServerError( 'Error loading from the database.' + str(e))
- return role
-
-
@expose_api
def set_permissions( self, trans, encoded_library_id, **kwd ):
"""
@@ -356,13 +254,13 @@
available actions: remove_restrictions, set_permissions
:type action: string
- :param access_ids[]: list of Role.name defining roles that should have access permission on the library
+ :param access_ids[]: list of Role.id defining roles that should have access permission on the library
:type access_ids[]: string or list
- :param add_ids[]: list of Role.name defining roles that should have add item permission on the library
+ :param add_ids[]: list of Role.id defining roles that should have add item permission on the library
:type add_ids[]: string or list
- :param manage_ids[]: list of Role.name defining roles that should have manage permission on the library
+ :param manage_ids[]: list of Role.id defining roles that should have manage permission on the library
:type manage_ids[]: string or list
- :param modify_ids[]: list of Role.name defining roles that should have modify permission on the library
+ :param modify_ids[]: list of Role.id defining roles that should have modify permission on the library
:type modify_ids[]: string or list
:rtype: dictionary
@@ -373,9 +271,8 @@
"""
is_admin = trans.user_is_admin()
current_user_roles = trans.get_current_user_roles()
- library = self._load_library( trans, encoded_library_id )
- if not library or not ( is_admin or trans.app.security_agent.can_access_library( current_user_roles, library ) ):
- raise exceptions.ObjectNotFound( 'Library with the id provided ( %s ) was not found' % id )
+ library = self.library_manager.get( trans, self.__decode_id( trans, encoded_library_id, 'library' ) )
+
if not ( is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, library ) ):
raise exceptions.InsufficientPermissionsException( 'You do not have proper permission to modify permissions of this library.' )
@@ -392,8 +289,8 @@
else:
raise exceptions.RequestParameterMissingException( 'The mandatory parameter "action" is missing.' )
elif action == 'remove_restrictions':
- trans.app.security_agent.make_library_public( library )
- if not trans.app.security_agent.library_is_public( library ):
+ is_public = self.library_manager.make_public( trans, library )
+ if not is_public:
raise exceptions.InternalServerError( 'An error occured while making library public.' )
elif action == 'set_permissions':
@@ -401,7 +298,7 @@
valid_access_roles = []
invalid_access_roles_names = []
for role_id in new_access_roles_ids:
- role = self._load_role( trans, role_id )
+ role = self.role_manager.get( trans, self.__decode_id( trans, role_id, 'role' ) )
valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, library, is_library_access=True )
if role in valid_roles:
valid_access_roles.append( role )
@@ -414,7 +311,7 @@
valid_add_roles = []
invalid_add_roles_names = []
for role_id in new_add_roles_ids:
- role = self._load_role( trans, role_id )
+ role = self.role_manager.get( trans, self.__decode_id( trans, role_id, 'role' ) )
valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, library )
if role in valid_roles:
valid_add_roles.append( role )
@@ -427,7 +324,7 @@
valid_manage_roles = []
invalid_manage_roles_names = []
for role_id in new_manage_roles_ids:
- role = self._load_role( trans, role_id )
+ role = self.role_manager.get( trans, self.__decode_id( trans, role_id, 'role' ) )
valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, library )
if role in valid_roles:
valid_manage_roles.append( role )
@@ -440,7 +337,7 @@
valid_modify_roles = []
invalid_modify_roles_names = []
for role_id in new_modify_roles_ids:
- role = self._load_role( trans, role_id )
+ role = self.role_manager.get( trans, self.__decode_id( trans, role_id, 'role' ) )
valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, library )
if role in valid_roles:
valid_modify_roles.append( role )
@@ -461,34 +358,8 @@
else:
raise exceptions.RequestParameterInvalidException( 'The mandatory parameter "action" has an invalid value.'
'Allowed values are: "remove_restrictions", set_permissions"' )
-
- return self._get_current_roles( trans, library )
-
-
- def _get_current_roles( self, trans, library):
- """
- Find all roles currently connected to relevant permissions
- on the library.
-
- :param library: the model object
- :type library: Library
-
- :rtype: dictionary
- :returns: dict of current roles for all available permission types
- """
- # Omit duplicated roles by converting to set
- access_roles = set( library.get_access_roles( trans ) )
- modify_roles = set( trans.app.security_agent.get_roles_for_action( library, trans.app.security_agent.permitted_actions.LIBRARY_MODIFY ) )
- manage_roles = set( trans.app.security_agent.get_roles_for_action( library, trans.app.security_agent.permitted_actions.LIBRARY_MANAGE ) )
- add_roles = set( trans.app.security_agent.get_roles_for_action( library, trans.app.security_agent.permitted_actions.LIBRARY_ADD ) )
-
- access_library_role_list = [ access_role.name for access_role in access_roles ]
- modify_library_role_list = [ modify_role.name for modify_role in modify_roles ]
- manage_library_role_list = [ manage_role.name for manage_role in manage_roles ]
- add_library_item_role_list = [ add_role.name for add_role in add_roles ]
-
- return dict( access_library_role_list=access_library_role_list, modify_library_role_list=modify_library_role_list, manage_library_role_list=manage_library_role_list, add_library_item_role_list=add_library_item_role_list )
-
+ roles = self.library_manager.get_current_roles( trans, library )
+ return roles
def set_permissions_old( self, trans, library, payload, **kwd ):
"""
@@ -508,7 +379,6 @@
# Copy the permissions to the root folder
trans.app.security_agent.copy_library_permissions( trans, library, library.root_folder )
message = "Permissions updated for library '%s'." % library.name
-
item = library.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id , 'root_folder_id' : trans.security.encode_id } )
return item
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0