4 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/dbb44b0f5b48/ Changeset: dbb44b0f5b48 User: dannon Date: 2013-10-25 17:47:42 Summary: Prevent redefinition of chrom in list comprehension -- was harmless in this case but could have been a bug down the road. Affected #: 1 file diff -r 6865031ea0c473984473e57100f60a3739065ca1 -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 lib/galaxy/visualization/genomes.py --- a/lib/galaxy/visualization/genomes.py +++ b/lib/galaxy/visualization/genomes.py @@ -161,7 +161,7 @@ # No more chroms to read. pass - to_sort = [{ 'chrom': chrom, 'len': length } for chrom, length in chroms.iteritems()] + to_sort = [{ 'chrom': chrm, 'len': length } for chrm, length in chroms.iteritems()] to_sort.sort(lambda a,b: cmp( split_by_number(a['chrom']), split_by_number(b['chrom']) )) return { 'id': self.key, https://bitbucket.org/galaxy/galaxy-central/commits/8c78de92633e/ Changeset: 8c78de92633e User: dannon Date: 2013-10-29 18:37:45 Summary: Merge. Affected #: 64 files diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/galaxy/datatypes/registry.py --- a/lib/galaxy/datatypes/registry.py +++ b/lib/galaxy/datatypes/registry.py @@ -217,7 +217,8 @@ if sniffers: for elem in sniffers.findall( 'sniffer' ): # Keep an in-memory list of sniffer elems to enable persistence. - self.sniffer_elems.append( elem ) + if elem not in self.sniffer_elems: + self.sniffer_elems.append( elem ) dtype = elem.get( 'type', None ) if dtype: try: @@ -239,6 +240,8 @@ module = getattr( module, comp ) aclass = getattr( module, datatype_class_name )() if deactivate: + if elem in self.sniffer_elems: + self.sniffer_elems.remove( elem ) for sniffer_class in self.sniff_order: if sniffer_class.__class__ == aclass.__class__: self.sniff_order.remove( sniffer_class ) @@ -463,10 +466,10 @@ target_datatype = elem[2] if installed_repository_dict: converter_path = installed_repository_dict[ 'converter_path' ] + else: + converter_path = self.converters_path + try: config_path = os.path.join( converter_path, tool_config ) - else: - config_path = os.path.join( self.converters_path, tool_config ) - try: converter = toolbox.load_tool( config_path ) if installed_repository_dict: # If the converter is included in an installed tool shed repository, set the tool @@ -484,7 +487,8 @@ converter.id = tool_dict[ 'guid' ] break if deactivate: - del toolbox.tools_by_id[ converter.id ] + if converter.id in toolbox.tools_by_id: + del toolbox.tools_by_id[ converter.id ] if source_datatype in self.datatype_converters: del self.datatype_converters[ source_datatype ][ target_datatype ] self.log.debug( "Deactivated converter: %s", converter.id ) @@ -496,9 +500,9 @@ self.log.debug( "Loaded converter: %s", converter.id ) except Exception, e: if deactivate: - self.log.exception( "Error deactivating converter (%s): %s" % ( config_path, str( e ) ) ) + self.log.exception( "Error deactivating converter from (%s): %s" % ( converter_path, str( e ) ) ) else: - self.log.exception( "Error loading converter (%s): %s" % ( config_path, str( e ) ) ) + self.log.exception( "Error loading converter (%s): %s" % ( converter_path, str( e ) ) ) def load_display_applications( self, installed_repository_dict=None, deactivate=False ): """ If deactivate is False, add display applications from self.display_app_containers or diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/galaxy/util/__init__.py --- a/lib/galaxy/util/__init__.py +++ b/lib/galaxy/util/__init__.py @@ -872,7 +872,7 @@ log.error( "Mail is not configured for this Galaxy instance." ) log.info( msg ) return - smtp_ssl = asbool( config.smtp_ssl ) + smtp_ssl = asbool( getattr(config, 'smtp_ssl', False ) ) if smtp_ssl: s = smtplib.SMTP_SSL() else: diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/galaxy/webapps/galaxy/buildapp.py --- a/lib/galaxy/webapps/galaxy/buildapp.py +++ b/lib/galaxy/webapps/galaxy/buildapp.py @@ -155,6 +155,7 @@ webapp.mapper.resource( 'role', 'roles', path_prefix='/api' ) webapp.mapper.resource( 'group', 'groups', path_prefix='/api' ) webapp.mapper.resource_with_deleted( 'quota', 'quotas', path_prefix='/api' ) + webapp.mapper.connect( '/api/tools/{id:.*?}', action='show', controller="tools" ) webapp.mapper.resource( 'tool', 'tools', path_prefix='/api' ) webapp.mapper.resource_with_deleted( 'user', 'users', path_prefix='/api' ) webapp.mapper.resource( 'genome', 'genomes', path_prefix='/api' ) diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/galaxy/webapps/tool_shed/api/repositories.py --- a/lib/galaxy/webapps/tool_shed/api/repositories.py +++ b/lib/galaxy/webapps/tool_shed/api/repositories.py @@ -1,6 +1,6 @@ -import logging, os +import logging +import os from time import strftime - from galaxy import eggs from galaxy import util from galaxy import web diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/galaxy/webapps/tool_shed/controllers/repository.py --- a/lib/galaxy/webapps/tool_shed/controllers/repository.py +++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py @@ -2980,6 +2980,12 @@ key_rd_dicts_to_be_processed=None, all_repository_dependencies=None, handled_key_rd_dicts=None ) + if str( repository.type ) != rt_util.TOOL_DEPENDENCY_DEFINITION: + # Handle messaging for orphan tool dependency definitions. + orphan_message = tool_dependency_util.generate_message_for_orphan_tool_dependencies( trans, repository, metadata ) + if orphan_message: + message += orphan_message + status = 'warning' else: metadata = None is_malicious = suc.changeset_is_malicious( trans, id, repository.tip( trans.app ) ) diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/galaxy/webapps/tool_shed/controllers/upload.py --- a/lib/galaxy/webapps/tool_shed/controllers/upload.py +++ b/lib/galaxy/webapps/tool_shed/controllers/upload.py @@ -227,7 +227,6 @@ # or some other problem. Tool dependency definitions can define orphan tool dependencies (no relationship to any tools contained in the repository), # so warning messages are important because orphans are always valid. The repository owner must be warned in case they did not intend to define an # orphan dependency, but simply provided incorrect information (tool shed, name owner, changeset_revision) for the definition. - # Handle messaging for orphan tool dependencies. orphan_message = tool_dependency_util.generate_message_for_orphan_tool_dependencies( trans, repository, metadata_dict ) if orphan_message: message += orphan_message diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/tool_shed/galaxy_install/install_manager.py --- a/lib/tool_shed/galaxy_install/install_manager.py +++ b/lib/tool_shed/galaxy_install/install_manager.py @@ -597,6 +597,8 @@ def __has_tool_dependencies( self, metadata_dict ): '''Determine if the provided metadata_dict specifies tool dependencies.''' + # The use of the orphan_tool_dependencies category in metadata has been deprecated, but we still need to check in case + # the metadata is out of date. if 'tool_dependencies' in metadata_dict or 'orphan_tool_dependencies' in metadata_dict: return True return False diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py --- a/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py +++ b/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py @@ -43,31 +43,15 @@ os.makedirs( extraction_path ) self.archive.extractall( extraction_path ) else: - # Sort filenames within the archive by length, because if the shortest path entry in the archive is a directory, - # and the next entry has the directory prepended, then everything following that entry must be within that directory. - # For example, consider tarball for BWA 0.5.9: - # bwa-0.5.9.tar.bz2: - # bwa-0.5.9/ - # bwa-0.5.9/bwt.c - # bwa-0.5.9/bwt.h - # bwa-0.5.9/Makefile - # bwa-0.5.9/bwt_gen/ - # bwa-0.5.9/bwt_gen/Makefile - # bwa-0.5.9/bwt_gen/bwt_gen.c - # bwa-0.5.9/bwt_gen/bwt_gen.h - # When sorted by length, one sees a directory at the root of the tarball, and all other tarball contents as - # children of that directory. - filenames = sorted( [ self.getname( item ) for item in contents ], cmp=lambda a,b: cmp( len( a ), len( b ) ) ) - parent_name = filenames[ 0 ] - parent = self.getmember( parent_name ) - first_child = filenames[ 1 ] - if first_child.startswith( parent_name ) and parent is not None and self.isdir( parent ): - if self.getname( parent ) == self.file_name: - self.archive.extractall( os.path.join( path ) ) - extraction_path = os.path.join( path, self.file_name ) - else: - self.archive.extractall( os.path.join( path ) ) - extraction_path = os.path.join( path, self.getname( parent ) ) + # Get the common prefix for all the files in the archive. If the common prefix ends with a slash, + # or self.isdir() returns True, the archive contains a single directory with the desired contents. + # Otherwise, it contains multiple files and/or directories at the root of the archive. + common_prefix = os.path.commonprefix( [ self.getname( item ) for item in contents ] ) + if len( common_prefix ) >= 1 and not common_prefix.endswith( os.sep ) and self.isdir( self.getmember( common_prefix ) ): + common_prefix += os.sep + if common_prefix.endswith( os.sep ): + self.archive.extractall( os.path.join( path ) ) + extraction_path = os.path.join( path, common_prefix ) else: extraction_path = os.path.join( path, self.file_name ) if not os.path.exists( extraction_path ): diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/tool_shed/util/container_util.py --- a/lib/tool_shed/util/container_util.py +++ b/lib/tool_shed/util/container_util.py @@ -5,6 +5,7 @@ from galaxy.web.framework.helpers import time_ago from tool_shed.util import common_util from tool_shed.util import readme_util +from tool_shed.util.tool_dependency_util import tool_dependency_is_orphan import tool_shed.util.shed_util_common as suc log = logging.getLogger( __name__ ) @@ -278,6 +279,14 @@ self.installation_status = installation_status self.repository_id = repository_id self.tool_dependency_id = tool_dependency_id + # The designation of a ToolDependency into the "orphan" category has evolved over time, and is significantly restricted since the + # introduction of the TOOL_DEPENDENCY_DEFINITION repository type. This designation is still critical, however, in that it handles + # the case where a repository contains both tools and a tool_dependencies.xml file, but the definition in the tool_dependencies.xml + # file is in no way related to anything defined by any of the contained tool's requirements tag sets. This is important in that it + # is often a result of a typo (e.g., dependency name or version) that differs between the tool dependency definition within the + # tool_dependencies.xml file and what is defined in the tool config's <requirements> tag sets. In these cases, the user should be + # presented with a warning message, and this warning message is is in fact displayed if the following is_orphan attribute is True. + # This is tricky because in some cases it may be intentional, and tool dependencies that are categorized as "orphan" are in fact valid. self.is_orphan = is_orphan @property @@ -310,32 +319,29 @@ self.repository_metadata_id = repository_metadata_id self.repository_id = repository_id -def add_orphan_settings_to_tool_dependencies( tool_dependencies, orphan_tool_dependencies ): +def add_orphan_settings_to_tool_dependencies( tool_dependencies, tools ): """Inspect all received tool dependencies and label those that are orphans within the repository.""" - orphan_env_dependencies = orphan_tool_dependencies.get( 'set_environment', None ) + #orphan_env_dependencies = orphan_tool_dependencies.get( 'set_environment', None ) new_tool_dependencies = {} - if tool_dependencies: - for td_key, requirements_dict in tool_dependencies.items(): - if td_key in [ 'set_environment' ]: - # "set_environment": [{"name": "R_SCRIPT_PATH", "type": "set_environment"}] - if orphan_env_dependencies: - new_set_environment_dict_list = [] - for set_environment_dict in requirements_dict: - if set_environment_dict in orphan_env_dependencies: - set_environment_dict[ 'is_orphan' ] = True - else: - set_environment_dict[ 'is_orphan' ] = False - new_set_environment_dict_list.append( set_environment_dict ) - new_tool_dependencies[ td_key ] = new_set_environment_dict_list - else: - new_tool_dependencies[ td_key ] = requirements_dict - else: - # {"R/2.15.1": {"name": "R", "readme": "some string", "type": "package", "version": "2.15.1"} - if td_key in orphan_tool_dependencies: - requirements_dict[ 'is_orphan' ] = True - else: - requirements_dict[ 'is_orphan' ] = False - new_tool_dependencies[ td_key ] = requirements_dict + for td_key, requirements_dict in tool_dependencies.items(): + if td_key in [ 'set_environment' ]: + # "set_environment": [{"name": "R_SCRIPT_PATH", "type": "set_environment"}] + new_set_environment_dict_list = [] + for env_requirements_dict in requirements_dict: + name = env_requirements_dict[ 'name' ] + type = env_requirements_dict[ 'type' ] + if tool_dependency_is_orphan( type, name, None, tools ): + env_requirements_dict[ 'is_orphan' ] = True + new_set_environment_dict_list.append( env_requirements_dict ) + new_tool_dependencies[ td_key ] = new_set_environment_dict_list + else: + # {"R/2.15.1": {"name": "R", "readme": "some string", "type": "package", "version": "2.15.1"} + name = requirements_dict[ 'name' ] + type = requirements_dict[ 'type' ] + version = requirements_dict[ 'version'] + if tool_dependency_is_orphan( type, name, version, tools ): + requirements_dict[ 'is_orphan' ] = True + new_tool_dependencies[ td_key ] = requirements_dict return new_tool_dependencies def build_data_managers_folder( trans, folder_id, data_managers, label=None ): @@ -802,8 +808,16 @@ tool_dependencies = metadata[ 'tool_dependencies' ] if trans.webapp.name == 'tool_shed': if 'orphan_tool_dependencies' in metadata: + # The use of the orphan_tool_dependencies category in metadata has been deprecated, but we still need to check in case + # the metadata is out of date. orphan_tool_dependencies = metadata[ 'orphan_tool_dependencies' ] - tool_dependencies = add_orphan_settings_to_tool_dependencies( tool_dependencies, orphan_tool_dependencies ) + tool_dependencies.update( orphan_tool_dependencies ) + # Tool dependencies can be categorized as orphans only if the repository contains tools. + if 'tools' not in exclude: + tools = metadata.get( 'tools', [] ) + tools.extend( metadata.get( 'invalid_tools', [] ) ) + if tools: + tool_dependencies = add_orphan_settings_to_tool_dependencies( tool_dependencies, tools ) folder_id, tool_dependencies_root_folder = build_tool_dependencies_folder( trans, folder_id, tool_dependencies, @@ -967,8 +981,7 @@ readme=None, installation_status='Installation status', repository_id=None, - tool_dependency_id=None, - is_orphan=None ) + tool_dependency_id=None ) else: tool_dependency = ToolDependency( id=tool_dependency_id, name='Name', @@ -977,8 +990,7 @@ readme=None, installation_status=None, repository_id=None, - tool_dependency_id=None, - is_orphan='Orphan' ) + tool_dependency_id=None ) folder.tool_dependencies.append( tool_dependency ) not_used_by_local_tools_description = "these dependencies may not be required by tools in this repository" for dependency_key, requirements_dict in tool_dependencies.items(): @@ -988,7 +1000,7 @@ if trans.webapp.name == 'tool_shed': is_orphan = set_environment_dict.get( 'is_orphan', False ) else: - # TODO: handle this is Galaxy + # This is probably not necessary to display in Galaxy. is_orphan = False if is_orphan: folder.description = not_used_by_local_tools_description diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/tool_shed/util/metadata_util.py --- a/lib/tool_shed/util/metadata_util.py +++ b/lib/tool_shed/util/metadata_util.py @@ -99,7 +99,6 @@ no_datatypes = not ancestor_datatypes and not current_datatypes no_readme_files = not ancestor_readme_files and not current_readme_files no_repository_dependencies = not ancestor_repository_dependencies and not current_repository_dependencies - # Tool dependencies can define orphan dependencies in the tool shed. no_tool_dependencies = not ancestor_tool_dependencies and not current_tool_dependencies no_tools = not ancestor_guids and not current_guids no_workflows = not ancestor_workflows and not current_workflows @@ -544,8 +543,8 @@ def generate_environment_dependency_metadata( elem, valid_tool_dependencies_dict ): """ - The value of env_var_name must match the value of the "set_environment" type in the tool config's <requirements> tag set, or the tool dependency - will be considered an orphan. Tool dependencies of type set_environment are always defined as valid, but may be orphans. + The value of env_var_name must match the value of the "set_environment" type in the tool config's <requirements> tag set, + or the tool dependency will be considered an orphan. """ # The value of the received elem looks something like this: # <set_environment version="1.0"> @@ -900,7 +899,6 @@ invalid_repository_dependency_tups.append( repository_dependency_tup ) error_message = '%s %s' % ( error_message, message ) elif elem.tag == 'set_environment': - # Tool dependencies of this type are always considered valid, but may be orphans. valid_tool_dependencies_dict = generate_environment_dependency_metadata( elem, valid_tool_dependencies_dict ) if valid_tool_dependencies_dict: if original_valid_tool_dependencies_dict: @@ -920,18 +918,6 @@ repository_dependency_tups=invalid_repository_dependency_tups, is_valid=False, description=description ) - # We need to continue to restrict the behavior for defining orphan tool dependencies, possibly eliminating them altoghether at some point. - check_for_orphan_tool_dependencies = False - if app.name == 'tool_shed': - if repository.type != rt_util.TOOL_DEPENDENCY_DEFINITION and not repository.can_change_type_to( app, rt_util.TOOL_DEPENDENCY_DEFINITION ): - check_for_orphan_tool_dependencies = True - elif 'tools' in metadata_dict: - check_for_orphan_tool_dependencies = True - if check_for_orphan_tool_dependencies: - # Determine and store orphan tool dependencies. - orphan_tool_dependencies = get_orphan_tool_dependencies( metadata_dict ) - if orphan_tool_dependencies: - metadata_dict[ 'orphan_tool_dependencies' ] = orphan_tool_dependencies return metadata_dict, error_message def generate_tool_metadata( tool_config, tool, repository_clone_url, metadata_dict ): @@ -1007,34 +993,6 @@ changeset_revision = suc.get_latest_changeset_revision( trans, repository, repo ) return suc.get_repository_metadata_by_changeset_revision( trans, trans.security.encode_id( repository.id ), changeset_revision ) -def get_orphan_tool_dependencies( metadata ): - """Inspect tool dependencies included in the received metadata and determine if any of them are orphans within the repository.""" - orphan_tool_dependencies_dict = {} - if metadata: - tools = metadata.get( 'tools', None ) - tool_dependencies = metadata.get( 'tool_dependencies', None ) - if tool_dependencies: - for td_key, requirements_dict in tool_dependencies.items(): - if td_key in [ 'set_environment' ]: - for set_environment_dict in requirements_dict: - type = 'set_environment' - name = set_environment_dict.get( 'name', None ) - version = None - if name: - if tool_dependency_is_orphan( type, name, version, tools ): - if td_key in orphan_tool_dependencies_dict: - orphan_tool_dependencies_dict[ td_key ].append( set_environment_dict ) - else: - orphan_tool_dependencies_dict[ td_key ] = [ set_environment_dict ] - else: - type = requirements_dict.get( 'type', None ) - name = requirements_dict.get( 'name', None ) - version = requirements_dict.get( 'version', None ) - if type and name: - if tool_dependency_is_orphan( type, name, version, tools ): - orphan_tool_dependencies_dict[ td_key ] = requirements_dict - return orphan_tool_dependencies_dict - def get_parent_id( trans, id, old_id, version, guid, changeset_revisions ): parent_id = None # Compare from most recent to oldest. @@ -1929,33 +1887,6 @@ message=error_message, status='error' ) ) -def tool_dependency_is_orphan( type, name, version, tools ): - """ - Determine if the combination of the received type, name and version is defined in the <requirement> tag for at least one tool in the received list of tools. - If not, the tool dependency defined by the combination is considered an orphan in it's repository in the tool shed. - """ - if tools: - if type == 'package': - if name and version: - for tool_dict in tools: - requirements = tool_dict.get( 'requirements', [] ) - for requirement_dict in requirements: - req_name = requirement_dict.get( 'name', None ) - req_version = requirement_dict.get( 'version', None ) - req_type = requirement_dict.get( 'type', None ) - if req_name == name and req_version == version and req_type == type: - return False - elif type == 'set_environment': - if name: - for tool_dict in tools: - requirements = tool_dict.get( 'requirements', [] ) - for requirement_dict in requirements: - req_name = requirement_dict.get( 'name', None ) - req_type = requirement_dict.get( 'type', None ) - if req_name == name and req_type == type: - return False - return True - def update_existing_tool_dependency( app, repository, original_dependency_dict, new_dependencies_dict ): """ Update an exsiting tool dependency whose definition was updated in a change set pulled by a Galaxy administrator when getting updates diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 lib/tool_shed/util/tool_dependency_util.py --- a/lib/tool_shed/util/tool_dependency_util.py +++ b/lib/tool_shed/util/tool_dependency_util.py @@ -102,9 +102,9 @@ def generate_message_for_invalid_tool_dependencies( metadata_dict ): """ - Due to support for orphan tool dependencies (which are always valid) tool dependency definitions can only be invalid if they include a definition for a complex - repository dependency and the repository dependency definition is invalid. This method retrieves the error message associated with the invalid tool dependency - for display in the caller. + Tool dependency definitions can only be invalid if they include a definition for a complex repository dependency and the repository + dependency definition is invalid. This method retrieves the error message associated with the invalid tool dependency for display + in the caller. """ message = '' if metadata_dict: @@ -118,38 +118,62 @@ def generate_message_for_orphan_tool_dependencies( trans, repository, metadata_dict ): """ - The introduction of the support for orphan tool dependency definitions in tool shed repositories has resulted in the inability - to define an improperly configured tool dependency definition / tool config requirements tag combination as an invalid tool - dependency. This is certainly a weakness which cannot be correctly handled since now the only way to categorize a tool dependency - as invalid is if it consists of a complex repository dependency that is invalid. Any tool dependency definition other than those - is considered valid but perhaps an orphan due to it's actual invalidity. + The designation of a ToolDependency into the "orphan" category has evolved over time, and is significantly restricted since the + introduction of the TOOL_DEPENDENCY_DEFINITION repository type. This designation is still critical, however, in that it handles + the case where a repository contains both tools and a tool_dependencies.xml file, but the definition in the tool_dependencies.xml + file is in no way related to anything defined by any of the contained tool's requirements tag sets. This is important in that it + is often a result of a typo (e.g., dependency name or version) that differs between the tool dependency definition within the + tool_dependencies.xml file and what is defined in the tool config's <requirements> tag sets. In these cases, the user should be + presented with a warning message, and this warning message is is in fact displayed if the following is_orphan attribute is True. + This is tricky because in some cases it may be intentional, and tool dependencies that are categorized as "orphan" are in fact valid. """ + has_orphan_package_dependencies = False + has_orphan_set_environment_dependencies = False message = '' + package_orphans_str = '' + set_environment_orphans_str = '' + # Tool dependencies are categorized as orphan only if the repository contains tools. if metadata_dict: - orphan_tool_dependencies = metadata_dict.get( 'orphan_tool_dependencies', None ) - if orphan_tool_dependencies: - if 'tools' in metadata_dict or 'invalid_tools' in metadata_dict: - for td_key, requirements_dict in orphan_tool_dependencies.items(): - if td_key == 'set_environment': - # "set_environment": [{"name": "R_SCRIPT_PATH", "type": "set_environment"}] - message += "The settings for <b>name</b> and <b>type</b> from a contained tool configuration file's <b>requirement</b> tag " - message += "does not match the information for the following tool dependency definitions in the <b>tool_dependencies.xml</b> " - message += "file, so these tool dependencies have no relationship with any tools within this repository.<br/>" - for env_requirements_dict in requirements_dict: - name = env_requirements_dict[ 'name' ] - type = env_requirements_dict[ 'type' ] - message += "<b>* name:</b> %s, <b>type:</b> %s<br/>" % ( str( name ), str( type ) ) - else: - # "R/2.15.1": {"name": "R", "readme": "some string", "type": "package", "version": "2.15.1"} - message += "The settings for <b>name</b>, <b>version</b> and <b>type</b> from a contained tool configuration file's " - message += "<b>requirement</b> tag does not match the information for the following tool dependency definitions in the " - message += "<b>tool_dependencies.xml</b> file, so these tool dependencies have no relationship with any tools within " - message += "this repository.<br/>" - name = requirements_dict[ 'name' ] - type = requirements_dict[ 'type' ] - version = requirements_dict[ 'version' ] - message += "<b>* name:</b> %s, <b>type:</b> %s, <b>version:</b> %s<br/>" % ( str( name ), str( type ), str( version ) ) - message += "<br/>" + tools = metadata_dict.get( 'tools', [] ) + invalid_tools = metadata_dict.get( 'invalid_tools', [] ) + tool_dependencies = metadata_dict.get( 'tool_dependencies', {} ) + # The use of the orphan_tool_dependencies category in metadata has been deprecated, but we still need to check in case + # the metadata is out of date. + orphan_tool_dependencies = metadata_dict.get( 'orphan_tool_dependencies', {} ) + # Updating should cause no problems here since a tool dependency cannot be included in both dictionaries. + tool_dependencies.update( orphan_tool_dependencies ) + if tool_dependencies and ( tools or invalid_tools ): + for td_key, requirements_dict in tool_dependencies.items(): + if td_key == 'set_environment': + # "set_environment": [{"name": "R_SCRIPT_PATH", "type": "set_environment"}] + for env_requirements_dict in requirements_dict: + name = env_requirements_dict[ 'name' ] + type = env_requirements_dict[ 'type' ] + if tool_dependency_is_orphan( type, name, None, tools ): + if not has_orphan_set_environment_dependencies: + has_orphan_set_environment_dependencies = True + set_environment_orphans_str += "<b>* name:</b> %s, <b>type:</b> %s<br/>" % ( str( name ), str( type ) ) + else: + # "R/2.15.1": {"name": "R", "readme": "some string", "type": "package", "version": "2.15.1"} + name = requirements_dict[ 'name' ] + type = requirements_dict[ 'type' ] + version = requirements_dict[ 'version' ] + if tool_dependency_is_orphan( type, name, version, tools ): + if not has_orphan_package_dependencies: + has_orphan_package_dependencies = True + package_orphans_str += "<b>* name:</b> %s, <b>type:</b> %s, <b>version:</b> %s<br/>" % \ + ( str( name ), str( type ), str( version ) ) + if has_orphan_package_dependencies: + message += "The settings for <b>name</b>, <b>version</b> and <b>type</b> from a contained tool configuration file's " + message += "<b>requirement</b> tag does not match the information for the following tool dependency definitions in the " + message += "<b>tool_dependencies.xml</b> file, so these tool dependencies have no relationship with any tools within " + message += "this repository.<br/>" + message += package_orphans_str + if has_orphan_set_environment_dependencies: + message += "The settings for <b>name</b> and <b>type</b> from a contained tool configuration file's <b>requirement</b> tag " + message += "does not match the information for the following tool dependency definitions in the <b>tool_dependencies.xml</b> " + message += "file, so these tool dependencies have no relationship with any tools within this repository.<br/>" + message += set_environment_orphans_str return message def generate_message_for_repository_type_change( trans, repository ): @@ -413,3 +437,30 @@ tool_dependency.status = status trans.sa_session.add( tool_dependency ) trans.sa_session.flush() + +def tool_dependency_is_orphan( type, name, version, tools ): + """ + Determine if the combination of the received type, name and version is defined in the <requirement> tag for at least one tool in the + received list of tools. If not, the tool dependency defined by the combination is considered an orphan in it's repository in the tool + shed. + """ + if type == 'package': + if name and version: + for tool_dict in tools: + requirements = tool_dict.get( 'requirements', [] ) + for requirement_dict in requirements: + req_name = requirement_dict.get( 'name', None ) + req_version = requirement_dict.get( 'version', None ) + req_type = requirement_dict.get( 'type', None ) + if req_name == name and req_version == version and req_type == type: + return False + elif type == 'set_environment': + if name: + for tool_dict in tools: + requirements = tool_dict.get( 'requirements', [] ) + for requirement_dict in requirements: + req_name = requirement_dict.get( 'name', None ) + req_type = requirement_dict.get( 'type', None ) + if req_name == name and req_type == type: + return False + return True diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 static/scripts/galaxy.base.js --- a/static/scripts/galaxy.base.js +++ b/static/scripts/galaxy.base.js @@ -295,7 +295,6 @@ use_textarea = ("use_textarea" in config_dict ? config_dict.use_textarea : false), on_finish = ("on_finish" in config_dict ? config_dict.on_finish : null), help_text = ("help_text" in config_dict ? config_dict.help_text : null); - // Add element behavior. var container = $(this); @@ -326,7 +325,7 @@ }; // Create input element(s) for editing. - var cur_text = container.text(), + var cur_text = ("cur_text" in config_dict ? config_dict.cur_text : container.text() ), input_elt, button_elt; if (use_textarea) { diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 static/scripts/galaxy.upload.js --- a/static/scripts/galaxy.upload.js +++ b/static/scripts/galaxy.upload.js @@ -206,7 +206,7 @@ return null; // configure uploadbox - this.uploadbox.configure({url : galaxy_config.root + "api/tools/", paramname : "files_0|file_data"}); + this.uploadbox.configure({url : galaxy_config.root + "api/tools", paramname : "files_0|file_data"}); // configure tool tool_input = {}; diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 static/scripts/mvc/base-mvc.js --- a/static/scripts/mvc/base-mvc.js +++ b/static/scripts/mvc/base-mvc.js @@ -219,60 +219,50 @@ //============================================================================== -function LoadingIndicator( $where ){ - var self = this, - $indicator; +function LoadingIndicator( $where, options ){ + options = options || {}; + var self = this; - function setPosition(){ - // even tho pos is 'fixed' - give illusion of width 100% and margin by manually setting width, offset - var padding = 4, - width = $indicator.parent().width() || $where.width(), - offset = $indicator.parent().offset() || $where.offset(); + function render(){ + var html = [ + '<div class="loading-indicator">', + '<span class="fa-icon-spinner fa-icon-spin fa-icon-large" style="color: grey"></span>', + '<span style="margin-left: 8px; color: grey"><i>loading...</i></span>', + '</div>' + ].join( '\n' ); - $indicator.outerWidth( width - ( padding * 2 ) ); - // have to use css top, left and not offset (wont work when indicator is hidden) - $indicator.css({ top: offset.top + padding + 'px' , left: offset.left + padding + 'px' }); + return $( html ).css( options.css || { + 'position' : 'fixed', + 'margin' : '6px 0px 0px 10px', + 'opacity' : '0.85' + }).hide(); } - function render(){ - var $spinner = $( '<span class="fa-icon-spinner fa-icon-spin fa-icon-large"></span>') - .css({ 'color' : 'grey', 'font-size' : '16px' }); - var $message = $( '<i>loading...</i>' ) - .css({ 'color' : 'grey', 'margin-left' : '8px' }); - $indicator = $( '<div/>' ).addClass( 'loading-indicator' ) - .css({ - 'position' : 'fixed', - 'padding' : '4px', - 'text-align' : 'center', - 'background-color' : 'white', - 'opacity' : '0.85', - 'border-radius' : '3px' - }) - .append( $spinner, $message ) - //NOTE: insert as sibling to $where - .insertBefore( $where ); - setPosition(); - return $indicator.hide(); - } + self.show = function( msg, speed, callback ){ + msg = msg || 'loading...'; + speed = speed || 'fast'; + // since position is fixed - we insert as sibling + self.$indicator = render().insertBefore( $where ); + self.message( msg ); + self.$indicator.fadeIn( speed, callback ); + return self; + }; - self.show = function( speed, callback ){ - speed = speed || 'fast'; - setPosition(); - $indicator.fadeIn( speed, callback ); - // not using full fadeOut allows using scroll to still work - //$whatIsLoading.fadeTo( speed, 0.0001, callback ); - return self; + self.message = function( msg ){ + self.$indicator.find( 'i' ).text( msg ); }; self.hide = function( speed, callback ){ speed = speed || 'fast'; - //$whatIsLoading.fadeTo( speed, 1.0, function(){ - // if( callback ){ callback(); } - //}); - $indicator.fadeOut( speed, callback ); + if( self.$indicator && self.$indicator.size() ){ + self.$indicator.fadeOut( speed, function(){ + self.$indicator.remove(); + if( callback ){ callback(); } + }); + } else { + if( callback ){ callback(); } + } return self; }; - $indicator = render(); return self; } - diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 static/scripts/mvc/dataset/hda-base.js --- a/static/scripts/mvc/dataset/hda-base.js +++ b/static/scripts/mvc/dataset/hda-base.js @@ -19,7 +19,8 @@ //logger : console, tagName : "div", - className : "historyItemContainer", + className : "dataset hda history-panel-hda", + id : function(){ return 'hda-' + this.model.get( 'id' ); }, fxSpeed : 'fast', @@ -67,55 +68,50 @@ // ......................................................................... render main /** Render this HDA, set up ui. - * @fires rendered:ready when rendered and NO running HDAs - * @fires rendered when rendered and running HDAs - * @fires rendered:initial on first render with running HDAs - * @fires rendered:initial:ready when first rendered and NO running HDAs + * @param {Boolean} fade whether or not to fade out/in when re-rendering + * @fires rendered when rendered + * @fires rendered:ready when first rendered and NO running HDAs * @returns {Object} this HDABaseView */ - render : function(){ - var view = this, - id = this.model.get( 'id' ), - state = this.model.get( 'state' ), - itemWrapper = $( '<div/>' ).attr( 'id', 'historyItem-' + id ), - initialRender = ( this.$el.children().size() === 0 ); - - this.$el.attr( 'id', 'historyItemContainer-' + id ); + render : function( fade ){ + fade = ( fade === undefined )?( true ):( fade ); + var view = this; //HACK: hover exit doesn't seem to be called on prev. tooltips when RE-rendering - so: no tooltip hide // handle that here by removing previous view's tooltips this.$el.find("[title]").tooltip( "destroy" ); - /** web controller urls for functions relating to this hda. */ + // re-get web controller urls for functions relating to this hda. (new model data may have changed this) this.urls = this.model.urls(); - itemWrapper - .addClass( 'historyItemWrapper' ).addClass( 'historyItem' ) - .addClass( 'historyItem-' + state ); + // create a new render using a skeleton template, render title buttons, render body, and set up events, etc. + var $newRender = $( HDABaseView.templates.skeleton( this.model.toJSON() ) ); + $newRender.find( '.dataset-primary-actions' ).append( this._render_titleButtons() ); + $newRender.children( '.dataset-body' ).replaceWith( this._render_body() ); + this._setUpBehaviors( $newRender ); - itemWrapper.append( this._render_warnings() ); - itemWrapper.append( this._render_titleBar() ); - - //NOTE: only sets behaviors on title and warnings - body will set up it's own - this._setUpBehaviors( itemWrapper ); - - this.body = $( this._render_body() ); - itemWrapper.append( this.body ); - - // transition... - this.$el.fadeOut( this.fxSpeed, function(){ - view.$el.children().remove(); - view.$el.append( itemWrapper ).fadeIn( view.fxSpeed, function(){ - view.log( view + ' rendered:', view.$el ); - - var renderedEventName = 'rendered'; - if( initialRender ){ - renderedEventName += ':initial'; - } else if( view.model.inReadyState() ){ - renderedEventName += ':ready'; - } - view.trigger( renderedEventName ); - }); + // fade the old render out (if desired) + if( fade ){ + $( view ).queue( function( next ){ this.$el.fadeOut( view.fxSpeed, next ); }); + } + // empty the old render, update to any new HDA state, swap in the new render contents + $( view ).queue( function( next ){ + this.$el.empty() + .attr( 'class', view.className ).addClass( 'state-' + view.model.get( 'state' ) ) + .append( $newRender.children() ); + next(); + }); + // fade the new in + if( fade ){ + $( view ).queue( function( next ){ this.$el.fadeIn( view.fxSpeed, next ); }); + } + // trigger an event to know we're ready + $( view ).queue( function( next ){ + this.trigger( 'rendered', view ); + if( this.model.inReadyState() ){ + this.trigger( 'rendered:ready', view ); + } + next(); }); return this; }, @@ -130,35 +126,39 @@ $container.find( '[title]' ).tooltip({ placement : 'bottom' }); }, - // ................................................................................ RENDER titlebar - /** Render any hda warnings including: is deleted, is purged, is hidden. - * (including links to further actions (undelete, etc.)) - * @returns {jQuery} rendered DOM - */ - _render_warnings : function(){ - // jQ errs on building dom with whitespace - if there are no messages, trim -> '' - return $( jQuery.trim( HDABaseView.templates.messages( this.model.toJSON() ))); - }, - - /** Render the part of an hda always shown (whether the body is expanded or not): title link, title buttons. - * @returns {jQuery} rendered DOM - */ - _render_titleBar : function(){ - var titleBar = $( '<div class="historyItemTitleBar" style="overflow: hidden"></div>' ); - titleBar.append( this._render_titleButtons() ); - titleBar.append( '<span class="state-icon"></span>' ); - titleBar.append( this._render_titleLink() ); - return titleBar; - }, - + // ................................................................................ titlebar buttons /** Render icon-button group for the common, most easily accessed actions. * @returns {jQuery} rendered DOM */ _render_titleButtons : function(){ - // render the display, edit attr and delete icon-buttons - var buttonDiv = $( '<div class="historyItemButtons"></div>' ); - buttonDiv.append( this._render_displayButton() ); - return buttonDiv; + // render just the display for read-only + return [ this._render_displayButton() ]; + }, + + _render_iconButton : function( options ){ + options = options || {}; + //options.classes = [ 'icon-button', 'menu-button' ].concat( options.classes || [] ); + options.classes = [ 'icon-btn' ].concat( options.classes || [] ); + //options.classes = [ 'btn' ].concat( options.classes || [] ); + //options.classes = options.classes || []; + if( options.disabled ){ + options.classes.push( 'disabled' ); + } + + var button = [ + '<a class="', options.classes.join( ' ' ), '"', + (( options.title )? ( ' title="' + options.title + '"' ):( '' )), + (( options.target )? ( ' target="' + options.target + '"' ):( '' )), + ' href="', (( options.href )?( options.href ):( 'javascript:void(0);' )), '">', + // could go with something less specific here - like 'html' + '<span class="', options.faIcon, '"></span>', + '</a>' + ].join( '' ); + button = $( button ); + if( _.isFunction( options.onClick ) ){ + button.click( options.onClick ); + } + return button; }, /** Render icon-button to display this hda in the galaxy main iframe. @@ -168,12 +168,12 @@ // don't show display if not viewable or not accessible // (do show if in error, running) if( ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NOT_VIEWABLE ) + || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.DISCARDED ) || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NEW ) || ( !this.model.get( 'accessible' ) ) ){ this.displayButton = null; return null; } - //NOTE: line 88 in history_common.mako should be handled by the url template generation var displayBtnData = { icon_class : 'display', @@ -198,7 +198,7 @@ // add frame manager option onclick event var self = this; - displayBtnData.on_click = function(){ + displayBtnData.onClick = function(){ Galaxy.frame_manager.frame_new({ title : "Data Viewer: " + self.model.get('name'), type : "url", @@ -210,52 +210,48 @@ this.displayButton = new IconButtonView({ model : new IconButton( displayBtnData ) }); return this.displayButton.render().$el; + //displayBtnData.faIcon = 'fa-icon-eye-open'; + //return this._render_iconButton( displayBtnData ); }, - /** Render the hid and hda.name as a link (that will expand the body). - * @returns {jQuery} rendered DOM - */ - _render_titleLink : function(){ - return $( jQuery.trim( HDABaseView.templates.titleLink( this.model.toJSON() ))); - }, - - // ......................................................................... body - /** Render the data/metadata summary (format, size, misc info, etc.). - * @returns {jQuery} rendered DOM - */ - _render_hdaSummary : function(){ - var modelData = _.extend( this.model.toJSON(), { urls: this.urls } ); - return HDABaseView.templates.hdaSummary( modelData ); - }, - // ......................................................................... primary actions - /** Render the icon-buttons gen. placed underneath the hda summary (e.g. download, show params, etc.) - * @param {Array} buttonRenderingFuncs array of rendering functions appending the results in order - * @returns {jQuery} rendered DOM - */ - _render_primaryActionButtons : function( buttonRenderingFuncs ){ - var view = this, - primaryActionButtons = $( '<div/>' ).attr( 'id', 'primary-actions-' + this.model.get( 'id' ) ); - _.each( buttonRenderingFuncs, function( fn ){ - primaryActionButtons.append( fn.call( view ) ); - }); - return primaryActionButtons; - }, - /** Render icon-button/popupmenu to download the data (and/or the associated meta files (bai, etc.)) for this hda. * @returns {jQuery} rendered DOM */ _render_downloadButton : function(){ // don't show anything if the data's been purged if( this.model.get( 'purged' ) || !this.model.hasData() ){ return null; } - + var urls = this.urls, + meta_files = this.model.get( 'meta_files' ); + // return either: a single download icon-button (if there are no meta files) + if( _.isEmpty( meta_files ) ){ + return $([ '<a href="', urls.download, '" title="', _l( 'Download' ), + '" class="icon-button disk"></a>' ].join( '' ) ); + } + // or a popupmenu with links to download assoc. meta files (if there are meta files) - var downloadLinkHTML = HDABaseView.templates.downloadLinks( - _.extend( this.model.toJSON(), { urls: this.urls } ) - ); - //this.log( this + '_render_downloadButton, downloadLinkHTML:', downloadLinkHTML ); - return $( downloadLinkHTML.trim() ); +//TODO: Popupmenu + var menuId = 'dataset-' + this.model.get( 'id' ) + '-popup', + html = [ + '<div popupmenu="' + menuId + '">', + '<a class="action-button" href="' + urls.download + '">', _l( 'Download Dataset' ), '</a>', + '<a>' + _l( 'Additional Files' ) + '</a>', + + _.map( meta_files, function( meta_file ){ + return [ + '<a class="action-button" href="', urls.meta_download + meta_file.file_type, '">', + _l( 'Download' ), ' ', meta_file.file_type, + '</a>' + ].join( '' ); + }).join( '\n' ), + + '</div>', + '<div style="float:left;" class="menubutton split popup" id="' + menuId + '">', + '<a href="' + urls.download + '" title="' + _l( 'Download' ) + '" class="icon-button disk"></a>', + '</div>' + ].join( '\n' ); + return $( html ); }, /** Render icon-button to show the input and output (stdout/err) for the job that created this hda. @@ -263,62 +259,12 @@ */ _render_showParamsButton : function(){ // gen. safe to show in all cases - this.showParamsButton = new IconButtonView({ model : new IconButton({ + return new IconButtonView({ model : new IconButton({ title : _l( 'View details' ), href : this.urls.show_params, target : 'galaxy_main', icon_class : 'information' - }) }); - return this.showParamsButton.render().$el; - }, - - // ......................................................................... other elements - /** Render the area for display application links. - * @returns {jQuery} rendered DOM - */ - _render_displayAppArea : function(){ - return $( '<div/>' ).addClass( 'display-apps' ); - }, - - /** Render links to external genome display applications (igb, gbrowse, etc.). - * @param {jQuery} $parent the jq node to search for .display-apps and render into to (defaults to this.$el) - */ -//TODO: move into visualization button - _render_displayApps : function( $parent ){ - $parent = $parent || this.$el; - var $displayAppsDiv = $parent.find( 'div.display-apps' ), - display_types = this.model.get( 'display_types' ), - display_apps = this.model.get( 'display_apps' ); - - if( ( !this.model.hasData() ) - || ( !$parent || !$parent.length ) - || ( !$displayAppsDiv.length ) ){ - return; - } - - $displayAppsDiv.html( null ); - if( !_.isEmpty( display_types ) ){ - //this.log( this + 'display_types:', this.model.get( 'urls' ).display_types ); - $displayAppsDiv.append( HDABaseView.templates.displayApps({ displayApps : display_types }) ); - } - if( !_.isEmpty( display_apps ) ){ - //this.log( this + 'display_apps:', this.model.get( 'urls' ).display_apps ); - $displayAppsDiv.append( HDABaseView.templates.displayApps({ displayApps : display_apps }) ); - } - }, - - /** Render the data peek. - * @returns {jQuery} rendered DOM - */ - _render_peek : function(){ - var peek = this.model.get( 'peek' ); - if( !peek ){ return null; } - return $( '<div/>' ).append( - $( '<pre/>' ) - .attr( 'id', 'peek' + this.model.get( 'id' ) ) - .addClass( 'peek' ) - .append( peek ) - ); + }) }).render().$el; }, // ......................................................................... state body renderers @@ -326,169 +272,142 @@ * @returns {jQuery} rendered DOM */ _render_body : function(){ - var $body = $( '<div/>' ) - .attr( 'id', 'info-' + this.model.get( 'id' ) ) - .addClass( 'historyItemBody' ) - .attr( 'style', 'display: none' ); - + var $body = $( '<div>Error: unknown dataset state "' + this.model.get( 'state' ) + '".</div>' ), + // cheesy: get function by assumed matching name + renderFn = this[ '_render_body_' + this.model.get( 'state' ) ]; + if( _.isFunction( renderFn ) ){ + $body = renderFn.call( this ); + } + // only render the body html if it's being shown if( this.expanded ){ - // only render the body html if it's being shown - this._render_body_html( $body ); $body.show(); } return $body; }, - /** Render the (expanded) body of an HDA, dispatching to other functions based on the HDA state - * @param {jQuery} body the body element to append the html to - */ - _render_body_html : function( $body ){ - //this.log( this + '_render_body' ); - $body.empty(); - - var modelState = this.model.get( 'state' ); - // cheesy get function by assumed matching name - var renderFnName = '_render_body_' + modelState, - renderFn = this[ renderFnName ]; - if( _.isFunction( renderFn ) ){ - this[ renderFnName ]( $body ); - } else { - $body.append( $( '<div>Error: unknown dataset state "' + this.model.get( 'state' ) + '".</div>' ) ); - } - $body.append( '<div style="clear: both"></div>' ); - this._setUpBehaviors( $body ); + /** helper for rendering the body in the common cases */ + _render_stateBodyHelper : function( body, primaryButtonArray ){ + primaryButtonArray = primaryButtonArray || []; + var view = this, + $body = $( HDABaseView.templates.body( _.extend( this.model.toJSON(), { body: body }))); + $body.find( '.dataset-actions .left' ).append( + _.map( primaryButtonArray, function( renderingFn ){ + return renderingFn.call( view ); + }) + ); + return $body; }, /** Render a new dataset - this should be a transient state that's never shown * in case it does tho, we'll make sure there's some information here * @param {jQuery} parent DOM to which to append this body */ - _render_body_new : function( parent ){ - var newMsg = _l( 'This is a new dataset and not all of its data are available yet' ); - parent.append( $( '<div>' + _l( newMsg ) + '</div>' ) ); + _render_body_new : function(){ + return this._render_stateBodyHelper( + '<div>' + _l( 'This is a new dataset and not all of its data are available yet' ) + '</div>' + ); + }, + /** Render inaccessible, not-owned by curr user. */ + _render_body_noPermission : function(){ + return this._render_stateBodyHelper( + '<div>' + _l( 'You do not have permission to view this dataset' ) + '</div>' + ); + }, + /** Render an HDA which was deleted during upload. */ + _render_body_discarded : function(){ + return this._render_stateBodyHelper( + '<div>' + _l( 'The job creating this dataset was cancelled before completion' ) + '</div>', + this.defaultPrimaryActionButtonRenderers + ); + }, + /** Render an HDA whose job is queued. */ + _render_body_queued : function(){ + return this._render_stateBodyHelper( + '<div>' + _l( 'This job is waiting to run' ) + '</div>', + this.defaultPrimaryActionButtonRenderers + ); + }, + /** Render an HDA still being uploaded. */ + _render_body_upload : function(){ + return this._render_stateBodyHelper( '<div>' + _l( 'This dataset is currently uploading' ) + '</div>' ); + }, + /** Render an HDA where the metadata is still being determined. */ + _render_body_setting_metadata : function(){ + return this._render_stateBodyHelper( '<div>' + _l( 'Metadata is being auto-detected' ) + '</div>' ); + }, + /** Render an HDA whose job is running. */ + _render_body_running : function(){ + return this._render_stateBodyHelper( + '<div>' + _l( 'This job is currently running' ) + '</div>', + this.defaultPrimaryActionButtonRenderers + ); + }, + /** Render an HDA whose job is paused. */ + _render_body_paused: function(){ + return this._render_stateBodyHelper( + '<div>' + _l( 'This job is paused. Use the "Resume Paused Jobs" in the history menu to resume' ) + '</div>', + this.defaultPrimaryActionButtonRenderers + ); }, - /** Render inaccessible, not-owned by curr user. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_noPermission : function( parent ){ - parent.append( $( '<div>' + _l( 'You do not have permission to view this dataset' ) + '</div>' ) ); - }, - - /** Render an HDA still being uploaded. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_upload : function( parent ){ - parent.append( $( '<div>' + _l( 'Dataset is uploading' ) + '</div>' ) ); + /** Render an HDA whose job has failed. */ + _render_body_error : function(){ + var html = _l( 'An error occurred with this dataset' ) + + ': <i>' + $.trim( this.model.get( 'misc_info' ) ) + '</i>'; + if( !this.model.get( 'purged' ) ){ + html = '<div>' + this.model.get( 'misc_blurb' ) + '</div>' + html; + } + return this._render_stateBodyHelper( html, + this.defaultPrimaryActionButtonRenderers.concat([ this._render_downloadButton ]) + ); }, - /** Render an HDA whose job is queued. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_queued : function( parent ){ - parent.append( $( '<div>' + _l( 'Job is waiting to run' ) + '</div>' ) ); - parent.append( this._render_primaryActionButtons( this.defaultPrimaryActionButtonRenderers )); - }, - - /** Render an HDA whose job is paused. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_paused: function( parent ){ - parent.append( $( '<div>' + _l( 'Job is paused. ' - + 'Use the "Resume Paused Jobs" in the history menu to resume' ) + '</div>' ) ); - parent.append( this._render_primaryActionButtons( this.defaultPrimaryActionButtonRenderers )); + /** Render an empty/no data HDA. */ + _render_body_empty : function(){ + return this._render_stateBodyHelper( + '<div>' + _l( 'No data' ) + ': <i>' + this.model.get( 'misc_blurb' ) + '</i></div>', + this.defaultPrimaryActionButtonRenderers + ); }, - /** Render an HDA whose job is running. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_running : function( parent ){ - parent.append( '<div>' + _l( 'Job is currently running' ) + '</div>' ); - parent.append( this._render_primaryActionButtons( this.defaultPrimaryActionButtonRenderers )); - }, - - /** Render an HDA whose job has failed. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_error : function( parent ){ - if( !this.model.get( 'purged' ) ){ - parent.append( $( '<div>' + this.model.get( 'misc_blurb' ) + '</div>' ) ); - } - parent.append( ( _l( 'An error occurred with this dataset' ) + ': ' - + '<i>' + $.trim( this.model.get( 'misc_info' ) ) + '</i>' ) ); - parent.append( this._render_primaryActionButtons( - this.defaultPrimaryActionButtonRenderers.concat([ this._render_downloadButton ]) - )); - }, - - /** Render an HDA which was deleted during upload. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_discarded : function( parent ){ - parent.append( '<div>' + _l( 'The job creating this dataset was cancelled before completion' ) + '.</div>' ); - parent.append( this._render_primaryActionButtons( this.defaultPrimaryActionButtonRenderers )); - }, - - /** Render an HDA where the metadata is still being determined. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_setting_metadata : function( parent ){ - parent.append( $( '<div>' + _l( 'Metadata is being auto-detected' ) + '.</div>' ) ); - }, - - /** Render an empty/no data HDA. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_empty : function( parent ){ - parent.append( $( '<div>' + _l( 'No data' ) + ': <i>' + this.model.get( 'misc_blurb' ) + '</i></div>' ) ); - parent.append( this._render_primaryActionButtons( this.defaultPrimaryActionButtonRenderers )); - }, - - /** Render an HDA where the metadata wasn't produced correctly. - * @param {jQuery} parent DOM to which to append this body - */ - _render_body_failed_metadata : function( parent ){ - // add a message box about the failure at the top of the body... - parent.append( $( HDABaseView.templates.failedMetadata( - _.extend( this.model.toJSON(), { urls: this.urls } ) - ))); - //...then render the remaining body as STATES.OK (only diff between these states is the box above) - this._render_body_ok( parent ); + /** Render an HDA where the metadata wasn't produced correctly. */ + _render_body_failed_metadata : function(){ + // add a message box about the failure at the top of the body then render the remaining body as STATES.OK + var $warning = $( '<div class="warningmessagesmall"></div>' ) + .append( $( '<strong/>' ).text( _l( 'An error occurred setting the metadata for this dataset' ) ) ), + $body = this._render_body_ok(); + $body.prepend( $warning ); + return $body; }, /** Render an HDA that's done running and where everything worked. * @param {jQuery} parent DOM to which to append this body */ - _render_body_ok : function( parent ){ + _render_body_ok : function(){ // most common state renderer and the most complicated - parent.append( this._render_hdaSummary() ); + var view = this, + $body = $( HDABaseView.templates.body( this.model.toJSON() ) ), + // prepend the download btn to the defaults and render + btnRenderers = [ this._render_downloadButton ].concat( this.defaultPrimaryActionButtonRenderers ); + $body.find( '.dataset-actions .left' ).append( + _.map( btnRenderers, function( renderingFn ){ + return renderingFn.call( view ); + })); - // return shortened form if del'd + // return shortened form if del'd (no display apps or peek?) if( this.model.isDeletedOrPurged() ){ - parent.append( this._render_primaryActionButtons([ - this._render_downloadButton, - this._render_showParamsButton - ])); - return; + return $body; } - - //NOTE: change the order here - parent.append( this._render_primaryActionButtons([ - this._render_downloadButton, - this._render_showParamsButton - ])); - parent.append( '<div class="clear"/>' ); - - parent.append( this._render_displayAppArea() ); - this._render_displayApps( parent ); - parent.append( this._render_peek() ); + + //this._render_displayApps( $body.children( '.dataset-display-applications' ) ); + return $body; }, // ......................................................................... events /** event map */ events : { // expand the body when the title is clicked - 'click .historyItemTitle' : 'toggleBodyVisibility' + 'click .dataset-title-bar' : 'toggleBodyVisibility' }, /** Show or hide the body/details of an HDA. @@ -499,7 +418,8 @@ * @fires body-collapsed when a body has been collapsed */ toggleBodyVisibility : function( event, expand ){ - expand = ( expand === undefined )?( !this.body.is( ':visible' ) ):( expand ); + var $body = this.$el.find( '.dataset-body' ); + expand = ( expand === undefined )?( !$body.is( ':visible' ) ):( expand ); if( expand ){ this.expandBody(); } else { @@ -514,15 +434,14 @@ var hdaView = this; function _renderBodyAndExpand(){ - hdaView._render_body_html( hdaView.body ); - hdaView.body.slideDown( hdaView.fxSpeed, function(){ + hdaView.render( false ).$el.children( '.dataset-body' ).slideDown( hdaView.fxSpeed, function(){ hdaView.expanded = true; hdaView.trigger( 'body-expanded', hdaView.model.get( 'id' ) ); }); } // fetch first if no details in the model if( this.model.inReadyState() && !this.model.hasDetails() ){ - this.model.fetch().done( function( model ){ + this.model.fetch({ silent: true }).always( function( model ){ _renderBodyAndExpand(); }); } else { @@ -535,7 +454,7 @@ */ collapseBody : function(){ var hdaView = this; - this.body.slideUp( hdaView.fxSpeed, function(){ + this.$el.children( '.dataset-body' ).slideUp( hdaView.fxSpeed, function(){ hdaView.expanded = false; hdaView.trigger( 'body-collapsed', hdaView.model.get( 'id' ) ); }); @@ -564,14 +483,8 @@ //------------------------------------------------------------------------------ TEMPLATES HDABaseView.templates = { - warningMsg : Handlebars.templates[ 'template-warningmessagesmall' ], - - messages : Handlebars.templates[ 'template-hda-warning-messages' ], - titleLink : Handlebars.templates[ 'template-hda-titleLink' ], - hdaSummary : Handlebars.templates[ 'template-hda-hdaSummary' ], - downloadLinks : Handlebars.templates[ 'template-hda-downloadLinks' ], - failedMetadata : Handlebars.templates[ 'template-hda-failedMetadata' ], - displayApps : Handlebars.templates[ 'template-hda-displayApps' ] + skeleton : Handlebars.templates[ 'template-hda-skeleton' ], + body : Handlebars.templates[ 'template-hda-body' ] }; //============================================================================== diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 static/scripts/mvc/dataset/hda-edit.js --- a/static/scripts/mvc/dataset/hda-edit.js +++ b/static/scripts/mvc/dataset/hda-edit.js @@ -34,28 +34,6 @@ ]; }, - /** Set up js behaviors, event handlers for elements within the given container. - * Overridden from hda-base. - * @param {jQuery} $container jq object that contains the elements to process (defaults to this.$el) - */ - _setUpBehaviors : function( $container ){ - hdaBase.HDABaseView.prototype._setUpBehaviors.call( this, $container ); - //var hdaView = this; - }, - - // ......................................................................... render warnings - /** Render any hda warnings including: is deleted, is purged, is hidden. - * Overrides _render_warnings to include links to further actions (undelete, etc.)). - * @returns {Object} the templated urls - * @see HDABaseView#_render_warnings - */ - _render_warnings : function(){ - // jQ errs on building dom with whitespace - if there are no messages, trim -> '' - return $( jQuery.trim( hdaBase.HDABaseView.templates.messages( - _.extend( this.model.toJSON(), { urls: this.urls } ) - ))); - }, - // ......................................................................... edit attr, delete /** Render icon-button group for the common, most easily accessed actions. * Overrides _render_titleButtons to include edit and delete buttons. @@ -64,11 +42,10 @@ */ _render_titleButtons : function(){ // render the display, edit attr and delete icon-buttons - var buttonDiv = $( '<div class="historyItemButtons"></div>' ); - buttonDiv.append( this._render_displayButton() ); - buttonDiv.append( this._render_editButton() ); - buttonDiv.append( this._render_deleteButton() ); - return buttonDiv; + return hdaBase.HDABaseView.prototype._render_titleButtons.call( this ).concat([ + this._render_editButton(), + this._render_deleteButton() + ]); }, //TODO: move titleButtons into state renderers, remove state checks in the buttons @@ -81,6 +58,7 @@ // DO show if in error (ala previous history panel) if( ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NEW ) || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.UPLOAD ) + || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.DISCARDED ) || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NOT_VIEWABLE ) || ( !this.model.get( 'accessible' ) ) ){ this.editButton = null; @@ -106,8 +84,11 @@ } } - this.editButton = new IconButtonView({ model : new IconButton( editBtnData ) }); - return this.editButton.render().$el; + //this.editButton = new IconButtonView({ model : new IconButton( editBtnData ) }); + //return this.editButton.render().$el; + return new IconButtonView({ model : new IconButton( editBtnData ) }).render().$el; + //editBtnData.faIcon = 'fa-icon-pencil'; + //return this._render_iconButton( editBtnData ); }, /** Render icon-button to delete this hda. @@ -123,12 +104,10 @@ } var self = this, - id = 'historyItemDeleter-' + self.model.get( 'id' ), delete_url = self.urls[ 'delete' ], deleteBtnData = { title : _l( 'Delete' ), href : delete_url, - id : id, icon_class : 'delete', on_click : function() { // ...bler... tooltips being left behind in DOM (hover out never called on deletion) @@ -143,24 +122,11 @@ enabled : false }; } - this.deleteButton = new IconButtonView({ model : new IconButton( deleteBtnData ) }); - return this.deleteButton.render().$el; - }, - - // ......................................................................... render body - /** Render the data/metadata summary (format, size, misc info, etc.). - * Overrides _render_hdaSummary to include edit link in dbkey. - * @see HDABaseView#_render_hdaSummary - * @returns {jQuery} rendered DOM - */ - _render_hdaSummary : function(){ - var modelData = _.extend( this.model.toJSON(), { urls: this.urls } ); - // if there's no dbkey and it's editable : pass a flag to the template to render a link to editing in the '?' - if( this.model.get( 'metadata_dbkey' ) === '?' - && !this.model.isDeletedOrPurged() ){ - _.extend( modelData, { dbkey_unknown_and_editable : true }); - } - return hdaBase.HDABaseView.templates.hdaSummary( modelData ); + //this.deleteButton = new IconButtonView({ model : new IconButton( deleteBtnData ) }); + //return this.deleteButton.render().$el; + return new IconButtonView({ model : new IconButton( deleteBtnData ) }).render().$el; + //deleteBtnData.faIcon = 'fa-icon-remove'; + //return this._render_iconButton( deleteBtnData ); }, // ......................................................................... primary actions @@ -173,26 +139,24 @@ return null; } - this.errButton = new IconButtonView({ model : new IconButton({ + return new IconButtonView({ model : new IconButton({ title : _l( 'View or report this error' ), href : this.urls.report_error, target : 'galaxy_main', icon_class : 'bug' - })}); - return this.errButton.render().$el; + })}).render().$el; }, /** Render icon-button to re-run the job that created this hda. * @returns {jQuery} rendered DOM */ _render_rerunButton : function(){ - this.rerunButton = new IconButtonView({ model : new IconButton({ + return new IconButtonView({ model : new IconButton({ title : _l( 'Run this job again' ), href : this.urls.rerun, target : 'galaxy_main', icon_class : 'arrow-circle' - }) }); - return this.rerunButton.render().$el; + }) }).render().$el; }, /** Render an icon-button or popupmenu based on the number of applicable visualizations @@ -309,24 +273,6 @@ }, // ......................................................................... secondary actions - /** Render secondary actions: currently tagging and annotation (if user is allowed). - * @param {Array} buttonRenderingFuncs array of rendering functions appending the results in order - * @returns {jQuery} rendered DOM - */ - _render_secondaryActionButtons : function( buttonRenderingFuncs ){ - // move to the right (same level as primary) - var secondaryActionButtons = $( '<div/>' ), - view = this; - secondaryActionButtons - .attr( 'style', 'float: right;' ) - .attr( 'id', 'secondary-actions-' + this.model.get( 'id' ) ); - - _.each( buttonRenderingFuncs, function( fn ){ - secondaryActionButtons.append( fn.call( view ) ); - }); - return secondaryActionButtons; - }, - /** Render icon-button to load and display tagging html. * @returns {jQuery} rendered DOM */ @@ -336,13 +282,12 @@ return null; } - this.tagButton = new IconButtonView({ model : new IconButton({ + return new IconButtonView({ model : new IconButton({ title : _l( 'Edit dataset tags' ), target : 'galaxy_main', href : this.urls.tags.get, icon_class : 'tags' - })}); - return this.tagButton.render().$el; + })}).render().$el; }, /** Render icon-button to load and display annotation html. @@ -354,74 +299,76 @@ return null; } - this.annotateButton = new IconButtonView({ model : new IconButton({ + return new IconButtonView({ model : new IconButton({ title : _l( 'Edit dataset annotation' ), target : 'galaxy_main', icon_class : 'annotate' - })}); - return this.annotateButton.render().$el; + })}).render().$el; }, // ......................................................................... state body renderers + /** Render an HDA where the metadata wasn't produced correctly. + * Overridden to add a link to dataset/edit + * @see HDABaseView#_render_body_failed_metadata + */ + _render_body_failed_metadata : function(){ + // add a message box about the failure at the top of the body then render the remaining body as STATES.OK + var $link = $( '<a/>' ).attr({ href: this.urls.edit, target: 'galaxy_main' }) + .text( _l( 'set it manually or retry auto-detection' ) ), + $span = $( '<span/>' ).text( _l( 'You may be able to' ) + ' ' ).append( $link ), + $body = hdaBase.HDABaseView.prototype._render_body_failed_metadata.call( this ); + $body.find( '.warningmessagesmall strong' ).append( $span ); + return $body; + }, + /** Render an HDA whose job has failed. * Overrides _render_body_error to prepend error report button to primary actions strip. - * @param {jQuery} parent DOM to which to append this body * @see HDABaseView#_render_body_error */ - _render_body_error : function( parent ){ - hdaBase.HDABaseView.prototype._render_body_error.call( this, parent ); - var primaryActions = parent.find( '#primary-actions-' + this.model.get( 'id' ) ); - primaryActions.prepend( this._render_errButton() ); + _render_body_error : function(){ + var $body = hdaBase.HDABaseView.prototype._render_body_error.call( this ); + $body.find( '.dataset-actions .left' ).prepend( this._render_errButton() ); + return $body; }, - + /** Render an HDA that's done running and where everything worked. * Overrides _render_body_ok to add tag/annotation functionality and additional primary actions * @param {jQuery} parent DOM to which to append this body * @see HDABaseView#_render_body_ok */ - _render_body_ok : function( parent ){ - // most common state renderer and the most complicated - parent.append( this._render_hdaSummary() ); + _render_body_ok : function(){ + var $body = hdaBase.HDABaseView.prototype._render_body_ok.call( this ); + // return shortened form if del'd + if( this.model.isDeletedOrPurged() ){ + return $body; + } + this.makeDbkeyEditLink( $body ); - // return shortened form if del'd - //TODO: is this correct? maybe only on purged - if( this.model.isDeletedOrPurged() ){ - parent.append( this._render_primaryActionButtons([ - this._render_downloadButton, - this._render_showParamsButton, - this._render_rerunButton - ])); - return; + // more actions/buttons + $body.find( '.dataset-actions .left' ).append( this._render_visualizationsButton() ); + $body.find( '.dataset-actions .right' ).append([ + this._render_tagButton(), + this._render_annotateButton() + ]); + return $body; + }, + + makeDbkeyEditLink : function( $body ){ + // make the dbkey a link to editing + if( this.model.get( 'metadata_dbkey' ) === '?' + && !this.model.isDeletedOrPurged() ){ + $body.find( '.dataset-dbkey .value' ).replaceWith( + $( '<a target="galaxy_main">?</a>' ).attr( 'href', this.urls.edit ) ); } - - //NOTE: change the order here - parent.append( this._render_primaryActionButtons([ - this._render_downloadButton, - this._render_showParamsButton, - this._render_rerunButton, - this._render_visualizationsButton - ])); - parent.append( this._render_secondaryActionButtons([ - this._render_tagButton, - this._render_annotateButton - ])); - parent.append( '<div class="clear"/>' ); - - parent.append( this._render_tagArea() ); - parent.append( this._render_annotationArea() ); - - parent.append( this._render_displayAppArea() ); - this._render_displayApps( parent ); - parent.append( this._render_peek() ); }, // ......................................................................... events /** event map */ events : { - 'click .historyItemTitle' : 'toggleBodyVisibility', - 'click .historyItemUndelete' : function( ev ){ this.model.undelete(); return false; }, - 'click .historyItemUnhide' : function( ev ){ this.model.unhide(); return false; }, - 'click .historyItemPurge' : 'confirmPurge', + 'click .dataset-title-bar' : 'toggleBodyVisibility', + 'click .dataset-undelete' : function( ev ){ this.model.undelete(); return false; }, + 'click .dataset-unhide' : function( ev ){ this.model.unhide(); return false; }, + 'click .dataset-purge' : 'confirmPurge', 'click a.icon-button.tags' : 'loadAndDisplayTags', 'click a.icon-button.annotate' : 'loadAndDisplayAnnotation' @@ -430,115 +377,87 @@ /** listener for item purge */ confirmPurge : function _confirmPurge( ev ){ //TODO: confirm dialog - this.model.purge({ url: this.urls.purge }); + this.model.purge(); return false; }, // ......................................................................... tags - /** Render area to display tags. - * @returns {jQuery} rendered DOM - */ -//TODO: into sub-MV - _render_tagArea : function(){ - if( !this.hasUser || !this.urls.tags.set ){ return null; } - return $( HDAEditView.templates.tagArea( - _.extend( this.model.toJSON(), { urls: this.urls } ) - ).trim() ); - }, - /** Find the tag area and, if initial: load the html (via ajax) for displaying them; otherwise, unhide/hide */ //TODO: into sub-MV loadAndDisplayTags : function( event ){ - //BUG: broken with latest - //TODO: this is a drop in from history.mako - should use MV as well this.log( this + '.loadAndDisplayTags', event ); var view = this, - tagArea = this.$el.find( '.tag-area' ), - tagElt = tagArea.find( '.tag-elt' ); + $tagArea = this.$el.find( '.tags-display' ), + $tagElt = $tagArea.find( '.tags' ); // Show or hide tag area; if showing tag area and it's empty, fill it. - if( tagArea.is( ":hidden" ) ){ - if( !jQuery.trim( tagElt.html() ) ){ + if( $tagArea.is( ":hidden" ) ){ + if( !jQuery.trim( $tagElt.html() ) ){ // Need to fill tag element. - $.ajax({ - //TODO: the html from this breaks a couple of times - url: this.urls.tags.get, - error: function( xhr, status, error ){ - view.log( "Tagging failed", xhr, status, error ); - view.trigger( 'error', view, xhr, {}, _l( "Tagging failed" ) ); - }, - success: function(tag_elt_html) { - tagElt.html(tag_elt_html); - tagElt.find("[title]").tooltip(); - tagArea.slideDown( view.fxSpeed ); - } + var xhr = $.ajax( this.urls.tags.get ); + xhr.fail( function( xhr, status, error ){ + view.log( "Tagging failed", xhr, status, error ); + view.trigger( 'error', view, xhr, {}, _l( "Tagging failed" ) ); + }); + xhr.done( function( tagHtml ){ + $tagElt.html( tagHtml ); + $tagElt.find( "[title]" ).tooltip(); + $tagArea.slideDown( view.fxSpeed ); }); } else { // Tag element is filled; show. - tagArea.slideDown( view.fxSpeed ); + $tagArea.slideDown( view.fxSpeed ); } } else { // Hide. - tagArea.slideUp( view.fxSpeed ); + $tagArea.slideUp( view.fxSpeed ); } return false; }, // ......................................................................... annotations - /** Render area to display annotation. - * @returns {jQuery} rendered DOM - */ -//TODO: into sub-MV - _render_annotationArea : function(){ - if( !this.hasUser || !this.urls.annotation.get ){ return null; } - return $( HDAEditView.templates.annotationArea( - _.extend( this.model.toJSON(), { urls: this.urls } ) - ).trim() ); - }, - /** Find the annotation area and, if initial: load the html (via ajax) for displaying them; otherwise, unhide/hide */ loadAndDisplayAnnotation : function( event ){ //TODO: this is a drop in from history.mako - should use MV as well this.log( this + '.loadAndDisplayAnnotation', event ); var view = this, - annotationArea = this.$el.find( '.annotation-area' ), - annotationElem = annotationArea.find( '.annotation-elt' ), + $annotationArea = this.$el.find( '.annotation-display' ), + $annotationElem = $annotationArea.find( '.annotation' ), setAnnotationUrl = this.urls.annotation.set; // Show or hide annotation area; if showing annotation area and it's empty, fill it. - if ( annotationArea.is( ":hidden" ) ){ - if( !jQuery.trim( annotationElem.html() ) ){ + if ( $annotationArea.is( ":hidden" ) ){ + if( !jQuery.trim( $annotationElem.html() ) ){ // Need to fill annotation element. - $.ajax({ - url: this.urls.annotation.get, - error: function(){ - view.log( "Annotation failed", xhr, status, error ); - view.trigger( 'error', view, xhr, {}, _l( "Annotation failed" ) ); - }, - success: function( htmlFromAjax ){ - if( htmlFromAjax === "" ){ - htmlFromAjax = "<em>" + _l( "Describe or add notes to dataset" ) + "</em>"; + var xhr = $.ajax( this.urls.annotation.get ); + xhr.fail( function( xhr, status, error ){ + view.log( "Annotation failed", xhr, status, error ); + view.trigger( 'error', view, xhr, {}, _l( "Annotation failed" ) ); + }); + xhr.done( function( html ){ + html = html || "<em>" + _l( "Describe or add notes to dataset" ) + "</em>"; + $annotationElem.html( html ); + $annotationArea.find( "[title]" ).tooltip(); + + $annotationElem.make_text_editable({ + use_textarea: true, + on_finish: function( newAnnotation ){ + $annotationElem.text( newAnnotation ); + view.model.save({ annotation: newAnnotation }, { silent: true }) + .fail( function(){ + $annotationElem.text( view.model.previous( 'annotation' ) ); + }); } - annotationElem.html( htmlFromAjax ); - annotationArea.find("[title]").tooltip(); - - async_save_text( - annotationElem.attr("id"), annotationElem.attr("id"), - setAnnotationUrl, - "new_annotation", 18, true, 4 - ); - annotationArea.slideDown( view.fxSpeed ); - } + }); + $annotationArea.slideDown( view.fxSpeed ); }); } else { - annotationArea.slideDown( view.fxSpeed ); + $annotationArea.slideDown( view.fxSpeed ); } - } else { - // Hide. - annotationArea.slideUp( view.fxSpeed ); + $annotationArea.slideUp( view.fxSpeed ); } return false; }, @@ -551,12 +470,6 @@ } }); -//------------------------------------------------------------------------------ -HDAEditView.templates = { - tagArea : Handlebars.templates[ 'template-hda-tagArea' ], - annotationArea : Handlebars.templates[ 'template-hda-annotationArea' ] -}; - //============================================================================== //TODO: these belong somewhere else diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 static/scripts/mvc/dataset/hda-model.js --- a/static/scripts/mvc/dataset/hda-model.js +++ b/static/scripts/mvc/dataset/hda-model.js @@ -68,8 +68,9 @@ 'purge' : galaxy_config.root + 'datasets/' + id + '/purge_async', 'display' : galaxy_config.root + 'datasets/' + id + '/display/?preview=True', + 'edit' : galaxy_config.root + 'datasets/' + id + '/edit', + 'download' : galaxy_config.root + 'datasets/' + id + '/display?to_ext=' + this.get( 'file_ext' ), - 'edit' : galaxy_config.root + 'datasets/' + id + '/edit', 'report_error' : galaxy_config.root + 'dataset/errors?id=' + id, 'rerun' : galaxy_config.root + 'tool_runner/rerun?id=' + id, 'show_params' : galaxy_config.root + 'datasets/' + id + '/show_params', @@ -80,19 +81,9 @@ 'tags' : { 'get': galaxy_config.root + 'tag/get_tagging_elt_async?item_id=' + id + '&item_class=HistoryDatasetAssociation', 'set': galaxy_config.root + 'tag/retag?item_id=' - + id + '&item_class=HistoryDatasetAssociation' } + + id + '&item_class=HistoryDatasetAssociation' }, + 'meta_download' : galaxy_config.root + 'dataset/get_metadata_file?hda_id=' + id + '&metadata_name=' }; - // download links to assoc. metadata files (bam indeces, etc.) - var meta_files = this.get( 'meta_files' ); - if( meta_files ){ - urls.meta_download = _.map( meta_files, function( meta_file ){ - return { - url : galaxy_config.root + 'dataset/get_metadata_file?hda_id=' - + id + '&metadata_name=' + meta_file.file_type, - file_type : meta_file.file_type - }; - }); - } return urls; }, @@ -173,6 +164,7 @@ }, // ........................................................................ ajax + /** save this HDA, _Mark_ing it as deleted (just a flag) */ 'delete' : function _delete( options ){ return this.save( { deleted: true }, options ); @@ -192,7 +184,11 @@ }, /** purge this HDA and remove the underlying dataset file from the server's fs */ +//TODO: use, override model.destroy, HDA.delete({ purge: true }) purge : function _purge( options ){ + options = options || {}; + options.url = galaxy_config.root + 'datasets/' + this.get( 'id' ) + '/purge_async'; + //TODO: ideally this would be a DELETE call to the api // using purge async for now var hda = this, @@ -337,11 +333,11 @@ initialize : function( models, options ){ options = options || {}; this.historyId = options.historyId; - this._setUpListeners(); + //this._setUpListeners(); }, - _setUpListeners : function(){ - }, + //_setUpListeners : function(){ + //}, // ........................................................................ common queries /** Get the ids of every hda in this collection diff -r dbb44b0f5b481ac249e9a3758667dff5bac518b3 -r 8c78de92633e5474b6a9107595042868fe250679 static/scripts/mvc/history/history-model.js --- a/static/scripts/mvc/history/history-model.js +++ b/static/scripts/mvc/history/history-model.js @@ -99,13 +99,6 @@ this.hdas.historyId = newId; } }, this ); - - // debugging events - //if( this.logger ){ - // this.on( 'all', function( event ){ - // this.log( this + '', arguments ); - // }, this ); - //} }, //TODO: see base-mvc @@ -220,7 +213,6 @@ function getHistory( id ){ // get the history data - //return jQuery.ajax( '/generate_json_error' ); return jQuery.ajax( galaxy_config.root + 'api/histories/' + historyId ); } function countHdasFromHistory( historyData ){ @@ -240,7 +232,6 @@ } var data = ( hdaDetailIds.length )?( { details : hdaDetailIds.join( ',' ) } ):( {} ); return jQuery.ajax( galaxy_config.root + 'api/histories/' + historyData.id + '/contents', { data: data }); - //return jQuery.ajax( '/generate_json_error' ); } // getting these concurrently is 400% slower (sqlite, local, vanilla) - so: @@ -258,7 +249,6 @@ }); historyXHR.fail( function( xhr, status, message ){ // call reject on the outer deferred to allow it's fail callback to run - //console.warn( 'getHistoryData.localFailHandler (history)', xhr, status, message ); df.reject( xhr, 'loading the history' ); }); @@ -270,7 +260,6 @@ }); hdaXHR.fail( function( xhr, status, message ){ // call reject on the outer deferred to allow it's fail callback to run - //console.warn( 'getHistoryData.localFailHandler (hdas)', xhr, status, message ); df.reject( xhr, 'loading the datasets', { history: historyJSON } ); }); This diff is so big that we needed to truncate the remainder. https://bitbucket.org/galaxy/galaxy-central/commits/31b15f0d3e80/ Changeset: 31b15f0d3e80 User: dannon Date: 2013-10-30 19:20:46 Summary: Merge. Affected #: 53 files diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/images/fonts/fontawesome-webfont.eot Binary file static/images/fonts/fontawesome-webfont.eot has changed diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/images/fonts/fontawesome-webfont.ttf Binary file static/images/fonts/fontawesome-webfont.ttf has changed diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/images/fonts/fontawesome-webfont.woff Binary file static/images/fonts/fontawesome-webfont.woff has changed diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/galaxy.frame.js --- a/static/scripts/galaxy.frame.js +++ b/static/scripts/galaxy.frame.js @@ -85,7 +85,7 @@ // add activate icon this.button_active = new mod_master.GalaxyMasterIcon ( { - icon : 'fa-icon-th', + icon : 'fa-th', tooltip : 'Enable/Disable Scratchbook', on_click : function(e) { self.event_panel_active(e) }, on_unload : function() { @@ -100,7 +100,7 @@ // add load icon this.button_load = new mod_master.GalaxyMasterIcon ( { - icon : 'fa-icon-eye-open', + icon : 'fa-eye', tooltip : 'Show/Hide Scratchbook', on_click : function(e) { self.event_panel_load(e) }, with_number : true @@ -724,7 +724,7 @@ $(".frame").fadeOut('fast'); // add class - this.button_load.icon("fa-icon-eye-close"); + this.button_load.icon("fa-eye-slash"); this.button_load.untoggle(); // hide background @@ -740,7 +740,7 @@ $(".frame").fadeIn('fast'); // add class - this.button_load.icon("fa-icon-eye-open"); + this.button_load.icon("fa-eye-open"); this.button_load.toggle(); // hide shadow @@ -1056,13 +1056,13 @@ return '<div id="' + id + '" class="frame corner">' + '<div class="f-header corner">' + '<span class="f-title">' + title + '</span>' + - '<span class="f-icon f-pin fa-icon-pushpin"></span>' + - '<span class="f-icon f-close fa-icon-trash"></span>' + + '<span class="f-icon f-pin fa fa-thumb-tack"></span>' + + '<span class="f-icon f-close fa fa-trash-o"></span>' + '</div>' + '<div class="f-content">' + content + '<div class="f-cover"></div>' + '</div>' + - '<span class="f-resize f-icon corner fa-icon-resize-full"></span>' + + '<span class="f-resize f-icon corner fa fa-resize-full"></span>' + '</div>'; }, @@ -1081,8 +1081,8 @@ // fill menu button template template_menu: function() { - return '<div class="frame-scroll-up frame-menu fa-icon-chevron-up fa-icon-2x"></div>' + - '<div class="frame-scroll-down frame-menu fa-icon-chevron-down fa-icon-2x"></div>'; + 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 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/galaxy.master.js --- a/static/scripts/galaxy.master.js +++ b/static/scripts/galaxy.master.js @@ -77,7 +77,7 @@ options: { id : "galaxy-icon", - icon : "fa-icon-cog", + icon : "fa-cog", tooltip : "galaxy-icon", with_number : false, on_click : function() { alert ('clicked') }, @@ -150,7 +150,7 @@ template: function (options) { var tmpl = '<div id=' + options.id + ' class="symbol">' + - '<div class="icon fa-icon-2x ' + options.icon + '"></div>'; + '<div class="icon fa fa-2x ' + options.icon + '"></div>'; if (options.with_number) tmpl+= '<div class="number"></div>'; tmpl += '</div>'; diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/galaxy.upload.js --- a/static/scripts/galaxy.upload.js +++ b/static/scripts/galaxy.upload.js @@ -25,11 +25,11 @@ // states state : { - init : 'fa-icon-trash', - queued : 'fa-icon-spinner fa-icon-spin', + init : 'fa fa-trash-o', + queued : 'fa fa-spinner fa-spin', running : '__running__', - success : 'fa-icon-ok', - error : 'fa-icon-warning-sign' + success : 'fa fa-check', + error : 'fa fa-exclamation-triangle' }, // counter @@ -66,7 +66,7 @@ var self = this; this.button_show = new mod_master.GalaxyMasterIcon ( { - icon : 'fa-icon-upload', + icon : 'fa-arrow-circle-o-up', tooltip : 'Upload Files', on_click : function(e) { self.event_show(e) }, on_unload : function() { diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/galaxy.workflow_editor.canvas.js --- a/static/scripts/galaxy.workflow_editor.canvas.js +++ b/static/scripts/galaxy.workflow_editor.canvas.js @@ -200,7 +200,7 @@ .appendTo( "body" ) .append( $("<div class='button'></div>").append( - $("<div/>").addClass("fa-icon-button fa-icon-remove").click( function() { + $("<div/>").addClass("fa-icon-button fa fa-times").click( function() { $.each( terminal.connectors, function( _, x ) { if (x) { x.destroy(); @@ -859,7 +859,7 @@ // Fix width to computed width // Now add floats var buttons = $("<div class='buttons' style='float: right;'></div>"); - buttons.append( $("<div>").addClass("fa-icon-button fa-icon-remove").click( function( e ) { + buttons.append( $("<div>").addClass("fa-icon-button fa fa-times").click( function( e ) { node.destroy(); })); // Place inside container diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/mvc/base-mvc.js --- a/static/scripts/mvc/base-mvc.js +++ b/static/scripts/mvc/base-mvc.js @@ -226,7 +226,7 @@ function render(){ var html = [ '<div class="loading-indicator">', - '<span class="fa-icon-spinner fa-icon-spin fa-icon-large" style="color: grey"></span>', + '<span class="fa fa-spinner fa-spin fa-lg" style="color: grey"></span>', '<span style="margin-left: 8px; color: grey"><i>loading...</i></span>', '</div>' ].join( '\n' ); diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/mvc/dataset/hda-base.js --- a/static/scripts/mvc/dataset/hda-base.js +++ b/static/scripts/mvc/dataset/hda-base.js @@ -135,32 +135,6 @@ return [ this._render_displayButton() ]; }, - _render_iconButton : function( options ){ - options = options || {}; - //options.classes = [ 'icon-button', 'menu-button' ].concat( options.classes || [] ); - options.classes = [ 'icon-btn' ].concat( options.classes || [] ); - //options.classes = [ 'btn' ].concat( options.classes || [] ); - //options.classes = options.classes || []; - if( options.disabled ){ - options.classes.push( 'disabled' ); - } - - var button = [ - '<a class="', options.classes.join( ' ' ), '"', - (( options.title )? ( ' title="' + options.title + '"' ):( '' )), - (( options.target )? ( ' target="' + options.target + '"' ):( '' )), - ' href="', (( options.href )?( options.href ):( 'javascript:void(0);' )), '">', - // could go with something less specific here - like 'html' - '<span class="', options.faIcon, '"></span>', - '</a>' - ].join( '' ); - button = $( button ); - if( _.isFunction( options.onClick ) ){ - button.click( options.onClick ); - } - return button; - }, - /** Render icon-button to display this hda in the galaxy main iframe. * @returns {jQuery} rendered DOM */ @@ -171,7 +145,6 @@ || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.DISCARDED ) || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NEW ) || ( !this.model.get( 'accessible' ) ) ){ - this.displayButton = null; return null; } @@ -182,12 +155,12 @@ // show a disabled display if the data's been purged if( this.model.get( 'purged' ) ){ - displayBtnData.enabled = false; + displayBtnData.disabled = true; displayBtnData.title = _l( 'Cannot display datasets removed from disk' ); // disable if still uploading } else if( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.UPLOAD ){ - displayBtnData.enabled = false; + displayBtnData.disabled = true; displayBtnData.title = _l( 'This dataset must finish uploading before it can be viewed' ); } else { @@ -198,7 +171,7 @@ // add frame manager option onclick event var self = this; - displayBtnData.onClick = function(){ + displayBtnData.on_click = function(){ Galaxy.frame_manager.frame_new({ title : "Data Viewer: " + self.model.get('name'), type : "url", @@ -207,11 +180,10 @@ }); }; } + //return new IconButtonView({ model : new IconButton( displayBtnData ) }).render().$el; - this.displayButton = new IconButtonView({ model : new IconButton( displayBtnData ) }); - return this.displayButton.render().$el; - //displayBtnData.faIcon = 'fa-icon-eye-open'; - //return this._render_iconButton( displayBtnData ); + displayBtnData.faIcon = 'fa-eye'; + return faIconButton( displayBtnData ); }, // ......................................................................... primary actions @@ -226,8 +198,12 @@ // return either: a single download icon-button (if there are no meta files) if( _.isEmpty( meta_files ) ){ - return $([ '<a href="', urls.download, '" title="', _l( 'Download' ), - '" class="icon-button disk"></a>' ].join( '' ) ); + return $([ + //'<a href="', urls.download, '" title="', _l( 'Download' ), '" class="icon-button disk"></a>' + '<a href="' + urls.download + '" title="' + _l( 'Download' ) + '" class="icon-btn">', + '<span class="fa fa-floppy-o"></span>', + '</a>' + ].join( '' ) ); } // or a popupmenu with links to download assoc. meta files (if there are meta files) @@ -235,7 +211,7 @@ var menuId = 'dataset-' + this.model.get( 'id' ) + '-popup', html = [ '<div popupmenu="' + menuId + '">', - '<a class="action-button" href="' + urls.download + '">', _l( 'Download Dataset' ), '</a>', + '<a href="' + urls.download + '">', _l( 'Download Dataset' ), '</a>', '<a>' + _l( 'Additional Files' ) + '</a>', _.map( meta_files, function( meta_file ){ @@ -245,10 +221,15 @@ '</a>' ].join( '' ); }).join( '\n' ), + '</div>', - '</div>', - '<div style="float:left;" class="menubutton split popup" id="' + menuId + '">', - '<a href="' + urls.download + '" title="' + _l( 'Download' ) + '" class="icon-button disk"></a>', + '<div class="icon-btn-group">', + '<a href="' + urls.download + '" title="' + _l( 'Download' ) + '" class="icon-btn">', + '<span class="fa fa-floppy-o"></span>', + // join these w/o whitespace or there'll be a gap when rendered + '</a><a class="icon-btn popup" id="' + menuId + '">', + '<span class="fa fa-caret-down"></span>', + '</a>', '</div>' ].join( '\n' ); return $( html ); @@ -259,12 +240,18 @@ */ _render_showParamsButton : function(){ // gen. safe to show in all cases - return new IconButtonView({ model : new IconButton({ + //return new IconButtonView({ model : new IconButton({ + // title : _l( 'View details' ), + // href : this.urls.show_params, + // target : 'galaxy_main', + // icon_class : 'information' + //}) }).render().$el; + return faIconButton({ title : _l( 'View details' ), href : this.urls.show_params, target : 'galaxy_main', - icon_class : 'information' - }) }).render().$el; + faIcon : 'fa-info-circle' + }); }, // ......................................................................... state body renderers @@ -272,6 +259,7 @@ * @returns {jQuery} rendered DOM */ _render_body : function(){ + console.debug( 'model:', this.model.toJSON() ); var $body = $( '<div>Error: unknown dataset state "' + this.model.get( 'state' ) + '".</div>' ), // cheesy: get function by assumed matching name renderFn = this[ '_render_body_' + this.model.get( 'state' ) ]; diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/mvc/dataset/hda-edit.js --- a/static/scripts/mvc/dataset/hda-edit.js +++ b/static/scripts/mvc/dataset/hda-edit.js @@ -57,11 +57,9 @@ // don't show edit while uploading, in-accessible // DO show if in error (ala previous history panel) if( ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NEW ) - || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.UPLOAD ) || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.DISCARDED ) || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NOT_VIEWABLE ) || ( !this.model.get( 'accessible' ) ) ){ - this.editButton = null; return null; } @@ -82,13 +80,18 @@ } else if( deleted ){ editBtnData.title = _l( 'Undelete dataset to edit attributes' ); } + + // disable if still uploading + } else if( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.UPLOAD ){ + editBtnData.disabled = true; + editBtnData.title = _l( 'This dataset must finish uploading before it can be edited' ); } + - //this.editButton = new IconButtonView({ model : new IconButton( editBtnData ) }); - //return this.editButton.render().$el; - return new IconButtonView({ model : new IconButton( editBtnData ) }).render().$el; - //editBtnData.faIcon = 'fa-icon-pencil'; - //return this._render_iconButton( editBtnData ); + //return new IconButtonView({ model : new IconButton( editBtnData ) }).render().$el; + + editBtnData.faIcon = 'fa-pencil'; + return faIconButton( editBtnData ); }, /** Render icon-button to delete this hda. @@ -99,7 +102,6 @@ if( ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NEW ) || ( this.model.get( 'state' ) === hdaModel.HistoryDatasetAssociation.STATES.NOT_VIEWABLE ) || ( !this.model.get( 'accessible' ) ) ){ - this.deleteButton = null; return null; } @@ -109,7 +111,7 @@ title : _l( 'Delete' ), href : delete_url, icon_class : 'delete', - on_click : function() { + onclick : function() { // ...bler... tooltips being left behind in DOM (hover out never called on deletion) self.$el.find( '.menu-button.delete' ).trigger( 'mouseout' ); self.model[ 'delete' ](); @@ -122,11 +124,10 @@ enabled : false }; } - //this.deleteButton = new IconButtonView({ model : new IconButton( deleteBtnData ) }); - //return this.deleteButton.render().$el; - return new IconButtonView({ model : new IconButton( deleteBtnData ) }).render().$el; - //deleteBtnData.faIcon = 'fa-icon-remove'; - //return this._render_iconButton( deleteBtnData ); + //return new IconButtonView({ model : new IconButton( deleteBtnData ) }).render().$el; + + deleteBtnData.faIcon = 'fa-times'; + return faIconButton( deleteBtnData ); }, // ......................................................................... primary actions @@ -135,28 +136,41 @@ */ _render_errButton : function(){ if( this.model.get( 'state' ) !== hdaModel.HistoryDatasetAssociation.STATES.ERROR ){ - this.errButton = null; return null; } - return new IconButtonView({ model : new IconButton({ + //return new IconButtonView({ model : new IconButton({ + // title : _l( 'View or report this error' ), + // href : this.urls.report_error, + // target : 'galaxy_main', + // icon_class : 'bug' + //})}).render().$el; + + return faIconButton({ title : _l( 'View or report this error' ), href : this.urls.report_error, target : 'galaxy_main', - icon_class : 'bug' - })}).render().$el; + faIcon : 'fa-bug' + }); }, /** Render icon-button to re-run the job that created this hda. * @returns {jQuery} rendered DOM */ _render_rerunButton : function(){ - return new IconButtonView({ model : new IconButton({ + //return new IconButtonView({ model : new IconButton({ + // title : _l( 'Run this job again' ), + // href : this.urls.rerun, + // target : 'galaxy_main', + // icon_class : 'arrow-circle' + //}) }).render().$el; + + return faIconButton({ title : _l( 'Run this job again' ), href : this.urls.rerun, target : 'galaxy_main', - icon_class : 'arrow-circle' - }) }).render().$el; + faIcon : 'fa-refresh' + }); }, /** Render an icon-button or popupmenu based on the number of applicable visualizations @@ -167,7 +181,6 @@ var visualizations = this.model.get( 'visualizations' ); if( ( !this.model.hasData() ) || ( _.isEmpty( visualizations ) ) ){ - this.visualizationsButton = null; return null; } @@ -178,7 +191,6 @@ } if( !this.urls.visualization ){ - this.visualizationsButton = null; return null; } @@ -193,13 +205,19 @@ if( dbkey ){ params.dbkey = dbkey; } // render the icon from template - this.visualizationsButton = new IconButtonView({ model : new IconButton({ + //var visualizationsButton = new IconButtonView({ model : new IconButton({ + // title : _l( 'Visualize' ), + // href : this.urls.visualization, + // icon_class : 'chart_curve' + //})}); + //var $icon = visualizationsButton.render().addClass( 'visualize-icon' ); // needed? + ////return visualizationsButton.render().$el; + + var $icon = faIconButton({ title : _l( 'Visualize' ), href : this.urls.visualization, - icon_class : 'chart_curve' - })}); - var $icon = this.visualizationsButton.render().$el; - $icon.addClass( 'visualize-icon' ); // needed? + faIcon : 'fa-bar-chart-o' + }); // map a function to each visualization in the icon's attributes // create a popupmenu from that map @@ -244,16 +262,19 @@ _render_visualizationsFrameworkButton : function( visualizations ){ if( !( this.model.hasData() ) || !( visualizations && !_.isEmpty( visualizations ) ) ){ - this.visualizationsButton = null; return null; } // render the icon from template - this.visualizationsButton = new IconButtonView({ model : new IconButton({ + //var visualizationsButton = new IconButtonView({ model : new IconButton({ + // title : _l( 'Visualize' ), + // icon_class : 'chart_curve' + //})}); + //var $icon = visualizationsButton.render().$el; + var $icon = faIconButton({ title : _l( 'Visualize' ), - icon_class : 'chart_curve' - })}); - var $icon = this.visualizationsButton.render().$el; + faIcon : 'fa-bar-chart-o' + }); $icon.addClass( 'visualize-icon' ); // needed? // No need for popup menu because there's a single visualization. @@ -278,16 +299,21 @@ */ _render_tagButton : function(){ if( !this.hasUser || !this.urls.tags.get ){ - this.tagButton = null; return null; } - return new IconButtonView({ model : new IconButton({ + //return new IconButtonView({ model : new IconButton({ + // title : _l( 'Edit dataset tags' ), + // target : 'galaxy_main', + // href : this.urls.tags.get, + // icon_class : 'tags' + //})}).render().$el; + + return faIconButton({ title : _l( 'Edit dataset tags' ), - target : 'galaxy_main', - href : this.urls.tags.get, - icon_class : 'tags' - })}).render().$el; + classes : 'dataset-tag-btn', + faIcon : 'fa-tags' + }); }, /** Render icon-button to load and display annotation html. @@ -295,15 +321,19 @@ */ _render_annotateButton : function(){ if( !this.hasUser || !this.urls.annotation.get ){ - this.annotateButton = null; return null; } - return new IconButtonView({ model : new IconButton({ + //return new IconButtonView({ model : new IconButton({ + // title : _l( 'Edit dataset annotation' ), + // target : 'galaxy_main', + // icon_class : 'annotate' + //})}).render().$el; + return faIconButton({ title : _l( 'Edit dataset annotation' ), - target : 'galaxy_main', - icon_class : 'annotate' - })}).render().$el; + classes : 'dataset-annotate-btn', + faIcon : 'fa-comment' + }); }, // ......................................................................... state body renderers @@ -315,7 +345,7 @@ // add a message box about the failure at the top of the body then render the remaining body as STATES.OK var $link = $( '<a/>' ).attr({ href: this.urls.edit, target: 'galaxy_main' }) .text( _l( 'set it manually or retry auto-detection' ) ), - $span = $( '<span/>' ).text( _l( 'You may be able to' ) + ' ' ).append( $link ), + $span = $( '<span/>' ).text( '. ' + _l( 'You may be able to' ) + ' ' ).append( $link ), $body = hdaBase.HDABaseView.prototype._render_body_failed_metadata.call( this ); $body.find( '.warningmessagesmall strong' ).append( $span ); return $body; @@ -365,13 +395,13 @@ // ......................................................................... events /** event map */ events : { - 'click .dataset-title-bar' : 'toggleBodyVisibility', - 'click .dataset-undelete' : function( ev ){ this.model.undelete(); return false; }, - 'click .dataset-unhide' : function( ev ){ this.model.unhide(); return false; }, - 'click .dataset-purge' : 'confirmPurge', + 'click .dataset-title-bar' : 'toggleBodyVisibility', + 'click .dataset-undelete' : function( ev ){ this.model.undelete(); return false; }, + 'click .dataset-unhide' : function( ev ){ this.model.unhide(); return false; }, + 'click .dataset-purge' : 'confirmPurge', - 'click a.icon-button.tags' : 'loadAndDisplayTags', - 'click a.icon-button.annotate' : 'loadAndDisplayAnnotation' + 'click .dataset-tag-btn' : 'loadAndDisplayTags', + 'click .dataset-annotate-btn' : 'loadAndDisplayAnnotation' }, /** listener for item purge */ @@ -424,8 +454,7 @@ this.log( this + '.loadAndDisplayAnnotation', event ); var view = this, $annotationArea = this.$el.find( '.annotation-display' ), - $annotationElem = $annotationArea.find( '.annotation' ), - setAnnotationUrl = this.urls.annotation.set; + $annotationElem = $annotationArea.find( '.annotation' ); // Show or hide annotation area; if showing annotation area and it's empty, fill it. if ( $annotationArea.is( ":hidden" ) ){ diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/mvc/dataset/hda-model.js --- a/static/scripts/mvc/dataset/hda-model.js +++ b/static/scripts/mvc/dataset/hda-model.js @@ -116,6 +116,13 @@ }, // ........................................................................ common queries + toJSON : function(){ + var json = Backbone.Model.prototype.toJSON.call( this ); + //HACK: this should be done on the server side when setting + json.misc_info = jQuery.trim( json.misc_info ); + return json; + }, + /** Is this hda deleted or purged? */ isDeletedOrPurged : function(){ return ( this.get( 'deleted' ) || this.get( 'purged' ) ); diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/mvc/history/history-panel.js --- a/static/scripts/mvc/history/history-panel.js +++ b/static/scripts/mvc/history/history-panel.js @@ -50,16 +50,7 @@ className : 'history-panel', /** (in ms) that jquery effects will use */ - //fxSpeed : 'fast', - fxSpeed : 400, - - /** event map */ - events : { - 'click .icon-button.tags' : 'loadAndDisplayTags', -//TODO: switch to common close (X) idiom - // allow (error) messages to be clicked away - 'click .message-container' : 'clearMessages' - }, + fxSpeed : 'fast', datasetsSelector : '.datasets-list', emptyMsgSelector : '.empty-history-message', @@ -616,7 +607,6 @@ }, function( next ){ //TODO: ideally, these would be set up before the fade in (can't because of async save text) - panel._setUpBehaviours(); if( callback ){ callback.call( this ); } panel.trigger( 'rendered', this ); } @@ -624,27 +614,6 @@ return this; }, - /** render with history data */ - renderModel : function( ){ - var $newRender = $( '<div/>' ); - // render the main template, tooltips - //NOTE: this is done before the items, since item views should handle theirs themselves - var templateFn = ( !Galaxy.currUser.isAnonymous() )?( HistoryPanel.templates.historyPanel ) - :( HistoryPanel.templates.anonHistoryPanel ); - $newRender.append( templateFn( this.model.toJSON() ) ); - - $newRender.find( '[title]' ).tooltip({ placement: 'bottom' }); - - // render hda views (if any and any shown (show_deleted/hidden) - //TODO: this seems too elaborate - if( !this.model.hdas.length - || !this.renderItems( $newRender.find( this.datasetsSelector ) ) ){ - // if history is empty or no hdas would be rendered, show the empty message - $newRender.find( this.emptyMsgSelector ).show(); - } - return $newRender; - }, - /** render with no history data */ renderWithoutModel : function( ){ // we'll always need the message container @@ -654,12 +623,119 @@ return $newRender.append( $msgContainer ); }, + /** render with history data */ + renderModel : function( ){ + var $newRender = $( '<div/>' ); + + // render based on anonymity, set up behaviors + if( Galaxy.currUser.isAnonymous() ){ + $newRender.append( HistoryPanel.templates.anonHistoryPanel( this.model.toJSON() ) ); + + } else { + $newRender.append( HistoryPanel.templates.historyPanel( this.model.toJSON() ) ); + $newRender.find( '.history-secondary-actions' ).append([ + this._render_tagButton(), + this._render_annotateButton() + ]); + } + this._setUpBehaviours( $newRender ); + + // render hda views (if any and any shown (show_deleted/hidden) + //TODO: this seems too elaborate + if( !this.model.hdas.length + || !this.renderHdas( $newRender.find( this.datasetsSelector ) ) ){ + // if history is empty or no hdas would be rendered, show the empty message + $newRender.find( this.emptyMsgSelector ).show(); + } + return $newRender; + }, + + /** Render icon-button to load and display tagging html. + * @returns {jQuery} rendered DOM + */ + _render_tagButton : function(){ + return faIconButton({ + title : _l( 'Edit history tags' ), + classes : 'history-tag-button', + faIcon : 'fa-tags' + }); + //return new IconButtonView({ model : new IconButton({ + // title : _l( 'Edit history tags' ), + // icon_class : 'tags' + //})}).render().$el; + }, + + /** Render icon-button to load and display annotation html. + * @returns {jQuery} rendered DOM + */ + _render_annotateButton : function(){ + return faIconButton({ + title : _l( 'Edit history tags' ), + classes : 'history-annotate-button', + faIcon : 'fa-comment' + }); + //return new IconButtonView({ model : new IconButton({ + // title : _l( 'Edit history annotation' ), + // icon_class : 'annotate' + //})}).render().$el; + }, + + /** Set up HistoryPanel js/widget behaviours + */ + //TODO: these should be either sub-MVs, or handled by events + _setUpBehaviours : function( $where ){ + $where = $where || this.$el; + $where.find( '[title]' ).tooltip({ placement: 'bottom' }); + + // anon users shouldn't have access to any of the following + if( !this.model || !Galaxy.currUser || Galaxy.currUser.isAnonymous() ){ return; } + + // annotation slide down + var panel = this, + // need specific selector ('annotation-display' is used in HDAs, too) + $historyAnnotationArea = $where.find( '.history-controls .annotation-display' ); + $where.find( '.history-controls .history-annotate-button' ).click( function() { + if( $historyAnnotationArea.is( ":hidden" ) ){ + //HACK: for whitespace added to annotation + var $anno = panel.$el.find( '.history-controls .annotation' ); + $anno.text( jQuery.trim( $anno.text() ) ); + $historyAnnotationArea.slideDown( panel.fxSpeed ); + + } else { + $historyAnnotationArea.slideUp( panel.fxSpeed ); + } + return false; + }); + //<em>{{#local}}Describe or add notes to history{{/local}}</em> + + $where.find( '.history-name' ).make_text_editable({ + on_finish: function( newName ){ + $where.find( '.history-name' ).text( newName ); + panel.model.save({ name: newName }) + .fail( function(){ + $where.find( '.history-name' ).text( panel.model.previous( 'name' ) ); + }); + } + }); + + $where.find( '.history-controls .annotation' ).make_text_editable({ + use_textarea : true, + on_finish: function( newAnnotation ){ + $where.find( '.history-controls .annotation' ).text( newAnnotation ); + panel.model.save({ annotation: newAnnotation }) + .fail( function(){ + $where.find( '.history-controls .annotation' ).text( panel.model.previous( 'annotation' ) ); + }); + } + }); + }, + /** Set up/render a view for each HDA to be shown, init with model and listeners. * HDA views are cached to the map this.hdaViews (using the model.id as key). * @param {jQuery} $whereTo what dom element to prepend the HDA views to * @returns the number of visible hda views */ - renderItems : function( $whereTo ){ + renderHdas : function( $whereTo ){ this.hdaViews = {}; var historyView = this, // only render the shown hdas @@ -676,49 +752,15 @@ return visibleHdas.length; }, - /** Set up HistoryPanel js/widget behaviours - */ - //TODO: these should be either sub-MVs, or handled by events - _setUpBehaviours : function(){ - // anon users shouldn't have access to any of these - if( !this.model || !Galaxy.currUser || Galaxy.currUser.isAnonymous() ){ return; } - - // annotation slide down - var panel = this, - // need specific selector ('annotation-display' is used in HDAs, too) - $historyAnnotationArea = this.$el.find( '.history-controls .annotation-display' ); - this.$el.find( '.history-controls .icon-button.annotate' ).click( function() { - if( $historyAnnotationArea.is( ":hidden" ) ){ - $historyAnnotationArea.slideDown( panel.fxSpeed ); - } else { - $historyAnnotationArea.slideUp( panel.fxSpeed ); - } - return false; - }); - - this.$el.find( '.history-name' ).make_text_editable({ - on_finish: function( newName ){ - panel.$el.find( '.history-name' ).text( newName ); - panel.model.save({ name: newName }) - .fail( function(){ - panel.$el.find( '.history-name' ).text( panel.model.previous( 'name' ) ); - }); - } - }); - - this.$el.find( '.history-controls .annotation' ).make_text_editable({ - use_textarea : true, - on_finish: function( newAnnotation ){ - panel.$el.find( '.history-controls .annotation' ).text( newAnnotation ); - panel.model.save({ annotation: newAnnotation }) - .fail( function(){ - panel.$el.find( '.history-controls .annotation' ).text( panel.model.previous( 'annotation' ) ); - }); - } - }); + // ------------------------------------------------------------------------ panel events + /** event map */ + events : { + 'click .history-tag-button' : 'loadAndDisplayTags', +//TODO: switch to common close (X) idiom + // allow (error) messages to be clicked away + 'click .message-container' : 'clearMessages' }, - // ------------------------------------------------------------------------ panel events /** Update the history size display (curr. upper right of panel). */ updateHistoryDiskSize : function(){ diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/mvc/ui.js --- a/static/scripts/mvc/ui.js +++ b/static/scripts/mvc/ui.js @@ -5,10 +5,8 @@ /** * backbone model for icon buttons */ -var IconButton = Backbone.Model.extend( -{ - defaults: - { +var IconButton = Backbone.Model.extend({ + defaults: { title : "", icon_class : "", on_click : null, @@ -26,105 +24,85 @@ /** * backbone view for icon buttons */ -var IconButtonView = Backbone.View.extend( -{ - // initialize - initialize: function() - { +var IconButtonView = Backbone.View.extend({ + + initialize : function(){ // better rendering this way this.model.attributes.tooltip_config = { placement : 'bottom' }; - this.model.bind('change', this.render, this); + this.model.bind( 'change', this.render, this ); }, - - // render - render: function() - { + + render : function( ){ // hide tooltip - this.$el.tooltip('hide'); + this.$el.tooltip( 'hide' ); - // create element - var new_elem = this.template(this.model.attributes); - + var new_elem = this.template( this.model.toJSON() ); // configure tooltip - new_elem.tooltip(this.model.get('tooltip_config')); - - // replace - this.$el.replaceWith(new_elem); - this.setElement(new_elem); - - // return + new_elem.tooltip( this.model.get( 'tooltip_config' )); + this.$el.replaceWith( new_elem ); + this.setElement( new_elem ); return this; }, - // events - events: - { + events : { 'click' : 'click' }, - // click - click: function( event ) - { + click : function( event ){ // if on_click pass to that function - if(this.model.attributes.on_click) - { - this.model.attributes.on_click(event); + if( _.isFunction( this.model.get( 'on_click' ) ) ){ + this.model.get( 'on_click' )( event ); return false; } - - // otherwise, bubble up (to href or whatever) + // otherwise, bubble up ( to href or whatever ) return true; }, // generate html element - template: function(options) - { - // initialize + template: function( options ){ var buffer = 'title="' + options.title + '" class="icon-button'; - // is menu button - if(options.is_menu_button) + if( options.is_menu_button ){ buffer += ' menu-button'; + } - // add icon class buffer += ' ' + options.icon_class; - // add enabled/disabled class - if(!options.enabled) + if( !options.enabled ){ buffer += '_disabled'; + } // close class tag buffer += '"'; - // add id - if(options.id) + if( options.id ){ buffer += ' id="' + options.id + '"'; + } - // add href buffer += ' href="' + options.href + '"'; - // add target for href - if(options.target) + if( options.target ){ buffer += ' target="' + options.target + '"'; - + } // set visibility - if(!options.visible) + if( !options.visible ){ buffer += ' style="display: none;"'; + } // enabled/disabled - if (options.enabled) + if ( options.enabled ){ buffer = '<a ' + buffer + '/>'; - else + } else { buffer = '<span ' + buffer + '/>'; + } // return element - return $(buffer); + return $( buffer ); } -}); +} ); // define collection -var IconButtonCollection = Backbone.Collection.extend( -{ +var IconButtonCollection = Backbone.Collection.extend({ model: IconButton }); @@ -132,24 +110,18 @@ * menu with multiple icon buttons * views are not needed nor used for individual buttons */ -var IconButtonMenuView = Backbone.View.extend( -{ - // tag +var IconButtonMenuView = Backbone.View.extend({ + tagName: 'div', - // initialize - initialize: function() - { + initialize: function(){ this.render(); }, - // render - render: function() - { + render: function(){ // initialize icon buttons var self = this; - this.collection.each(function(button) - { + this.collection.each(function(button){ // create and add icon button to menu var elt = $('<a/>').attr('href', 'javascript:void(0)') @@ -160,13 +132,15 @@ .click(button.attributes.on_click); // configure tooltip - if (button.attributes.tooltip_config) + if (button.attributes.tooltip_config){ elt.tooltip(button.attributes.tooltip_config); + } // add popup menu to icon var menu_options = button.get('options'); - if (menu_options) + if (menu_options){ make_popupmenu(elt, menu_options); + } }); // return @@ -187,8 +161,7 @@ // create and initialize menu var buttons = new IconButtonCollection( - _.map(config, function(button_config) - { + _.map(config, function(button_config){ return new IconButton(_.extend(button_config, global_config)); }) ); @@ -288,7 +261,7 @@ } var href = option.href || 'javascript:void(0);', target = ( option.target )?( ' target="' + target + '"' ):( '' ), - check = ( option.checked )?( '<span class="fa-icon-ok"></span>' ):( '' ); + check = ( option.checked )?( '<span class="fa fa-check"></span>' ):( '' ); return [ '<li><a class="popupmenu-option" href="', href, '"', target, '>', check, option.html, @@ -406,33 +379,27 @@ * @returns {Object[]} the options array to initialize a PopupMenu */ //TODO: lose parent and selector, pass in array of links, use map to return options -PopupMenu.convertLinksToOptions = function( $parent, selector ) -{ - $parent = $($parent); +PopupMenu.convertLinksToOptions = function( $parent, selector ){ + $parent = $( $parent ); selector = selector || 'a'; var options = []; - $parent.find( selector ).each( function( elem, i ) - { + $parent.find( selector ).each( function( elem, i ){ var option = {}, $link = $( elem ); // convert link text to the option text (html) and the href into the option func option.html = $link.text(); - if( linkHref ) - { + if( $link.attr( 'href' ) ){ var linkHref = $link.attr( 'href' ), linkTarget = $link.attr( 'target' ), confirmText = $link.attr( 'confirm' ); - option.func = function() - { + option.func = function(){ // if there's a "confirm" attribute, throw up a confirmation dialog, and // if the user cancels - do nothing if( ( confirmText ) && ( !confirm( confirmText ) ) ){ return; } // if there's no confirm attribute, or the user accepted the confirm dialog: - var f; - switch( linkTarget ) - { + switch( linkTarget ){ // relocate the center panel case '_parent': window.parent.location = linkHref; @@ -443,15 +410,6 @@ window.top.location = linkHref; break; - // Http request target is a window named demolocal on the local box - //TODO: I still don't understand this option (where the hell does f get set? confirm?) - case 'demo': - if( f === undefined || f.closed ){ - f = window.open( linkHref, linkTarget ); - f.creator = self; - } - break; - // relocate this panel default: window.location = linkHref; @@ -505,5 +463,30 @@ $buttonElement.addClass( 'popup' ); }); return popupMenusCreated; -} +}; +var faIconButton = function( options ){ + //FFS + options = options || {}; + options.tooltipConfig = options.tooltipConfig || { placement: 'bottom' }; + + options.classes = [ 'icon-btn' ].concat( options.classes || [] ); + if( options.disabled ){ + options.classes.push( 'disabled' ); + } + + var html = [ + '<a class="', options.classes.join( ' ' ), '"', + (( options.title )? ( ' title="' + options.title + '"' ):( '' )), + (( options.target )? ( ' target="' + options.target + '"' ):( '' )), + ' href="', (( options.href )?( options.href ):( 'javascript:void(0);' )), '">', + // could go with something less specific here - like 'html' + '<span class="fa ', options.faIcon, '"></span>', + '</a>' + ].join( '' ); + var $button = $( html ).tooltip( options.tooltipConfig ); + if( _.isFunction( options.onclick ) ){ + $button.click( options.onclick ); + } + return $button; +}; diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/galaxy.frame.js --- a/static/scripts/packed/galaxy.frame.js +++ b/static/scripts/packed/galaxy.frame.js @@ -1,1 +1,1 @@ -define(["galaxy.master","libs/backbone/backbone-relational"],function(b){var a=Backbone.View.extend({el_main:"#everything",options:{frame:{cols:6,rows:3},rows:1000,cell:130,margin:5,scroll:5,top_min:40,frame_max:9},cols:0,top:0,top_max:0,frame_z:0,frame_counter:0,frame_counter_id:0,frame_list:[],frame_shadow:null,visible:false,active:false,button_active:null,button_load:null,initialize:function(d){var c=this;this.button_active=new b.GalaxyMasterIcon({icon:"fa-icon-th",tooltip:"Enable/Disable Scratchbook",on_click:function(f){c.event_panel_active(f)},on_unload:function(){if(c.frame_counter>0){return"You opened "+c.frame_counter+" frame(s) which will be lost."}}});Galaxy.master.append(this.button_active);this.button_load=new b.GalaxyMasterIcon({icon:"fa-icon-eye-open",tooltip:"Show/Hide Scratchbook",on_click:function(f){c.event_panel_load(f)},with_number:true});Galaxy.master.append(this.button_load);if(d){this.options=_.defaults(d,this.options)}this.top=this.top_max=this.options.top_min;this.setElement(this.template());$(this.el).append(this.template_background());$(this.el).append(this.template_menu());$(this.el_main).append($(this.el));var e="#frame-shadow";$(this.el).append(this.template_shadow(e.substring(1)));this.frame_shadow={id:e,screen_location:{},grid_location:{},grid_rank:null,grid_lock:false};this.frame_resize(this.frame_shadow,{width:0,height:0});this.frame_list[e]=this.frame_shadow;this.panel_refresh();var c=this;$(window).resize(function(){if(c.visible){c.panel_refresh()}})},event:{type:null,target:null,xy:null},events:{mousemove:"event_frame_mouse_move",mouseup:"event_frame_mouse_up",mouseleave:"event_frame_mouse_up",mousewheel:"event_panel_scroll",DOMMouseScroll:"event_panel_scroll","mousedown .frame":"event_frame_mouse_down","mousedown .frame-background":"event_panel_load","mousedown .frame-scroll-up":"event_panel_scroll_up","mousedown .frame-scroll-down":"event_panel_scroll_down","mousedown .f-close":"event_frame_close","mousedown .f-pin":"event_frame_lock"},event_frame_mouse_down:function(c){if(this.event.type!==null){return}if($(c.target).hasClass("f-header")||$(c.target).hasClass("f-title")){this.event.type="drag"}if($(c.target).hasClass("f-resize")){this.event.type="resize"}if(this.event.type===null){return}c.preventDefault();this.event.target=this.event_get_frame(c.target);if(this.event.target.grid_lock){this.event.type=null;return}this.event.xy={x:c.originalEvent.pageX,y:c.originalEvent.pageY};this.frame_drag_start(this.event.target)},event_frame_mouse_move:function(i){if(this.event.type!="drag"&&this.event.type!="resize"){return}var g={x:i.originalEvent.pageX,y:i.originalEvent.pageY};var d={x:g.x-this.event.xy.x,y:g.y-this.event.xy.y};this.event.xy=g;var h=this.frame_screen(this.event.target);if(this.event.type=="resize"){h.width+=d.x;h.height+=d.y;var f=this.options.cell-this.options.margin-1;h.width=Math.max(h.width,f);h.height=Math.max(h.height,f);this.frame_resize(this.event.target,h);h.width=this.to_grid_coord("width",h.width)+1;h.height=this.to_grid_coord("height",h.height)+1;h.width=this.to_pixel_coord("width",h.width);h.height=this.to_pixel_coord("height",h.height);this.frame_resize(this.frame_shadow,h);this.frame_insert(this.frame_shadow,{top:this.to_grid_coord("top",h.top),left:this.to_grid_coord("left",h.left)})}if(this.event.type=="drag"){h.left+=d.x;h.top+=d.y;this.frame_offset(this.event.target,h);var c={top:this.to_grid_coord("top",h.top),left:this.to_grid_coord("left",h.left)};if(c.left!==0){c.left++}this.frame_insert(this.frame_shadow,c)}},event_frame_mouse_up:function(c){if(this.event.type!="drag"&&this.event.type!="resize"){return}this.frame_drag_stop(this.event.target);this.event.type=null},event_frame_close:function(d){if(this.event.type!==null){return}d.preventDefault();var f=this.event_get_frame(d.target);var c=this;$(f.id).fadeOut("fast",function(){$(f.id).remove();delete c.frame_list[f.id];c.frame_counter--;c.panel_refresh(true);c.panel_animation_complete();if(c.visible&&c.frame_counter==0){c.panel_show_hide()}})},event_frame_lock:function(c){if(this.event.type!==null){return}c.preventDefault();var d=this.event_get_frame(c.target);if(d.grid_lock){d.grid_lock=false;$(d.id).find(".f-pin").removeClass("toggle");$(d.id).find(".f-header").removeClass("f-not-allowed");$(d.id).find(".f-title").removeClass("f-not-allowed");$(d.id).find(".f-resize").show();$(d.id).find(".f-close").show()}else{d.grid_lock=true;$(d.id).find(".f-pin").addClass("toggle");$(d.id).find(".f-header").addClass("f-not-allowed");$(d.id).find(".f-title").addClass("f-not-allowed");$(d.id).find(".f-resize").hide();$(d.id).find(".f-close").hide()}},event_panel_load:function(c){if(this.event.type!==null){return}this.panel_show_hide()},event_panel_active:function(c){if(this.event.type!==null){return}this.panel_active_disable()},event_panel_scroll:function(c){if(this.event.type!==null||!this.visible){return}c.preventDefault();var d=c.originalEvent.detail?c.originalEvent.detail:c.originalEvent.wheelDelta/-3;this.panel_scroll(d)},event_panel_scroll_up:function(c){if(this.event.type!==null){return}c.preventDefault();this.panel_scroll(-this.options.scroll)},event_panel_scroll_down:function(c){if(this.event.type!==null){return}c.preventDefault();this.panel_scroll(this.options.scroll)},event_get_frame:function(c){return this.frame_list["#"+$(c).closest(".frame").attr("id")]},frame_drag_start:function(d){this.frame_focus(d,true);var c=this.frame_screen(d);this.frame_resize(this.frame_shadow,c);this.frame_grid(this.frame_shadow,d.grid_location);d.grid_location=null;$(this.frame_shadow.id).show();$(".f-cover").show()},frame_drag_stop:function(d){this.frame_focus(d,false);var c=this.frame_screen(this.frame_shadow);this.frame_resize(d,c);this.frame_grid(d,this.frame_shadow.grid_location,true);this.frame_shadow.grid_location=null;$(this.frame_shadow.id).hide();$(".f-cover").hide();this.panel_animation_complete()},to_grid_coord:function(e,d){var c=(e=="width"||e=="height")?1:-1;if(e=="top"){d-=this.top}return parseInt((d+c*this.options.margin)/this.options.cell,10)},to_pixel_coord:function(e,f){var c=(e=="width"||e=="height")?1:-1;var d=(f*this.options.cell)-c*this.options.margin;if(e=="top"){d+=this.top}return d},to_grid:function(c){return{top:this.to_grid_coord("top",c.top),left:this.to_grid_coord("left",c.left),width:this.to_grid_coord("width",c.width),height:this.to_grid_coord("height",c.height)}},to_pixel:function(c){return{top:this.to_pixel_coord("top",c.top),left:this.to_pixel_coord("left",c.left),width:this.to_pixel_coord("width",c.width),height:this.to_pixel_coord("height",c.height)}},is_collision:function(e){function c(h,g){return !(h.left>g.left+g.width-1||h.left+h.width-1<g.left||h.top>g.top+g.height-1||h.top+h.height-1<g.top)}for(var d in this.frame_list){var f=this.frame_list[d];if(f.grid_location===null){continue}if(c(e,f.grid_location)){return true}}return false},location_rank:function(c){return(c.top*this.cols)+c.left},menu_refresh:function(){this.button_load.number(this.frame_counter);if(this.frame_counter==0){this.button_load.hide()}else{this.button_load.show()}if(this.top==this.options.top_min){$(".frame-scroll-up").hide()}else{$(".frame-scroll-up").show()}if(this.top==this.top_max){$(".frame-scroll-down").hide()}else{$(".frame-scroll-down").show()}},panel_animation_complete:function(){var c=this;$(".frame").promise().done(function(){c.panel_scroll(0,true)})},panel_refresh:function(c){this.cols=parseInt($(window).width()/this.options.cell,10)+1;this.frame_insert(null,null,c)},panel_scroll:function(h,c){var e=this.top-this.options.scroll*h;e=Math.max(e,this.top_max);e=Math.min(e,this.options.top_min);if(this.top!=e){for(var d in this.frame_list){var g=this.frame_list[d];if(g.grid_location!==null){var f={top:g.screen_location.top-(this.top-e),left:g.screen_location.left};this.frame_offset(g,f,c)}}this.top=e}this.menu_refresh()},panel_show_hide:function(){if(this.visible){this.visible=false;$(".frame").fadeOut("fast");this.button_load.icon("fa-icon-eye-close");this.button_load.untoggle();$(".frame-background").hide();$(".frame-menu").hide()}else{this.visible=true;$(".frame").fadeIn("fast");this.button_load.icon("fa-icon-eye-open");this.button_load.toggle();$(this.frame_shadow.id).hide();$(".frame-background").show();this.panel_refresh()}},panel_active_disable:function(){if(this.active){this.active=false;this.button_active.untoggle();if(this.visible){this.panel_show_hide()}}else{this.active=true;this.button_active.toggle()}},frame_new:function(d){if(!this.active){if(d.location=="center"){var c=$(window.parent.document).find("iframe#galaxy_main");c.attr("src",d.content)}else{window.location=d.content}return}if(this.frame_counter>=this.options.frame_max){alert("You have reached the maximum number of allowed frames ("+this.options.frame_max+").");return}var e="#frame-"+(this.frame_counter_id++);if($(e).length!==0){alert("This frame already exists. This page might contain multiple frame managers.");return}this.top=this.options.top_min;$(this.el).append(this.template_frame(e.substring(1),d.title,d.type,d.content));var f={id:e,screen_location:{},grid_location:{},grid_rank:null,grid_lock:false};d.width=this.to_pixel_coord("width",this.options.frame.cols);d.height=this.to_pixel_coord("height",this.options.frame.rows);this.frame_z=parseInt($(f.id).css("z-index"));this.frame_list[e]=f;this.frame_counter++;this.frame_resize(f,{width:d.width,height:d.height});this.frame_insert(f,{top:0,left:0},true);if(!this.visible){this.panel_show_hide()}},frame_insert:function(j,c,e){var d=[];if(j){j.grid_location=null;d.push([j,this.location_rank(c)])}var g=null;for(g in this.frame_list){var h=this.frame_list[g];if(h.grid_location!==null&&!h.grid_lock){h.grid_location=null;d.push([h,h.grid_rank])}}d.sort(function(k,f){var m=k[1];var l=f[1];return m<l?-1:(m>l?1:0)});for(g=0;g<d.length;g++){this.frame_place(d[g][0],e)}this.top_max=0;for(var g in this.frame_list){var j=this.frame_list[g];if(j.grid_location!==null){this.top_max=Math.max(this.top_max,j.grid_location.top+j.grid_location.height)}}this.top_max=$(window).height()-this.top_max*this.options.cell-2*this.options.margin;this.top_max=Math.min(this.top_max,this.options.top_min);this.menu_refresh()},frame_place:function(k,d){k.grid_location=null;var h=this.to_grid(this.frame_screen(k));var c=false;for(var f=0;f<this.options.rows;f++){for(var e=0;e<Math.max(1,this.cols-h.width);e++){h.top=f;h.left=e;if(!this.is_collision(h)){c=true;break}}if(c){break}}if(c){this.frame_grid(k,h,d)}else{console.log("Grid dimensions exceeded.")}},frame_focus:function(e,c){var d=this.frame_z+(c?1:0);$(e.id).css("z-index",d)},frame_offset:function(f,e,d){f.screen_location.left=e.left;f.screen_location.top=e.top;if(d){this.frame_focus(f,true);var c=this;$(f.id).animate({top:e.top,left:e.left},"fast",function(){c.frame_focus(f,false)})}else{$(f.id).css({top:e.top,left:e.left})}},frame_resize:function(d,c){$(d.id).css({width:c.width,height:c.height});d.screen_location.width=c.width;d.screen_location.height=c.height},frame_grid:function(e,c,d){e.grid_location=c;this.frame_offset(e,this.to_pixel(c),d);e.grid_rank=this.location_rank(c)},frame_screen:function(d){var c=d.screen_location;return{top:c.top,left:c.left,width:c.width,height:c.height}},template:function(){return'<div class="galaxy-frame"></div>'},template_frame:function(f,e,c,d){if(!e){e=""}if(c=="url"){d='<iframe scrolling="auto" class="f-iframe" src="'+d+'"></iframe>'}return'<div id="'+f+'" class="frame corner"><div class="f-header corner"><span class="f-title">'+e+'</span><span class="f-icon f-pin fa-icon-pushpin"></span><span class="f-icon f-close fa-icon-trash"></span></div><div class="f-content">'+d+'<div class="f-cover"></div></div><span class="f-resize f-icon corner fa-icon-resize-full"></span></div>'},template_shadow:function(c){return'<div id="'+c+'" class="frame-shadow corner"></div>'},template_background:function(){return'<div class="frame-background"></div>'},template_menu:function(){return'<div class="frame-scroll-up frame-menu fa-icon-chevron-up fa-icon-2x"></div><div class="frame-scroll-down frame-menu fa-icon-chevron-down fa-icon-2x"></div>'}});return{GalaxyFrameManager:a}}); \ No newline at end of file +define(["galaxy.master","libs/backbone/backbone-relational"],function(b){var a=Backbone.View.extend({el_main:"#everything",options:{frame:{cols:6,rows:3},rows:1000,cell:130,margin:5,scroll:5,top_min:40,frame_max:9},cols:0,top:0,top_max:0,frame_z:0,frame_counter:0,frame_counter_id:0,frame_list:[],frame_shadow:null,visible:false,active:false,button_active:null,button_load:null,initialize:function(d){var c=this;this.button_active=new b.GalaxyMasterIcon({icon:"fa-th",tooltip:"Enable/Disable Scratchbook",on_click:function(f){c.event_panel_active(f)},on_unload:function(){if(c.frame_counter>0){return"You opened "+c.frame_counter+" frame(s) which will be lost."}}});Galaxy.master.append(this.button_active);this.button_load=new b.GalaxyMasterIcon({icon:"fa-eye",tooltip:"Show/Hide Scratchbook",on_click:function(f){c.event_panel_load(f)},with_number:true});Galaxy.master.append(this.button_load);if(d){this.options=_.defaults(d,this.options)}this.top=this.top_max=this.options.top_min;this.setElement(this.template());$(this.el).append(this.template_background());$(this.el).append(this.template_menu());$(this.el_main).append($(this.el));var e="#frame-shadow";$(this.el).append(this.template_shadow(e.substring(1)));this.frame_shadow={id:e,screen_location:{},grid_location:{},grid_rank:null,grid_lock:false};this.frame_resize(this.frame_shadow,{width:0,height:0});this.frame_list[e]=this.frame_shadow;this.panel_refresh();var c=this;$(window).resize(function(){if(c.visible){c.panel_refresh()}})},event:{type:null,target:null,xy:null},events:{mousemove:"event_frame_mouse_move",mouseup:"event_frame_mouse_up",mouseleave:"event_frame_mouse_up",mousewheel:"event_panel_scroll",DOMMouseScroll:"event_panel_scroll","mousedown .frame":"event_frame_mouse_down","mousedown .frame-background":"event_panel_load","mousedown .frame-scroll-up":"event_panel_scroll_up","mousedown .frame-scroll-down":"event_panel_scroll_down","mousedown .f-close":"event_frame_close","mousedown .f-pin":"event_frame_lock"},event_frame_mouse_down:function(c){if(this.event.type!==null){return}if($(c.target).hasClass("f-header")||$(c.target).hasClass("f-title")){this.event.type="drag"}if($(c.target).hasClass("f-resize")){this.event.type="resize"}if(this.event.type===null){return}c.preventDefault();this.event.target=this.event_get_frame(c.target);if(this.event.target.grid_lock){this.event.type=null;return}this.event.xy={x:c.originalEvent.pageX,y:c.originalEvent.pageY};this.frame_drag_start(this.event.target)},event_frame_mouse_move:function(i){if(this.event.type!="drag"&&this.event.type!="resize"){return}var g={x:i.originalEvent.pageX,y:i.originalEvent.pageY};var d={x:g.x-this.event.xy.x,y:g.y-this.event.xy.y};this.event.xy=g;var h=this.frame_screen(this.event.target);if(this.event.type=="resize"){h.width+=d.x;h.height+=d.y;var f=this.options.cell-this.options.margin-1;h.width=Math.max(h.width,f);h.height=Math.max(h.height,f);this.frame_resize(this.event.target,h);h.width=this.to_grid_coord("width",h.width)+1;h.height=this.to_grid_coord("height",h.height)+1;h.width=this.to_pixel_coord("width",h.width);h.height=this.to_pixel_coord("height",h.height);this.frame_resize(this.frame_shadow,h);this.frame_insert(this.frame_shadow,{top:this.to_grid_coord("top",h.top),left:this.to_grid_coord("left",h.left)})}if(this.event.type=="drag"){h.left+=d.x;h.top+=d.y;this.frame_offset(this.event.target,h);var c={top:this.to_grid_coord("top",h.top),left:this.to_grid_coord("left",h.left)};if(c.left!==0){c.left++}this.frame_insert(this.frame_shadow,c)}},event_frame_mouse_up:function(c){if(this.event.type!="drag"&&this.event.type!="resize"){return}this.frame_drag_stop(this.event.target);this.event.type=null},event_frame_close:function(d){if(this.event.type!==null){return}d.preventDefault();var f=this.event_get_frame(d.target);var c=this;$(f.id).fadeOut("fast",function(){$(f.id).remove();delete c.frame_list[f.id];c.frame_counter--;c.panel_refresh(true);c.panel_animation_complete();if(c.visible&&c.frame_counter==0){c.panel_show_hide()}})},event_frame_lock:function(c){if(this.event.type!==null){return}c.preventDefault();var d=this.event_get_frame(c.target);if(d.grid_lock){d.grid_lock=false;$(d.id).find(".f-pin").removeClass("toggle");$(d.id).find(".f-header").removeClass("f-not-allowed");$(d.id).find(".f-title").removeClass("f-not-allowed");$(d.id).find(".f-resize").show();$(d.id).find(".f-close").show()}else{d.grid_lock=true;$(d.id).find(".f-pin").addClass("toggle");$(d.id).find(".f-header").addClass("f-not-allowed");$(d.id).find(".f-title").addClass("f-not-allowed");$(d.id).find(".f-resize").hide();$(d.id).find(".f-close").hide()}},event_panel_load:function(c){if(this.event.type!==null){return}this.panel_show_hide()},event_panel_active:function(c){if(this.event.type!==null){return}this.panel_active_disable()},event_panel_scroll:function(c){if(this.event.type!==null||!this.visible){return}c.preventDefault();var d=c.originalEvent.detail?c.originalEvent.detail:c.originalEvent.wheelDelta/-3;this.panel_scroll(d)},event_panel_scroll_up:function(c){if(this.event.type!==null){return}c.preventDefault();this.panel_scroll(-this.options.scroll)},event_panel_scroll_down:function(c){if(this.event.type!==null){return}c.preventDefault();this.panel_scroll(this.options.scroll)},event_get_frame:function(c){return this.frame_list["#"+$(c).closest(".frame").attr("id")]},frame_drag_start:function(d){this.frame_focus(d,true);var c=this.frame_screen(d);this.frame_resize(this.frame_shadow,c);this.frame_grid(this.frame_shadow,d.grid_location);d.grid_location=null;$(this.frame_shadow.id).show();$(".f-cover").show()},frame_drag_stop:function(d){this.frame_focus(d,false);var c=this.frame_screen(this.frame_shadow);this.frame_resize(d,c);this.frame_grid(d,this.frame_shadow.grid_location,true);this.frame_shadow.grid_location=null;$(this.frame_shadow.id).hide();$(".f-cover").hide();this.panel_animation_complete()},to_grid_coord:function(e,d){var c=(e=="width"||e=="height")?1:-1;if(e=="top"){d-=this.top}return parseInt((d+c*this.options.margin)/this.options.cell,10)},to_pixel_coord:function(e,f){var c=(e=="width"||e=="height")?1:-1;var d=(f*this.options.cell)-c*this.options.margin;if(e=="top"){d+=this.top}return d},to_grid:function(c){return{top:this.to_grid_coord("top",c.top),left:this.to_grid_coord("left",c.left),width:this.to_grid_coord("width",c.width),height:this.to_grid_coord("height",c.height)}},to_pixel:function(c){return{top:this.to_pixel_coord("top",c.top),left:this.to_pixel_coord("left",c.left),width:this.to_pixel_coord("width",c.width),height:this.to_pixel_coord("height",c.height)}},is_collision:function(e){function c(h,g){return !(h.left>g.left+g.width-1||h.left+h.width-1<g.left||h.top>g.top+g.height-1||h.top+h.height-1<g.top)}for(var d in this.frame_list){var f=this.frame_list[d];if(f.grid_location===null){continue}if(c(e,f.grid_location)){return true}}return false},location_rank:function(c){return(c.top*this.cols)+c.left},menu_refresh:function(){this.button_load.number(this.frame_counter);if(this.frame_counter==0){this.button_load.hide()}else{this.button_load.show()}if(this.top==this.options.top_min){$(".frame-scroll-up").hide()}else{$(".frame-scroll-up").show()}if(this.top==this.top_max){$(".frame-scroll-down").hide()}else{$(".frame-scroll-down").show()}},panel_animation_complete:function(){var c=this;$(".frame").promise().done(function(){c.panel_scroll(0,true)})},panel_refresh:function(c){this.cols=parseInt($(window).width()/this.options.cell,10)+1;this.frame_insert(null,null,c)},panel_scroll:function(h,c){var e=this.top-this.options.scroll*h;e=Math.max(e,this.top_max);e=Math.min(e,this.options.top_min);if(this.top!=e){for(var d in this.frame_list){var g=this.frame_list[d];if(g.grid_location!==null){var f={top:g.screen_location.top-(this.top-e),left:g.screen_location.left};this.frame_offset(g,f,c)}}this.top=e}this.menu_refresh()},panel_show_hide:function(){if(this.visible){this.visible=false;$(".frame").fadeOut("fast");this.button_load.icon("fa-eye-slash");this.button_load.untoggle();$(".frame-background").hide();$(".frame-menu").hide()}else{this.visible=true;$(".frame").fadeIn("fast");this.button_load.icon("fa-eye-open");this.button_load.toggle();$(this.frame_shadow.id).hide();$(".frame-background").show();this.panel_refresh()}},panel_active_disable:function(){if(this.active){this.active=false;this.button_active.untoggle();if(this.visible){this.panel_show_hide()}}else{this.active=true;this.button_active.toggle()}},frame_new:function(d){if(!this.active){if(d.location=="center"){var c=$(window.parent.document).find("iframe#galaxy_main");c.attr("src",d.content)}else{window.location=d.content}return}if(this.frame_counter>=this.options.frame_max){alert("You have reached the maximum number of allowed frames ("+this.options.frame_max+").");return}var e="#frame-"+(this.frame_counter_id++);if($(e).length!==0){alert("This frame already exists. This page might contain multiple frame managers.");return}this.top=this.options.top_min;$(this.el).append(this.template_frame(e.substring(1),d.title,d.type,d.content));var f={id:e,screen_location:{},grid_location:{},grid_rank:null,grid_lock:false};d.width=this.to_pixel_coord("width",this.options.frame.cols);d.height=this.to_pixel_coord("height",this.options.frame.rows);this.frame_z=parseInt($(f.id).css("z-index"));this.frame_list[e]=f;this.frame_counter++;this.frame_resize(f,{width:d.width,height:d.height});this.frame_insert(f,{top:0,left:0},true);if(!this.visible){this.panel_show_hide()}},frame_insert:function(j,c,e){var d=[];if(j){j.grid_location=null;d.push([j,this.location_rank(c)])}var g=null;for(g in this.frame_list){var h=this.frame_list[g];if(h.grid_location!==null&&!h.grid_lock){h.grid_location=null;d.push([h,h.grid_rank])}}d.sort(function(k,f){var m=k[1];var l=f[1];return m<l?-1:(m>l?1:0)});for(g=0;g<d.length;g++){this.frame_place(d[g][0],e)}this.top_max=0;for(var g in this.frame_list){var j=this.frame_list[g];if(j.grid_location!==null){this.top_max=Math.max(this.top_max,j.grid_location.top+j.grid_location.height)}}this.top_max=$(window).height()-this.top_max*this.options.cell-2*this.options.margin;this.top_max=Math.min(this.top_max,this.options.top_min);this.menu_refresh()},frame_place:function(k,d){k.grid_location=null;var h=this.to_grid(this.frame_screen(k));var c=false;for(var f=0;f<this.options.rows;f++){for(var e=0;e<Math.max(1,this.cols-h.width);e++){h.top=f;h.left=e;if(!this.is_collision(h)){c=true;break}}if(c){break}}if(c){this.frame_grid(k,h,d)}else{console.log("Grid dimensions exceeded.")}},frame_focus:function(e,c){var d=this.frame_z+(c?1:0);$(e.id).css("z-index",d)},frame_offset:function(f,e,d){f.screen_location.left=e.left;f.screen_location.top=e.top;if(d){this.frame_focus(f,true);var c=this;$(f.id).animate({top:e.top,left:e.left},"fast",function(){c.frame_focus(f,false)})}else{$(f.id).css({top:e.top,left:e.left})}},frame_resize:function(d,c){$(d.id).css({width:c.width,height:c.height});d.screen_location.width=c.width;d.screen_location.height=c.height},frame_grid:function(e,c,d){e.grid_location=c;this.frame_offset(e,this.to_pixel(c),d);e.grid_rank=this.location_rank(c)},frame_screen:function(d){var c=d.screen_location;return{top:c.top,left:c.left,width:c.width,height:c.height}},template:function(){return'<div class="galaxy-frame"></div>'},template_frame:function(f,e,c,d){if(!e){e=""}if(c=="url"){d='<iframe scrolling="auto" class="f-iframe" src="'+d+'"></iframe>'}return'<div id="'+f+'" class="frame corner"><div class="f-header corner"><span class="f-title">'+e+'</span><span class="f-icon f-pin fa fa-thumb-tack"></span><span class="f-icon f-close fa fa-trash-o"></span></div><div class="f-content">'+d+'<div class="f-cover"></div></div><span class="f-resize f-icon corner fa fa-resize-full"></span></div>'},template_shadow:function(c){return'<div id="'+c+'" class="frame-shadow corner"></div>'},template_background:function(){return'<div class="frame-background"></div>'},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>'}});return{GalaxyFrameManager:a}}); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/galaxy.master.js --- a/static/scripts/packed/galaxy.master.js +++ b/static/scripts/packed/galaxy.master.js @@ -1,1 +1,1 @@ -define(["libs/backbone/backbone-relational"],function(){var a=Backbone.View.extend({el_master:"#masthead",list:[],initialize:function(d){this.setElement($(this.template()));$(this.el_master).append($(this.el));var c=this;window.onbeforeunload=function(){var f="";for(key in c.list){if(c.list[key].options.on_unload){var e=c.list[key].options.on_unload();if(e){f+=e+" "}}}if(f!=""){return f}}},events:{mousedown:function(c){c.preventDefault()}},append:function(c){$(this.el).append($(c.el));this.list.push(c)},prepend:function(c){$(this.el).prepend($(c.el));this.list.push(c)},template:function(){return'<div class="iconbar"></div>'}});var b=Backbone.View.extend({options:{id:"galaxy-icon",icon:"fa-icon-cog",tooltip:"galaxy-icon",with_number:false,on_click:function(){alert("clicked")},on_unload:null,visible:true},initialize:function(d){if(d){this.options=_.defaults(d,this.options)}this.setElement($(this.template(this.options)));var c=this;$(this.el).find(".icon").tooltip({title:this.options.tooltip}).on("click",c.options.on_click);if(!this.options.visible){this.hide()}},show:function(){$(this.el).css({visibility:"visible"})},hide:function(){$(this.el).css({visibility:"hidden"})},icon:function(c){$(this.el).find(".icon").removeClass(this.options.icon).addClass(c);this.options.icon=c},toggle:function(){$(this.el).addClass("toggle")},untoggle:function(){$(this.el).removeClass("toggle")},number:function(c){$(this.el).find(".number").text(c)},template:function(d){var c="<div id="+d.id+' class="symbol"><div class="icon fa-icon-2x '+d.icon+'"></div>';if(d.with_number){c+='<div class="number"></div>'}c+="</div>";return c}});return{GalaxyMaster:a,GalaxyMasterIcon:b}}); \ No newline at end of file +define(["libs/backbone/backbone-relational"],function(){var a=Backbone.View.extend({el_master:"#masthead",list:[],initialize:function(d){this.setElement($(this.template()));$(this.el_master).append($(this.el));var c=this;window.onbeforeunload=function(){var f="";for(key in c.list){if(c.list[key].options.on_unload){var e=c.list[key].options.on_unload();if(e){f+=e+" "}}}if(f!=""){return f}}},events:{mousedown:function(c){c.preventDefault()}},append:function(c){$(this.el).append($(c.el));this.list.push(c)},prepend:function(c){$(this.el).prepend($(c.el));this.list.push(c)},template:function(){return'<div class="iconbar"></div>'}});var b=Backbone.View.extend({options:{id:"galaxy-icon",icon:"fa-cog",tooltip:"galaxy-icon",with_number:false,on_click:function(){alert("clicked")},on_unload:null,visible:true},initialize:function(d){if(d){this.options=_.defaults(d,this.options)}this.setElement($(this.template(this.options)));var c=this;$(this.el).find(".icon").tooltip({title:this.options.tooltip}).on("click",c.options.on_click);if(!this.options.visible){this.hide()}},show:function(){$(this.el).css({visibility:"visible"})},hide:function(){$(this.el).css({visibility:"hidden"})},icon:function(c){$(this.el).find(".icon").removeClass(this.options.icon).addClass(c);this.options.icon=c},toggle:function(){$(this.el).addClass("toggle")},untoggle:function(){$(this.el).removeClass("toggle")},number:function(c){$(this.el).find(".number").text(c)},template:function(d){var c="<div id="+d.id+' class="symbol"><div class="icon fa fa-2x '+d.icon+'"></div>';if(d.with_number){c+='<div class="number"></div>'}c+="</div>";return c}});return{GalaxyMaster:a,GalaxyMasterIcon:b}}); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/galaxy.upload.js --- a/static/scripts/packed/galaxy.upload.js +++ b/static/scripts/packed/galaxy.upload.js @@ -1,1 +1,1 @@ -define(["galaxy.modal","galaxy.master","utils/galaxy.utils","utils/galaxy.uploadbox","libs/backbone/backbone-relational"],function(b,d,c){var a=Backbone.View.extend({modal:null,button_show:null,uploadbox:null,select_extension:[["Auto-detect","auto"]],select_genome:[["Unspecified (?)","?"]],state:{init:"fa-icon-trash",queued:"fa-icon-spinner fa-icon-spin",running:"__running__",success:"fa-icon-ok",error:"fa-icon-warning-sign"},counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},initialize:function(){if(!Galaxy.currHistoryPanel){var e=this;window.setTimeout(function(){e.initialize()},500);return}if(!Galaxy.currUser.get("id")){return}var e=this;this.button_show=new d.GalaxyMasterIcon({icon:"fa-icon-upload",tooltip:"Upload Files",on_click:function(f){e.event_show(f)},on_unload:function(){if(e.counter.running>0){return"Several uploads are still processing."}},with_number:true});Galaxy.master.prepend(this.button_show);var e=this;c.jsonFromUrl(galaxy_config.root+"api/datatypes",function(f){for(key in f){e.select_extension.push([f[key],f[key]])}});c.jsonFromUrl(galaxy_config.root+"api/genomes",function(f){var g=e.select_genome[0];e.select_genome=[];for(key in f){if(f[key].length>1){if(f[key][1]!==g[1]){e.select_genome.push(f[key])}}}e.select_genome.sort(function(i,h){return i[0]>h[0]?1:i[0]<h[0]?-1:0});e.select_genome.unshift(g)})},event_dragover:function(f){},event_dragleave:function(f){},event_announce:function(i,g,n){var f="#upload-"+i;$(this.el).find("tbody:last").append(this.template_row(f));var h=this.get_upload_item(i);h.fadeIn();h.find("#title").html(g.name);h.find("#size").html(this.size_to_string(g.size));var m=this;h.find("#symbol").on("click",function(){m.event_remove(i)});h.find("#text-content").on("keyup",function(){var o=h.find("#text-content").val().length;h.find("#size").html(m.size_to_string(o))});this.event_progress(i,g,0);this.counter.announce++;this.update_screen();if(g.size==-1){var l=h.find("#text");var j=8;var e=h.width()-2*j;var k=h.height()-j;l.css("width",e+"px");l.css("top",k+"px");h.height(k+l.height()+2*j);l.show()}},event_initialize:function(i,e,n){this.button_show.number(this.counter.announce);var g=this.get_upload_item(i);var k=g.find("#symbol");k.addClass(this.state.running);var j=Galaxy.currHistoryPanel.model.get("id");var f=g.find("#extension").val();var m=g.find("#genome").val();var l=g.find("#text-content").val();var h=g.find("#space_to_tabs").is(":checked");if(!l&&!(e.size>0)){return null}this.uploadbox.configure({url:galaxy_config.root+"api/tools/",paramname:"files_0|file_data"});tool_input={};tool_input.dbkey=m;tool_input.file_type=f;tool_input["files_0|NAME"]=e.name;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|url_paste"]=l;tool_input.space_to_tabs=h;data={};data.history_id=j;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},event_progress:function(f,g,i){var h=this.get_upload_item(f);var e=parseInt(i);h.find(".progress-bar").css({width:e+"%"});if(e!=100){h.find("#percentage").html(e+"%")}else{h.find("#percentage").html("Adding to history...")}},event_success:function(e,f,h){this.event_progress(e,f,100);this.button_show.number("");this.counter.announce--;this.counter.success++;this.update_screen();var g=this.get_upload_item(e);g.addClass("success");g.find("#percentage").html("100%");var i=g.find("#symbol");i.removeClass(this.state.running);i.removeClass(this.state.queued);i.addClass(this.state.success);Galaxy.currHistoryPanel.refreshHdas()},event_error:function(e,f,h){this.event_progress(e,f,0);this.button_show.number("");this.counter.announce--;this.counter.error++;this.update_screen();var g=this.get_upload_item(e);g.addClass("danger");g.find(".progress").remove();g.find("#info").html("<strong>Failed: </strong>"+h).show();var i=g.find("#symbol");i.removeClass(this.state.running);i.removeClass(this.state.queued);i.addClass(this.state.error)},event_start:function(){if(this.counter.announce==0||this.counter.running>0){return}var f=$(this.el).find(".upload-item");var e=this;f.each(function(){var g=$(this).find("#symbol");if(g.hasClass(e.state.init)){g.removeClass(e.state.init);g.addClass(e.state.queued);$(this).find("#text-content").attr("disabled",true);$(this).find("#genome").attr("disabled",true);$(this).find("#extension").attr("disabled",true);$(this).find("#space_to_tabs").attr("disabled",true)}});this.counter.running=this.counter.announce;this.update_screen();this.uploadbox.start()},event_stop:function(){if(this.counter.running==0){return}this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},event_complete:function(){this.counter.running=0;this.update_screen();var f=$(this.el).find(".upload-item");var e=this;f.each(function(){var g=$(this).find("#symbol");if(g.hasClass(e.state.queued)&&!g.hasClass(e.state.running)){g.removeClass(e.state.queued);g.addClass(e.state.init);$(this).find("#text-content").attr("disabled",false);$(this).find("#genome").attr("disabled",false);$(this).find("#extension").attr("disabled",false);$(this).find("#space_to_tabs").attr("disabled",false)}})},event_reset:function(){if(this.counter.running==0){var e=$(this.el).find(".upload-item");$(this.el).find("table").fadeOut({complete:function(){e.remove()}});this.counter.reset();this.update_screen();this.uploadbox.reset()}},event_remove:function(e){var f=this.get_upload_item(e);var g=f.find("#symbol");if(g.hasClass(this.state.init)||g.hasClass(this.state.success)||g.hasClass(this.state.error)){if(f.hasClass("success")){this.counter.success--}else{if(f.hasClass("danger")){this.counter.error--}else{this.counter.announce--}}this.update_screen();this.uploadbox.remove(e);f.remove()}},event_create:function(){this.uploadbox.add([{name:"New File",size:-1}])},event_show:function(g){g.preventDefault();if(!this.modal){var f=this;this.modal=new b.GalaxyModal({title:"Upload files from your local drive",body:this.template("upload-box","upload-info"),buttons:{Select:function(){f.uploadbox.select()},Create:function(){f.event_create()},Upload:function(){f.event_start()},Pause:function(){f.event_stop()},Reset:function(){f.event_reset()},Close:function(){f.modal.hide()},},height:"400",width:"900"});this.setElement("#upload-box");var f=this;this.uploadbox=this.$el.uploadbox({dragover:function(){f.event_dragover()},dragleave:function(){f.event_dragleave()},announce:function(e,h,i){f.event_announce(e,h,i)},initialize:function(e,h,i){return f.event_initialize(e,h,i)},success:function(e,h,i){f.event_success(e,h,i)},progress:function(e,h,i){f.event_progress(e,h,i)},error:function(e,h,i){f.event_error(e,h,i)},complete:function(){f.event_complete()},});this.update_screen()}this.modal.show()},get_upload_item:function(e){return $(this.el).find("#upload-"+e)},size_to_string:function(e){var f="";if(e>=100000000000){e=e/100000000000;f="TB"}else{if(e>=100000000){e=e/100000000;f="GB"}else{if(e>=100000){e=e/100000;f="MB"}else{if(e>=100){e=e/100;f="KB"}else{if(e>0){e=e*10;f="b"}else{return"<strong>-</strong>"}}}}}return"<strong>"+(Math.round(e)/10)+"</strong> "+f},update_screen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="Drag&drop files into this box or click 'Select' to select files!"}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Please upgrade to i.e. Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Upload' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Upload")}else{this.modal.disableButton("Upload")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Select");this.modal.enableButton("Create")}else{this.modal.disableButton("Select");this.modal.disableButton("Create")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("table").show()}else{$(this.el).find("table").hide()}},template:function(f,e){return'<div id="'+f+'" class="upload-box"><table class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Space→Tab</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><h6 id="'+e+'" class="upload-info"></h6>'},template_row:function(f){var e='<tr id="'+f.substr(1)+'" class="upload-item"><td><div style="position: relative;"><div id="title" class="title"></div><div id="text" class="text"><div class="text-info">You may specify a list of URLs (one per line) or paste the contents of a file.</div><textarea id="text-content" class="text-content form-control"></textarea></div></div></td><td><div id="size" class="size"></div></td>';e+='<td><select id="extension" class="extension">';for(key in this.select_extension){e+='<option value="'+this.select_extension[key][1]+'">'+this.select_extension[key][0]+"</option>"}e+="</select></td>";e+='<td><select id="genome" class="genome">';for(key in this.select_genome){e+='<option value="'+this.select_genome[key][1]+'">'+this.select_genome[key][0]+"</option>"}e+="</select></td>";e+='<td><input id="space_to_tabs" type="checkbox"></input></td><td><div id="info" class="info"><div class="progress"><div class="progress-bar progress-bar-success"></div><div id="percentage" class="percentage">0%</div></div></div></td><td><div id="symbol" class="symbol '+this.state.init+'"></div></td></tr>';return e}});return{GalaxyUpload:a}}); \ No newline at end of file +define(["galaxy.modal","galaxy.master","utils/galaxy.utils","utils/galaxy.uploadbox","libs/backbone/backbone-relational"],function(b,d,c){var a=Backbone.View.extend({modal:null,button_show:null,uploadbox:null,select_extension:[["Auto-detect","auto"]],select_genome:[["Unspecified (?)","?"]],state:{init:"fa fa-trash-o",queued:"fa fa-spinner fa-spin",running:"__running__",success:"fa fa-check",error:"fa fa-exclamation-triangle"},counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},initialize:function(){if(!Galaxy.currHistoryPanel){var e=this;window.setTimeout(function(){e.initialize()},500);return}if(!Galaxy.currUser.get("id")){return}var e=this;this.button_show=new d.GalaxyMasterIcon({icon:"fa-arrow-circle-o-up",tooltip:"Upload Files",on_click:function(f){e.event_show(f)},on_unload:function(){if(e.counter.running>0){return"Several uploads are still processing."}},with_number:true});Galaxy.master.prepend(this.button_show);var e=this;c.jsonFromUrl(galaxy_config.root+"api/datatypes",function(f){for(key in f){e.select_extension.push([f[key],f[key]])}});c.jsonFromUrl(galaxy_config.root+"api/genomes",function(f){var g=e.select_genome[0];e.select_genome=[];for(key in f){if(f[key].length>1){if(f[key][1]!==g[1]){e.select_genome.push(f[key])}}}e.select_genome.sort(function(i,h){return i[0]>h[0]?1:i[0]<h[0]?-1:0});e.select_genome.unshift(g)})},event_dragover:function(f){},event_dragleave:function(f){},event_announce:function(i,g,n){var f="#upload-"+i;$(this.el).find("tbody:last").append(this.template_row(f));var h=this.get_upload_item(i);h.fadeIn();h.find("#title").html(g.name);h.find("#size").html(this.size_to_string(g.size));var m=this;h.find("#symbol").on("click",function(){m.event_remove(i)});h.find("#text-content").on("keyup",function(){var o=h.find("#text-content").val().length;h.find("#size").html(m.size_to_string(o))});this.event_progress(i,g,0);this.counter.announce++;this.update_screen();if(g.size==-1){var l=h.find("#text");var j=8;var e=h.width()-2*j;var k=h.height()-j;l.css("width",e+"px");l.css("top",k+"px");h.height(k+l.height()+2*j);l.show()}},event_initialize:function(i,e,n){this.button_show.number(this.counter.announce);var g=this.get_upload_item(i);var k=g.find("#symbol");k.addClass(this.state.running);var j=Galaxy.currHistoryPanel.model.get("id");var f=g.find("#extension").val();var m=g.find("#genome").val();var l=g.find("#text-content").val();var h=g.find("#space_to_tabs").is(":checked");if(!l&&!(e.size>0)){return null}this.uploadbox.configure({url:galaxy_config.root+"api/tools",paramname:"files_0|file_data"});tool_input={};tool_input.dbkey=m;tool_input.file_type=f;tool_input["files_0|NAME"]=e.name;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|url_paste"]=l;tool_input.space_to_tabs=h;data={};data.history_id=j;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},event_progress:function(f,g,i){var h=this.get_upload_item(f);var e=parseInt(i);h.find(".progress-bar").css({width:e+"%"});if(e!=100){h.find("#percentage").html(e+"%")}else{h.find("#percentage").html("Adding to history...")}},event_success:function(e,f,h){this.event_progress(e,f,100);this.button_show.number("");this.counter.announce--;this.counter.success++;this.update_screen();var g=this.get_upload_item(e);g.addClass("success");g.find("#percentage").html("100%");var i=g.find("#symbol");i.removeClass(this.state.running);i.removeClass(this.state.queued);i.addClass(this.state.success);Galaxy.currHistoryPanel.refreshHdas()},event_error:function(e,f,h){this.event_progress(e,f,0);this.button_show.number("");this.counter.announce--;this.counter.error++;this.update_screen();var g=this.get_upload_item(e);g.addClass("danger");g.find(".progress").remove();g.find("#info").html("<strong>Failed: </strong>"+h).show();var i=g.find("#symbol");i.removeClass(this.state.running);i.removeClass(this.state.queued);i.addClass(this.state.error)},event_start:function(){if(this.counter.announce==0||this.counter.running>0){return}var f=$(this.el).find(".upload-item");var e=this;f.each(function(){var g=$(this).find("#symbol");if(g.hasClass(e.state.init)){g.removeClass(e.state.init);g.addClass(e.state.queued);$(this).find("#text-content").attr("disabled",true);$(this).find("#genome").attr("disabled",true);$(this).find("#extension").attr("disabled",true);$(this).find("#space_to_tabs").attr("disabled",true)}});this.counter.running=this.counter.announce;this.update_screen();this.uploadbox.start()},event_stop:function(){if(this.counter.running==0){return}this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},event_complete:function(){this.counter.running=0;this.update_screen();var f=$(this.el).find(".upload-item");var e=this;f.each(function(){var g=$(this).find("#symbol");if(g.hasClass(e.state.queued)&&!g.hasClass(e.state.running)){g.removeClass(e.state.queued);g.addClass(e.state.init);$(this).find("#text-content").attr("disabled",false);$(this).find("#genome").attr("disabled",false);$(this).find("#extension").attr("disabled",false);$(this).find("#space_to_tabs").attr("disabled",false)}})},event_reset:function(){if(this.counter.running==0){var e=$(this.el).find(".upload-item");$(this.el).find("table").fadeOut({complete:function(){e.remove()}});this.counter.reset();this.update_screen();this.uploadbox.reset()}},event_remove:function(e){var f=this.get_upload_item(e);var g=f.find("#symbol");if(g.hasClass(this.state.init)||g.hasClass(this.state.success)||g.hasClass(this.state.error)){if(f.hasClass("success")){this.counter.success--}else{if(f.hasClass("danger")){this.counter.error--}else{this.counter.announce--}}this.update_screen();this.uploadbox.remove(e);f.remove()}},event_create:function(){this.uploadbox.add([{name:"New File",size:-1}])},event_show:function(g){g.preventDefault();if(!this.modal){var f=this;this.modal=new b.GalaxyModal({title:"Upload files from your local drive",body:this.template("upload-box","upload-info"),buttons:{Select:function(){f.uploadbox.select()},Create:function(){f.event_create()},Upload:function(){f.event_start()},Pause:function(){f.event_stop()},Reset:function(){f.event_reset()},Close:function(){f.modal.hide()},},height:"400",width:"900"});this.setElement("#upload-box");var f=this;this.uploadbox=this.$el.uploadbox({dragover:function(){f.event_dragover()},dragleave:function(){f.event_dragleave()},announce:function(e,h,i){f.event_announce(e,h,i)},initialize:function(e,h,i){return f.event_initialize(e,h,i)},success:function(e,h,i){f.event_success(e,h,i)},progress:function(e,h,i){f.event_progress(e,h,i)},error:function(e,h,i){f.event_error(e,h,i)},complete:function(){f.event_complete()},});this.update_screen()}this.modal.show()},get_upload_item:function(e){return $(this.el).find("#upload-"+e)},size_to_string:function(e){var f="";if(e>=100000000000){e=e/100000000000;f="TB"}else{if(e>=100000000){e=e/100000000;f="GB"}else{if(e>=100000){e=e/100000;f="MB"}else{if(e>=100){e=e/100;f="KB"}else{if(e>0){e=e*10;f="b"}else{return"<strong>-</strong>"}}}}}return"<strong>"+(Math.round(e)/10)+"</strong> "+f},update_screen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="Drag&drop files into this box or click 'Select' to select files!"}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Please upgrade to i.e. Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Upload' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Upload")}else{this.modal.disableButton("Upload")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Select");this.modal.enableButton("Create")}else{this.modal.disableButton("Select");this.modal.disableButton("Create")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("table").show()}else{$(this.el).find("table").hide()}},template:function(f,e){return'<div id="'+f+'" class="upload-box"><table class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Space→Tab</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><h6 id="'+e+'" class="upload-info"></h6>'},template_row:function(f){var e='<tr id="'+f.substr(1)+'" class="upload-item"><td><div style="position: relative;"><div id="title" class="title"></div><div id="text" class="text"><div class="text-info">You may specify a list of URLs (one per line) or paste the contents of a file.</div><textarea id="text-content" class="text-content form-control"></textarea></div></div></td><td><div id="size" class="size"></div></td>';e+='<td><select id="extension" class="extension">';for(key in this.select_extension){e+='<option value="'+this.select_extension[key][1]+'">'+this.select_extension[key][0]+"</option>"}e+="</select></td>";e+='<td><select id="genome" class="genome">';for(key in this.select_genome){e+='<option value="'+this.select_genome[key][1]+'">'+this.select_genome[key][0]+"</option>"}e+="</select></td>";e+='<td><input id="space_to_tabs" type="checkbox"></input></td><td><div id="info" class="info"><div class="progress"><div class="progress-bar progress-bar-success"></div><div id="percentage" class="percentage">0%</div></div></div></td><td><div id="symbol" class="symbol '+this.state.init+'"></div></td></tr>';return e}});return{GalaxyUpload:a}}); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d 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 Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(b,c,a){Terminal.call(this,b);this.datatypes=c;this.multiple=a}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1||this.multiple){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){if(f[b]=="input"||issubtype(f[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;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()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};if(!this.handle1||!this.handle2){return}var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(f,b,c,a){var d=this;$(f).each(function(){var g=this.terminal=new InputTerminal(this,c,a);g.node=d;g.name=b;$(this).bind("dropinit",function(h,i){return $(i.drag).hasClass("output-terminal")&&g.can_accept(i.drag.terminal)}).bind("dropstart",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#BBFFBB"}}).bind("dropend",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#FFFFFF"}}).bind("drop",function(h,i){(new Connector(i.drag.terminal,g)).redraw()}).bind("hover",function(){if(g.connectors.length>0){var h=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa-icon-remove").click(function(){$.each(g.connectors,function(j,i){if(i){i.destroy()}});h.remove()}))).bind("mouseleave",function(){$(this).remove()});h.css({top:$(this).offset().top-2,left:$(this).offset().left-h.width(),"padding-right":$(this).width()}).show()}});d.input_terminals[b]=g})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j,k){$(k.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var l=new Connector();l.dragging=true;l.connect(this.terminal,i.terminal);return i}).bind("drag",function(i,j){var h=function(){var l=$(j.proxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.proxy).css({left:k,top:m});j.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h,i){i.proxy.terminal.connectors[0].destroy();$(i.proxy).remove();$(i.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(h){var g=this.element;if(h.type){this.type=h.type}this.name=h.name;this.form_html=h.form_html;this.tool_state=h.tool_state;this.tool_errors=h.tool_errors;this.tooltip=h.tooltip?h.tooltip:"";this.annotation=h.annotation;this.post_job_actions=h.post_job_actions?h.post_job_actions:{};this.workflow_outputs=h.workflow_outputs?h.workflow_outputs:[];if(this.tool_errors){g.addClass("tool-node-error")}else{g.removeClass("tool-node-error")}var d=this;var c=Math.max(150,g.width());var a=g.find(".toolFormBody");a.find("div").remove();var i=$("<div class='inputs'></div>").appendTo(a);$.each(h.data_inputs,function(k,f){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,f.name,f.extensions,f.multiple);var b=$("<div class='form-row dataRow input-data-row' name='"+f.name+"'>"+f.label+"</div>");b.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(b);c=Math.max(c,b.outerWidth());b.css({position:"",left:"",top:"",display:""});b.remove();i.append(b.prepend(j))});if((h.data_inputs.length>0)&&(h.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(h.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");d.enable_output_terminal(j,b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions.join(", ")+")"}var m=$("<div class='form-row dataRow'>"+f+"</div>");if(d.type=="tool"){var l=$("<div class='callout "+f+"'></div>").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(b.name,d.workflow_outputs)!=-1){d.workflow_outputs.splice($.inArray(b.name,d.workflow_outputs),1);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{d.workflow_outputs.push(b.name);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Flag this as a workflow output. All non-flagged outputs will be hidden."});l.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});l.show();m.append(l);if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}m.hover(function(){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")},function(){if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}})}m.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(m);c=Math.max(c,m.outerWidth()+17);m.css({position:"",left:"",top:"",display:""});m.detach();a.append(m.append(j))});g.css("width",Math.min(250,Math.max(g.width(),c)));workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;var g=$.parseJSON(f.post_job_actions);this.post_job_actions=g?g:{};if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var h=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=h.find("div.input-data-row");$.each(f.data_inputs,function(l,j){var k=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(k,j.name,j.extensions,j.multiple);h.find("div[name='"+j.name+"']").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){k[0].terminal.connectors[0]=i;i.handle2=k[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+j.name+"'>"+j.label+"</div>").prepend(k))});h.replaceWith(b);h.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;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("tool",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)){$.each(h,function(m,k){var n=wf.nodes[k.id];var o=new Connector();o.connect(n.output_terminals[k.output_name],d.input_terminals[i]);o.redraw()})}else{var j=wf.nodes[h.id];var l=new Connector();l.connect(j.output_terminals[h.output_name],d.input_terminals[i]);l.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(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-icon-remove").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}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(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 Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(b,c,a){Terminal.call(this,b);this.datatypes=c;this.multiple=a}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1||this.multiple){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){if(f[b]=="input"||issubtype(f[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;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()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};if(!this.handle1||!this.handle2){return}var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(f,b,c,a){var d=this;$(f).each(function(){var g=this.terminal=new InputTerminal(this,c,a);g.node=d;g.name=b;$(this).bind("dropinit",function(h,i){return $(i.drag).hasClass("output-terminal")&&g.can_accept(i.drag.terminal)}).bind("dropstart",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#BBFFBB"}}).bind("dropend",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#FFFFFF"}}).bind("drop",function(h,i){(new Connector(i.drag.terminal,g)).redraw()}).bind("hover",function(){if(g.connectors.length>0){var h=$("<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(g.connectors,function(j,i){if(i){i.destroy()}});h.remove()}))).bind("mouseleave",function(){$(this).remove()});h.css({top:$(this).offset().top-2,left:$(this).offset().left-h.width(),"padding-right":$(this).width()}).show()}});d.input_terminals[b]=g})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j,k){$(k.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var l=new Connector();l.dragging=true;l.connect(this.terminal,i.terminal);return i}).bind("drag",function(i,j){var h=function(){var l=$(j.proxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.proxy).css({left:k,top:m});j.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h,i){i.proxy.terminal.connectors[0].destroy();$(i.proxy).remove();$(i.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(h){var g=this.element;if(h.type){this.type=h.type}this.name=h.name;this.form_html=h.form_html;this.tool_state=h.tool_state;this.tool_errors=h.tool_errors;this.tooltip=h.tooltip?h.tooltip:"";this.annotation=h.annotation;this.post_job_actions=h.post_job_actions?h.post_job_actions:{};this.workflow_outputs=h.workflow_outputs?h.workflow_outputs:[];if(this.tool_errors){g.addClass("tool-node-error")}else{g.removeClass("tool-node-error")}var d=this;var c=Math.max(150,g.width());var a=g.find(".toolFormBody");a.find("div").remove();var i=$("<div class='inputs'></div>").appendTo(a);$.each(h.data_inputs,function(k,f){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,f.name,f.extensions,f.multiple);var b=$("<div class='form-row dataRow input-data-row' name='"+f.name+"'>"+f.label+"</div>");b.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(b);c=Math.max(c,b.outerWidth());b.css({position:"",left:"",top:"",display:""});b.remove();i.append(b.prepend(j))});if((h.data_inputs.length>0)&&(h.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(h.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");d.enable_output_terminal(j,b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions.join(", ")+")"}var m=$("<div class='form-row dataRow'>"+f+"</div>");if(d.type=="tool"){var l=$("<div class='callout "+f+"'></div>").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(b.name,d.workflow_outputs)!=-1){d.workflow_outputs.splice($.inArray(b.name,d.workflow_outputs),1);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{d.workflow_outputs.push(b.name);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Flag this as a workflow output. All non-flagged outputs will be hidden."});l.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});l.show();m.append(l);if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}m.hover(function(){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")},function(){if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}})}m.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(m);c=Math.max(c,m.outerWidth()+17);m.css({position:"",left:"",top:"",display:""});m.detach();a.append(m.append(j))});g.css("width",Math.min(250,Math.max(g.width(),c)));workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;var g=$.parseJSON(f.post_job_actions);this.post_job_actions=g?g:{};if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var h=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=h.find("div.input-data-row");$.each(f.data_inputs,function(l,j){var k=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(k,j.name,j.extensions,j.multiple);h.find("div[name='"+j.name+"']").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){k[0].terminal.connectors[0]=i;i.handle2=k[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+j.name+"'>"+j.label+"</div>").prepend(k))});h.replaceWith(b);h.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;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("tool",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)){$.each(h,function(m,k){var n=wf.nodes[k.id];var o=new Connector();o.connect(n.output_terminals[k.output_name],d.input_terminals[i]);o.redraw()})}else{var j=wf.nodes[h.id];var l=new Connector();l.connect(j.output_terminals[h.output_name],d.input_terminals[i]);l.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(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}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(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 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/mvc/base-mvc.js --- a/static/scripts/packed/mvc/base-mvc.js +++ b/static/scripts/packed/mvc/base-mvc.js @@ -1,1 +1,1 @@ -var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){var a=this.logger.log;if(typeof this.logger.log==="object"){a=Function.prototype.bind.call(this.logger.log,this.logger)}return a.apply(this.logger,arguments)}return undefined}};var PersistentStorage=function(k,g){if(!k){throw ("PersistentStorage needs storageKey argument")}g=g||{};var i=sessionStorage,c=function j(m){var n=this.getItem(m);return(n!==null)?(JSON.parse(this.getItem(m))):(null)},b=function e(m,n){return this.setItem(m,JSON.stringify(n))},d=function f(m){return this.removeItem(m)};function a(n,m){n=n||{};m=m||null;return{get:function(o){if(o===undefined){return n}else{if(n.hasOwnProperty(o)){return(jQuery.type(n[o])==="object")?(new a(n[o],this)):(n[o])}}return undefined},set:function(o,p){n[o]=p;this._save();return this},deleteKey:function(o){delete n[o];this._save();return this},_save:function(){return m._save()},toString:function(){return("StorageRecursionHelper("+n+")")}}}var l={},h=c.call(i,k);if(h===null||h===undefined){h=jQuery.extend(true,{},g);b.call(i,k,h)}l=new a(h);jQuery.extend(l,{_save:function(m){return b.call(i,k,l.get())},destroy:function(){return d.call(i,k)},toString:function(){return"PersistentStorage("+k+")"}});return l};function LoadingIndicator(a,c){c=c||{};var b=this;function d(){var e=['<div class="loading-indicator">','<span class="fa-icon-spinner fa-icon-spin fa-icon-large" style="color: grey"></span>','<span style="margin-left: 8px; color: grey"><i>loading...</i></span>',"</div>"].join("\n");return $(e).css(c.css||{position:"fixed",margin:"6px 0px 0px 10px",opacity:"0.85"}).hide()}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}; \ No newline at end of file +var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){var a=this.logger.log;if(typeof this.logger.log==="object"){a=Function.prototype.bind.call(this.logger.log,this.logger)}return a.apply(this.logger,arguments)}return undefined}};var PersistentStorage=function(k,g){if(!k){throw ("PersistentStorage needs storageKey argument")}g=g||{};var i=sessionStorage,c=function j(m){var n=this.getItem(m);return(n!==null)?(JSON.parse(this.getItem(m))):(null)},b=function e(m,n){return this.setItem(m,JSON.stringify(n))},d=function f(m){return this.removeItem(m)};function a(n,m){n=n||{};m=m||null;return{get:function(o){if(o===undefined){return n}else{if(n.hasOwnProperty(o)){return(jQuery.type(n[o])==="object")?(new a(n[o],this)):(n[o])}}return undefined},set:function(o,p){n[o]=p;this._save();return this},deleteKey:function(o){delete n[o];this._save();return this},_save:function(){return m._save()},toString:function(){return("StorageRecursionHelper("+n+")")}}}var l={},h=c.call(i,k);if(h===null||h===undefined){h=jQuery.extend(true,{},g);b.call(i,k,h)}l=new a(h);jQuery.extend(l,{_save:function(m){return b.call(i,k,l.get())},destroy:function(){return d.call(i,k)},toString:function(){return"PersistentStorage("+k+")"}});return l};function LoadingIndicator(a,c){c=c||{};var b=this;function d(){var e=['<div class="loading-indicator">','<span class="fa fa-spinner fa-spin fa-lg" style="color: grey"></span>','<span style="margin-left: 8px; color: grey"><i>loading...</i></span>',"</div>"].join("\n");return $(e).css(c.css||{position:"fixed",margin:"6px 0px 0px 10px",opacity:"0.85"}).hide()}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}; \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/mvc/dataset/hda-base.js --- a/static/scripts/packed/mvc/dataset/hda-base.js +++ b/static/scripts/packed/mvc/dataset/hda-base.js @@ -1,1 +1,1 @@ -define(["mvc/dataset/hda-model"],function(b){var a=Backbone.View.extend(LoggableMixin).extend({tagName:"div",className:"dataset hda history-panel-hda",id:function(){return"hda-"+this.model.get("id")},fxSpeed:"fast",initialize:function(c){if(c.logger){this.logger=this.model.logger=c.logger}this.log(this+".initialize:",c);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.expanded=c.expanded||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(d,c){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(e){e=(e===undefined)?(true):(e);var c=this;this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();var d=$(a.templates.skeleton(this.model.toJSON()));d.find(".dataset-primary-actions").append(this._render_titleButtons());d.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(d);if(e){$(c).queue(function(f){this.$el.fadeOut(c.fxSpeed,f)})}$(c).queue(function(f){this.$el.empty().attr("class",c.className).addClass("state-"+c.model.get("state")).append(d.children());f()});if(e){$(c).queue(function(f){this.$el.fadeIn(c.fxSpeed,f)})}$(c).queue(function(f){this.trigger("rendered",c);if(this.model.inReadyState()){this.trigger("rendered:ready",c)}f()});return this},_setUpBehaviors:function(c){c=c||this.$el;make_popup_menus(c);c.find("[title]").tooltip({placement:"bottom"})},_render_titleButtons:function(){return[this._render_displayButton()]},_render_iconButton:function(c){c=c||{};c.classes=["icon-btn"].concat(c.classes||[]);if(c.disabled){c.classes.push("disabled")}var d=['<a class="',c.classes.join(" "),'"',((c.title)?(' title="'+c.title+'"'):("")),((c.target)?(' target="'+c.target+'"'):("")),' href="',((c.href)?(c.href):("javascript:void(0);")),'">','<span class="',c.faIcon,'"></span>',"</a>"].join("");d=$(d);if(_.isFunction(c.onClick)){d.click(c.onClick)}return d},_render_displayButton:function(){if((this.model.get("state")===b.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===b.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===b.HistoryDatasetAssociation.STATES.NEW)||(!this.model.get("accessible"))){this.displayButton=null;return null}var d={icon_class:"display",target:"galaxy_main"};if(this.model.get("purged")){d.enabled=false;d.title=_l("Cannot display datasets removed from disk")}else{if(this.model.get("state")===b.HistoryDatasetAssociation.STATES.UPLOAD){d.enabled=false;d.title=_l("This dataset must finish uploading before it can be viewed")}else{d.title=_l("View data");d.href=this.urls.display;var c=this;d.onClick=function(){Galaxy.frame_manager.frame_new({title:"Data Viewer: "+c.model.get("name"),type:"url",location:"center",content:c.urls.display})}}}this.displayButton=new IconButtonView({model:new IconButton(d)});return this.displayButton.render().$el},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var d=this.urls,e=this.model.get("meta_files");if(_.isEmpty(e)){return $(['<a href="',d.download,'" title="',_l("Download"),'" class="icon-button disk"></a>'].join(""))}var f="dataset-"+this.model.get("id")+"-popup",c=['<div popupmenu="'+f+'">','<a class="action-button" href="'+d.download+'">',_l("Download Dataset"),"</a>","<a>"+_l("Additional Files")+"</a>",_.map(e,function(g){return['<a class="action-button" href="',d.meta_download+g.file_type,'">',_l("Download")," ",g.file_type,"</a>"].join("")}).join("\n"),"</div>",'<div style="float:left;" class="menubutton split popup" id="'+f+'">','<a href="'+d.download+'" title="'+_l("Download")+'" class="icon-button disk"></a>',"</div>"].join("\n");return $(c)},_render_showParamsButton:function(){return new IconButtonView({model:new IconButton({title:_l("View details"),href:this.urls.show_params,target:"galaxy_main",icon_class:"information"})}).render().$el},_render_body:function(){var d=$('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'),c=this["_render_body_"+this.model.get("state")];if(_.isFunction(c)){d=c.call(this)}if(this.expanded){d.show()}return d},_render_stateBodyHelper:function(c,f){f=f||[];var d=this,e=$(a.templates.body(_.extend(this.model.toJSON(),{body:c})));e.find(".dataset-actions .left").append(_.map(f,function(g){return g.call(d)}));return e},_render_body_new:function(){return this._render_stateBodyHelper("<div>"+_l("This is a new dataset and not all of its data are available yet")+"</div>")},_render_body_noPermission:function(){return this._render_stateBodyHelper("<div>"+_l("You do not have permission to view this dataset")+"</div>")},_render_body_discarded:function(){return this._render_stateBodyHelper("<div>"+_l("The job creating this dataset was cancelled before completion")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_queued:function(){return this._render_stateBodyHelper("<div>"+_l("This job is waiting to run")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_upload:function(){return this._render_stateBodyHelper("<div>"+_l("This dataset is currently uploading")+"</div>")},_render_body_setting_metadata:function(){return this._render_stateBodyHelper("<div>"+_l("Metadata is being auto-detected")+"</div>")},_render_body_running:function(){return this._render_stateBodyHelper("<div>"+_l("This job is currently running")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_paused:function(){return this._render_stateBodyHelper("<div>"+_l('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_error:function(){var c=_l("An error occurred with this dataset")+": <i>"+$.trim(this.model.get("misc_info"))+"</i>";if(!this.model.get("purged")){c="<div>"+this.model.get("misc_blurb")+"</div>"+c}return this._render_stateBodyHelper(c,this.defaultPrimaryActionButtonRenderers.concat([this._render_downloadButton]))},_render_body_empty:function(){return this._render_stateBodyHelper("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>",this.defaultPrimaryActionButtonRenderers)},_render_body_failed_metadata:function(){var c=$('<div class="warningmessagesmall"></div>').append($("<strong/>").text(_l("An error occurred setting the metadata for this dataset"))),d=this._render_body_ok();d.prepend(c);return d},_render_body_ok:function(){var c=this,e=$(a.templates.body(this.model.toJSON())),d=[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers);e.find(".dataset-actions .left").append(_.map(d,function(f){return f.call(c)}));if(this.model.isDeletedOrPurged()){return e}return e},events:{"click .dataset-title-bar":"toggleBodyVisibility"},toggleBodyVisibility:function(d,c){var e=this.$el.find(".dataset-body");c=(c===undefined)?(!e.is(":visible")):(c);if(c){this.expandBody()}else{this.collapseBody()}},expandBody:function(){var c=this;function d(){c.render(false).$el.children(".dataset-body").slideDown(c.fxSpeed,function(){c.expanded=true;c.trigger("body-expanded",c.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch({silent:true}).always(function(e){d()})}else{d()}},collapseBody:function(){var c=this;this.$el.children(".dataset-body").slideUp(c.fxSpeed,function(){c.expanded=false;c.trigger("body-collapsed",c.model.get("id"))})},remove:function(d){var c=this;this.$el.fadeOut(c.fxSpeed,function(){c.$el.remove();c.off();if(d){d()}})},toString:function(){var c=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+c+")"}});a.templates={skeleton:Handlebars.templates["template-hda-skeleton"],body:Handlebars.templates["template-hda-body"]};return{HDABaseView:a}}); \ No newline at end of file +define(["mvc/dataset/hda-model"],function(b){var a=Backbone.View.extend(LoggableMixin).extend({tagName:"div",className:"dataset hda history-panel-hda",id:function(){return"hda-"+this.model.get("id")},fxSpeed:"fast",initialize:function(c){if(c.logger){this.logger=this.model.logger=c.logger}this.log(this+".initialize:",c);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.expanded=c.expanded||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(d,c){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(e){e=(e===undefined)?(true):(e);var c=this;this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();var d=$(a.templates.skeleton(this.model.toJSON()));d.find(".dataset-primary-actions").append(this._render_titleButtons());d.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(d);if(e){$(c).queue(function(f){this.$el.fadeOut(c.fxSpeed,f)})}$(c).queue(function(f){this.$el.empty().attr("class",c.className).addClass("state-"+c.model.get("state")).append(d.children());f()});if(e){$(c).queue(function(f){this.$el.fadeIn(c.fxSpeed,f)})}$(c).queue(function(f){this.trigger("rendered",c);if(this.model.inReadyState()){this.trigger("rendered:ready",c)}f()});return this},_setUpBehaviors:function(c){c=c||this.$el;make_popup_menus(c);c.find("[title]").tooltip({placement:"bottom"})},_render_titleButtons:function(){return[this._render_displayButton()]},_render_displayButton:function(){if((this.model.get("state")===b.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===b.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===b.HistoryDatasetAssociation.STATES.NEW)||(!this.model.get("accessible"))){return null}var d={icon_class:"display",target:"galaxy_main"};if(this.model.get("purged")){d.disabled=true;d.title=_l("Cannot display datasets removed from disk")}else{if(this.model.get("state")===b.HistoryDatasetAssociation.STATES.UPLOAD){d.disabled=true;d.title=_l("This dataset must finish uploading before it can be viewed")}else{d.title=_l("View data");d.href=this.urls.display;var c=this;d.on_click=function(){Galaxy.frame_manager.frame_new({title:"Data Viewer: "+c.model.get("name"),type:"url",location:"center",content:c.urls.display})}}}d.faIcon="fa-eye";return faIconButton(d)},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var d=this.urls,e=this.model.get("meta_files");if(_.isEmpty(e)){return $(['<a href="'+d.download+'" title="'+_l("Download")+'" class="icon-btn">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))}var f="dataset-"+this.model.get("id")+"-popup",c=['<div popupmenu="'+f+'">','<a href="'+d.download+'">',_l("Download Dataset"),"</a>","<a>"+_l("Additional Files")+"</a>",_.map(e,function(g){return['<a class="action-button" href="',d.meta_download+g.file_type,'">',_l("Download")," ",g.file_type,"</a>"].join("")}).join("\n"),"</div>",'<div class="icon-btn-group">','<a href="'+d.download+'" title="'+_l("Download")+'" class="icon-btn">','<span class="fa fa-floppy-o"></span>','</a><a class="icon-btn popup" id="'+f+'">','<span class="fa fa-caret-down"></span>',"</a>","</div>"].join("\n");return $(c)},_render_showParamsButton:function(){return faIconButton({title:_l("View details"),href:this.urls.show_params,target:"galaxy_main",faIcon:"fa-info-circle"})},_render_body:function(){console.debug("model:",this.model.toJSON());var d=$('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'),c=this["_render_body_"+this.model.get("state")];if(_.isFunction(c)){d=c.call(this)}if(this.expanded){d.show()}return d},_render_stateBodyHelper:function(c,f){f=f||[];var d=this,e=$(a.templates.body(_.extend(this.model.toJSON(),{body:c})));e.find(".dataset-actions .left").append(_.map(f,function(g){return g.call(d)}));return e},_render_body_new:function(){return this._render_stateBodyHelper("<div>"+_l("This is a new dataset and not all of its data are available yet")+"</div>")},_render_body_noPermission:function(){return this._render_stateBodyHelper("<div>"+_l("You do not have permission to view this dataset")+"</div>")},_render_body_discarded:function(){return this._render_stateBodyHelper("<div>"+_l("The job creating this dataset was cancelled before completion")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_queued:function(){return this._render_stateBodyHelper("<div>"+_l("This job is waiting to run")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_upload:function(){return this._render_stateBodyHelper("<div>"+_l("This dataset is currently uploading")+"</div>")},_render_body_setting_metadata:function(){return this._render_stateBodyHelper("<div>"+_l("Metadata is being auto-detected")+"</div>")},_render_body_running:function(){return this._render_stateBodyHelper("<div>"+_l("This job is currently running")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_paused:function(){return this._render_stateBodyHelper("<div>"+_l('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_error:function(){var c=_l("An error occurred with this dataset")+": <i>"+$.trim(this.model.get("misc_info"))+"</i>";if(!this.model.get("purged")){c="<div>"+this.model.get("misc_blurb")+"</div>"+c}return this._render_stateBodyHelper(c,this.defaultPrimaryActionButtonRenderers.concat([this._render_downloadButton]))},_render_body_empty:function(){return this._render_stateBodyHelper("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>",this.defaultPrimaryActionButtonRenderers)},_render_body_failed_metadata:function(){var c=$('<div class="warningmessagesmall"></div>').append($("<strong/>").text(_l("An error occurred setting the metadata for this dataset"))),d=this._render_body_ok();d.prepend(c);return d},_render_body_ok:function(){var c=this,e=$(a.templates.body(this.model.toJSON())),d=[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers);e.find(".dataset-actions .left").append(_.map(d,function(f){return f.call(c)}));if(this.model.isDeletedOrPurged()){return e}return e},events:{"click .dataset-title-bar":"toggleBodyVisibility"},toggleBodyVisibility:function(d,c){var e=this.$el.find(".dataset-body");c=(c===undefined)?(!e.is(":visible")):(c);if(c){this.expandBody()}else{this.collapseBody()}},expandBody:function(){var c=this;function d(){c.render(false).$el.children(".dataset-body").slideDown(c.fxSpeed,function(){c.expanded=true;c.trigger("body-expanded",c.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch({silent:true}).always(function(e){d()})}else{d()}},collapseBody:function(){var c=this;this.$el.children(".dataset-body").slideUp(c.fxSpeed,function(){c.expanded=false;c.trigger("body-collapsed",c.model.get("id"))})},remove:function(d){var c=this;this.$el.fadeOut(c.fxSpeed,function(){c.$el.remove();c.off();if(d){d()}})},toString:function(){var c=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+c+")"}});a.templates={skeleton:Handlebars.templates["template-hda-skeleton"],body:Handlebars.templates["template-hda-body"]};return{HDABaseView:a}}); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/mvc/dataset/hda-edit.js --- a/static/scripts/packed/mvc/dataset/hda-edit.js +++ b/static/scripts/packed/mvc/dataset/hda-edit.js @@ -1,1 +1,1 @@ -define(["mvc/dataset/hda-model","mvc/dataset/hda-base"],function(d,a){var f=a.HDABaseView.extend(LoggableMixin).extend({initialize:function(g){a.HDABaseView.prototype.initialize.call(this,g);this.hasUser=g.hasUser;this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton,this._render_rerunButton]},_render_titleButtons:function(){return a.HDABaseView.prototype._render_titleButtons.call(this).concat([this._render_editButton(),this._render_deleteButton()])},_render_editButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.editButton=null;return null}var i=this.model.get("purged"),g=this.model.get("deleted"),h={title:_l("Edit Attributes"),href:this.urls.edit,target:"galaxy_main",icon_class:"edit"};if(g||i){h.enabled=false;if(i){h.title=_l("Cannot edit attributes of datasets removed from disk")}else{if(g){h.title=_l("Undelete dataset to edit attributes")}}}return new IconButtonView({model:new IconButton(h)}).render().$el},_render_deleteButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.deleteButton=null;return null}var g=this,h=g.urls["delete"],i={title:_l("Delete"),href:h,icon_class:"delete",on_click:function(){g.$el.find(".menu-button.delete").trigger("mouseout");g.model["delete"]()}};if(this.model.get("deleted")||this.model.get("purged")){i={title:_l("Dataset is already deleted"),icon_class:"delete",enabled:false}}return new IconButtonView({model:new IconButton(i)}).render().$el},_render_errButton:function(){if(this.model.get("state")!==d.HistoryDatasetAssociation.STATES.ERROR){this.errButton=null;return null}return new IconButtonView({model:new IconButton({title:_l("View or report this error"),href:this.urls.report_error,target:"galaxy_main",icon_class:"bug"})}).render().$el},_render_rerunButton:function(){return new IconButtonView({model:new IconButton({title:_l("Run this job again"),href:this.urls.rerun,target:"galaxy_main",icon_class:"arrow-circle"})}).render().$el},_render_visualizationsButton:function(){var g=this.model.get("visualizations");if((!this.model.hasData())||(_.isEmpty(g))){this.visualizationsButton=null;return null}if(_.isObject(g[0])){return this._render_visualizationsFrameworkButton(g)}if(!this.urls.visualization){this.visualizationsButton=null;return null}var i=this.model.get("dbkey"),l=this.urls.visualization,j={},m={dataset_id:this.model.get("id"),hda_ldda:"hda"};if(i){m.dbkey=i}this.visualizationsButton=new IconButtonView({model:new IconButton({title:_l("Visualize"),href:this.urls.visualization,icon_class:"chart_curve"})});var h=this.visualizationsButton.render().$el;h.addClass("visualize-icon");function k(n){switch(n){case"trackster":return b(l,m,i);case"scatterplot":return e(l,m);default:return function(){Galaxy.frame_manager.frame_new({title:"Visualization",type:"url",content:l+"/"+n+"?"+$.param(m)})}}}if(g.length===1){h.attr("title",g[0]);h.click(k(g[0]))}else{_.each(g,function(o){var n=o.charAt(0).toUpperCase()+o.slice(1);j[_l(n)]=k(o)});make_popupmenu(h,j)}return h},_render_visualizationsFrameworkButton:function(g){if(!(this.model.hasData())||!(g&&!_.isEmpty(g))){this.visualizationsButton=null;return null}this.visualizationsButton=new IconButtonView({model:new IconButton({title:_l("Visualize"),icon_class:"chart_curve"})});var i=this.visualizationsButton.render().$el;i.addClass("visualize-icon");if(_.keys(g).length===1){i.attr("title",_.keys(g)[0]);i.attr("href",_.values(g)[0])}else{var j=[];_.each(g,function(k){j.push(k)});var h=new PopupMenu(i,j)}return i},_render_tagButton:function(){if(!this.hasUser||!this.urls.tags.get){this.tagButton=null;return null}return new IconButtonView({model:new IconButton({title:_l("Edit dataset tags"),target:"galaxy_main",href:this.urls.tags.get,icon_class:"tags"})}).render().$el},_render_annotateButton:function(){if(!this.hasUser||!this.urls.annotation.get){this.annotateButton=null;return null}return new IconButtonView({model:new IconButton({title:_l("Edit dataset annotation"),target:"galaxy_main",icon_class:"annotate"})}).render().$el},_render_body_failed_metadata:function(){var h=$("<a/>").attr({href:this.urls.edit,target:"galaxy_main"}).text(_l("set it manually or retry auto-detection")),g=$("<span/>").text(_l("You may be able to")+" ").append(h),i=a.HDABaseView.prototype._render_body_failed_metadata.call(this);i.find(".warningmessagesmall strong").append(g);return i},_render_body_error:function(){var g=a.HDABaseView.prototype._render_body_error.call(this);g.find(".dataset-actions .left").prepend(this._render_errButton());return g},_render_body_ok:function(){var g=a.HDABaseView.prototype._render_body_ok.call(this);if(this.model.isDeletedOrPurged()){return g}this.makeDbkeyEditLink(g);g.find(".dataset-actions .left").append(this._render_visualizationsButton());g.find(".dataset-actions .right").append([this._render_tagButton(),this._render_annotateButton()]);return g},makeDbkeyEditLink:function(g){if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){g.find(".dataset-dbkey .value").replaceWith($('<a target="galaxy_main">?</a>').attr("href",this.urls.edit))}},events:{"click .dataset-title-bar":"toggleBodyVisibility","click .dataset-undelete":function(g){this.model.undelete();return false},"click .dataset-unhide":function(g){this.model.unhide();return false},"click .dataset-purge":"confirmPurge","click a.icon-button.tags":"loadAndDisplayTags","click a.icon-button.annotate":"loadAndDisplayAnnotation"},confirmPurge:function c(g){this.model.purge();return false},loadAndDisplayTags:function(i){this.log(this+".loadAndDisplayTags",i);var g=this,h=this.$el.find(".tags-display"),j=h.find(".tags");if(h.is(":hidden")){if(!jQuery.trim(j.html())){var k=$.ajax(this.urls.tags.get);k.fail(function(n,l,m){g.log("Tagging failed",n,l,m);g.trigger("error",g,n,{},_l("Tagging failed"))});k.done(function(l){j.html(l);j.find("[title]").tooltip();h.slideDown(g.fxSpeed)})}else{h.slideDown(g.fxSpeed)}}else{h.slideUp(g.fxSpeed)}return false},loadAndDisplayAnnotation:function(k){this.log(this+".loadAndDisplayAnnotation",k);var i=this,h=this.$el.find(".annotation-display"),g=h.find(".annotation"),j=this.urls.annotation.set;if(h.is(":hidden")){if(!jQuery.trim(g.html())){var l=$.ajax(this.urls.annotation.get);l.fail(function(o,m,n){i.log("Annotation failed",o,m,n);i.trigger("error",i,o,{},_l("Annotation failed"))});l.done(function(m){m=m||"<em>"+_l("Describe or add notes to dataset")+"</em>";g.html(m);h.find("[title]").tooltip();g.make_text_editable({use_textarea:true,on_finish:function(n){g.text(n);i.model.save({annotation:n},{silent:true}).fail(function(){g.text(i.model.previous("annotation"))})}});h.slideDown(i.fxSpeed)})}else{h.slideDown(i.fxSpeed)}}else{h.slideUp(i.fxSpeed)}return false},toString:function(){var g=(this.model)?(this.model+""):("(no model)");return"HDAView("+g+")"}});function e(g,h){action=function(){Galaxy.frame_manager.frame_new({title:"Scatterplot",type:"url",content:g+"/scatterplot?"+$.param(h),location:"center"});$("div.popmenu-wrapper").remove();return false};return action}function b(g,i,h){return function(){var j={};if(h){j["f-dbkey"]=h}$.ajax({url:g+"/list_tracks?"+$.param(j),dataType:"html",error:function(){alert(("Could not add this dataset to browser")+".")},success:function(k){var l=window.parent;l.Galaxy.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){l.Galaxy.modal.hide()},"View in saved visualization":function(){l.Galaxy.modal.show({title:"Add Data to Saved Visualization",body:k,buttons:{Cancel:function(){l.Galaxy.modal.hide()},"Add to visualization":function(){$(l.document).find("input[name=id]:checked").each(function(){l.Galaxy.modal.hide();var m=$(this).val();i.id=m;l.Galaxy.frame_manager.frame_new({title:"Trackster",type:"url",content:g+"/trackster?"+$.param(i)})})}}})},"View in new visualization":function(){l.Galaxy.modal.hide();var m=g+"/trackster?"+$.param(i);l.Galaxy.frame_manager.frame_new({title:"Trackster",type:"url",content:m})}}})}});return false}}return{HDAEditView:f}}); \ No newline at end of file +define(["mvc/dataset/hda-model","mvc/dataset/hda-base"],function(d,a){var f=a.HDABaseView.extend(LoggableMixin).extend({initialize:function(g){a.HDABaseView.prototype.initialize.call(this,g);this.hasUser=g.hasUser;this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton,this._render_rerunButton]},_render_titleButtons:function(){return a.HDABaseView.prototype._render_titleButtons.call(this).concat([this._render_editButton(),this._render_deleteButton()])},_render_editButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){return null}var i=this.model.get("purged"),g=this.model.get("deleted"),h={title:_l("Edit Attributes"),href:this.urls.edit,target:"galaxy_main",icon_class:"edit"};if(g||i){h.enabled=false;if(i){h.title=_l("Cannot edit attributes of datasets removed from disk")}else{if(g){h.title=_l("Undelete dataset to edit attributes")}}}else{if(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD){h.disabled=true;h.title=_l("This dataset must finish uploading before it can be edited")}}h.faIcon="fa-pencil";return faIconButton(h)},_render_deleteButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){return null}var g=this,h=g.urls["delete"],i={title:_l("Delete"),href:h,icon_class:"delete",onclick:function(){g.$el.find(".menu-button.delete").trigger("mouseout");g.model["delete"]()}};if(this.model.get("deleted")||this.model.get("purged")){i={title:_l("Dataset is already deleted"),icon_class:"delete",enabled:false}}i.faIcon="fa-times";return faIconButton(i)},_render_errButton:function(){if(this.model.get("state")!==d.HistoryDatasetAssociation.STATES.ERROR){return null}return faIconButton({title:_l("View or report this error"),href:this.urls.report_error,target:"galaxy_main",faIcon:"fa-bug"})},_render_rerunButton:function(){return faIconButton({title:_l("Run this job again"),href:this.urls.rerun,target:"galaxy_main",faIcon:"fa-refresh"})},_render_visualizationsButton:function(){var g=this.model.get("visualizations");if((!this.model.hasData())||(_.isEmpty(g))){return null}if(_.isObject(g[0])){return this._render_visualizationsFrameworkButton(g)}if(!this.urls.visualization){return null}var i=this.model.get("dbkey"),l=this.urls.visualization,j={},m={dataset_id:this.model.get("id"),hda_ldda:"hda"};if(i){m.dbkey=i}var h=faIconButton({title:_l("Visualize"),href:this.urls.visualization,faIcon:"fa-bar-chart-o"});function k(n){switch(n){case"trackster":return b(l,m,i);case"scatterplot":return e(l,m);default:return function(){Galaxy.frame_manager.frame_new({title:"Visualization",type:"url",content:l+"/"+n+"?"+$.param(m)})}}}if(g.length===1){h.attr("title",g[0]);h.click(k(g[0]))}else{_.each(g,function(o){var n=o.charAt(0).toUpperCase()+o.slice(1);j[_l(n)]=k(o)});make_popupmenu(h,j)}return h},_render_visualizationsFrameworkButton:function(g){if(!(this.model.hasData())||!(g&&!_.isEmpty(g))){return null}var i=faIconButton({title:_l("Visualize"),faIcon:"fa-bar-chart-o"});i.addClass("visualize-icon");if(_.keys(g).length===1){i.attr("title",_.keys(g)[0]);i.attr("href",_.values(g)[0])}else{var j=[];_.each(g,function(k){j.push(k)});var h=new PopupMenu(i,j)}return i},_render_tagButton:function(){if(!this.hasUser||!this.urls.tags.get){return null}return faIconButton({title:_l("Edit dataset tags"),classes:"dataset-tag-btn",faIcon:"fa-tags"})},_render_annotateButton:function(){if(!this.hasUser||!this.urls.annotation.get){return null}return faIconButton({title:_l("Edit dataset annotation"),classes:"dataset-annotate-btn",faIcon:"fa-comment"})},_render_body_failed_metadata:function(){var h=$("<a/>").attr({href:this.urls.edit,target:"galaxy_main"}).text(_l("set it manually or retry auto-detection")),g=$("<span/>").text(". "+_l("You may be able to")+" ").append(h),i=a.HDABaseView.prototype._render_body_failed_metadata.call(this);i.find(".warningmessagesmall strong").append(g);return i},_render_body_error:function(){var g=a.HDABaseView.prototype._render_body_error.call(this);g.find(".dataset-actions .left").prepend(this._render_errButton());return g},_render_body_ok:function(){var g=a.HDABaseView.prototype._render_body_ok.call(this);if(this.model.isDeletedOrPurged()){return g}this.makeDbkeyEditLink(g);g.find(".dataset-actions .left").append(this._render_visualizationsButton());g.find(".dataset-actions .right").append([this._render_tagButton(),this._render_annotateButton()]);return g},makeDbkeyEditLink:function(g){if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){g.find(".dataset-dbkey .value").replaceWith($('<a target="galaxy_main">?</a>').attr("href",this.urls.edit))}},events:{"click .dataset-title-bar":"toggleBodyVisibility","click .dataset-undelete":function(g){this.model.undelete();return false},"click .dataset-unhide":function(g){this.model.unhide();return false},"click .dataset-purge":"confirmPurge","click .dataset-tag-btn":"loadAndDisplayTags","click .dataset-annotate-btn":"loadAndDisplayAnnotation"},confirmPurge:function c(g){this.model.purge();return false},loadAndDisplayTags:function(i){this.log(this+".loadAndDisplayTags",i);var g=this,h=this.$el.find(".tags-display"),j=h.find(".tags");if(h.is(":hidden")){if(!jQuery.trim(j.html())){var k=$.ajax(this.urls.tags.get);k.fail(function(n,l,m){g.log("Tagging failed",n,l,m);g.trigger("error",g,n,{},_l("Tagging failed"))});k.done(function(l){j.html(l);j.find("[title]").tooltip();h.slideDown(g.fxSpeed)})}else{h.slideDown(g.fxSpeed)}}else{h.slideUp(g.fxSpeed)}return false},loadAndDisplayAnnotation:function(j){this.log(this+".loadAndDisplayAnnotation",j);var i=this,h=this.$el.find(".annotation-display"),g=h.find(".annotation");if(h.is(":hidden")){if(!jQuery.trim(g.html())){var k=$.ajax(this.urls.annotation.get);k.fail(function(n,l,m){i.log("Annotation failed",n,l,m);i.trigger("error",i,n,{},_l("Annotation failed"))});k.done(function(l){l=l||"<em>"+_l("Describe or add notes to dataset")+"</em>";g.html(l);h.find("[title]").tooltip();g.make_text_editable({use_textarea:true,on_finish:function(m){g.text(m);i.model.save({annotation:m},{silent:true}).fail(function(){g.text(i.model.previous("annotation"))})}});h.slideDown(i.fxSpeed)})}else{h.slideDown(i.fxSpeed)}}else{h.slideUp(i.fxSpeed)}return false},toString:function(){var g=(this.model)?(this.model+""):("(no model)");return"HDAView("+g+")"}});function e(g,h){action=function(){Galaxy.frame_manager.frame_new({title:"Scatterplot",type:"url",content:g+"/scatterplot?"+$.param(h),location:"center"});$("div.popmenu-wrapper").remove();return false};return action}function b(g,i,h){return function(){var j={};if(h){j["f-dbkey"]=h}$.ajax({url:g+"/list_tracks?"+$.param(j),dataType:"html",error:function(){alert(("Could not add this dataset to browser")+".")},success:function(k){var l=window.parent;l.Galaxy.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){l.Galaxy.modal.hide()},"View in saved visualization":function(){l.Galaxy.modal.show({title:"Add Data to Saved Visualization",body:k,buttons:{Cancel:function(){l.Galaxy.modal.hide()},"Add to visualization":function(){$(l.document).find("input[name=id]:checked").each(function(){l.Galaxy.modal.hide();var m=$(this).val();i.id=m;l.Galaxy.frame_manager.frame_new({title:"Trackster",type:"url",content:g+"/trackster?"+$.param(i)})})}}})},"View in new visualization":function(){l.Galaxy.modal.hide();var m=g+"/trackster?"+$.param(i);l.Galaxy.frame_manager.frame_new({title:"Trackster",type:"url",content:m})}}})}});return false}}return{HDAEditView:f}}); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/mvc/dataset/hda-model.js --- a/static/scripts/packed/mvc/dataset/hda-model.js +++ b/static/scripts/packed/mvc/dataset/hda-model.js @@ -1,1 +1,1 @@ -define([],function(){var d=Backbone.Model.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"new",deleted:false,visible:true,accessible:true,purged:false,data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:""},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("history_id")+"/contents/"+this.get("id")},urls:function(){var i=this.get("id");if(!i){return{}}var h={purge:galaxy_config.root+"datasets/"+i+"/purge_async",display:galaxy_config.root+"datasets/"+i+"/display/?preview=True",edit:galaxy_config.root+"datasets/"+i+"/edit",download:galaxy_config.root+"datasets/"+i+"/display?to_ext="+this.get("file_ext"),report_error:galaxy_config.root+"dataset/errors?id="+i,rerun:galaxy_config.root+"tool_runner/rerun?id="+i,show_params:galaxy_config.root+"datasets/"+i+"/show_params",visualization:galaxy_config.root+"visualization",annotation:{get:galaxy_config.root+"dataset/get_annotation_async?id="+i,set:galaxy_config.root+"dataset/annotate_async?id="+i},tags:{get:galaxy_config.root+"tag/get_tagging_elt_async?item_id="+i+"&item_class=HistoryDatasetAssociation",set:galaxy_config.root+"tag/retag?item_id="+i+"&item_class=HistoryDatasetAssociation"},meta_download:galaxy_config.root+"dataset/get_metadata_file?hda_id="+i+"&metadata_name="};return h},initialize:function(h){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",d.STATES.NOT_VIEWABLE)}this._setUpListeners()},_setUpListeners:function(){this.on("change:state",function(i,h){this.log(this+" has changed state:",i,h);if(this.inReadyState()){this.trigger("state:ready",i,h,this.previous("state"))}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(i,j){var h=true;if((!i)&&(this.get("deleted")||this.get("purged"))){h=false}if((!j)&&(!this.get("visible"))){h=false}return h},hidden:function(){return !this.get("visible")},inReadyState:function(){var h=_.contains(d.READY_STATES,this.get("state"));return(this.isDeletedOrPurged()||h)},hasDetails:function(){return _.has(this.attributes,"genome_build")},hasData:function(){return(this.get("file_size")>0)},"delete":function c(h){return this.save({deleted:true},h)},undelete:function a(h){return this.save({deleted:false},h)},hide:function b(h){return this.save({visible:false},h)},unhide:function g(h){return this.save({visible:true},h)},purge:function f(h){h=h||{};h.url=galaxy_config.root+"datasets/"+this.get("id")+"/purge_async";var i=this,j=jQuery.ajax(h);j.done(function(m,k,l){i.set("purged",true)});j.fail(function(o,k,n){var l=_l("Unable to purge this dataset");var m=("Removal of datasets by users is not allowed in this Galaxy instance");if(o.responseJSON&&o.responseJSON.error){l=o.responseJSON.error}else{if(o.responseText.indexOf(m)!==-1){l=m}}o.responseText=l;i.trigger("error",i,o,h,_l(l),{error:l})})},searchKeys:["name","file_ext","genome_build","misc_blurb","misc_info","annotation","tags"],search:function(h){var i=this;h=h.toLowerCase();return _.filter(this.searchKeys,function(k){var j=i.get(k);return(_.isString(j)&&j.toLowerCase().indexOf(h)!==-1)})},matches:function(h){return !!this.search(h).length},toString:function(){var h=this.get("id")||"";if(this.get("name")){h=this.get("hid")+' :"'+this.get("name")+'",'+h}return"HDA("+h+")"}});d.STATES={UPLOAD:"upload",QUEUED:"queued",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",PAUSED:"paused",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};d.READY_STATES=[d.STATES.NEW,d.STATES.OK,d.STATES.EMPTY,d.STATES.PAUSED,d.STATES.FAILED_METADATA,d.STATES.NOT_VIEWABLE,d.STATES.DISCARDED,d.STATES.ERROR];d.NOT_READY_STATES=[d.STATES.UPLOAD,d.STATES.QUEUED,d.STATES.RUNNING,d.STATES.SETTING_METADATA];var e=Backbone.Collection.extend(LoggableMixin).extend({model:d,urlRoot:galaxy_config.root+"api/histories",url:function(){return this.urlRoot+"/"+this.historyId+"/contents"},initialize:function(i,h){h=h||{};this.historyId=h.historyId},ids:function(){return this.map(function(h){return h.id})},notReady:function(){return this.filter(function(h){return !h.inReadyState()})},running:function(){var h=[];this.each(function(i){if(!i.inReadyState()){h.push(i.get("id"))}});return h},getByHid:function(h){return _.first(this.filter(function(i){return i.get("hid")===h}))},getVisible:function(h,i){return this.filter(function(j){return j.isVisible(h,i)})},fetchAllDetails:function(){return this.fetch({data:{details:"all"}})},matches:function(h){return this.filter(function(i){return i.matches(h)})},set:function(j,h){var i=this;j=_.map(j,function(l){var m=i.get(l.id);if(!m){return l}var k=m.toJSON();_.extend(k,l);return k});Backbone.Collection.prototype.set.call(this,j,h)},toString:function(){return("HDACollection()")}});return{HistoryDatasetAssociation:d,HDACollection:e}}); \ No newline at end of file +define([],function(){var d=Backbone.Model.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"new",deleted:false,visible:true,accessible:true,purged:false,data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:""},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("history_id")+"/contents/"+this.get("id")},urls:function(){var i=this.get("id");if(!i){return{}}var h={purge:galaxy_config.root+"datasets/"+i+"/purge_async",display:galaxy_config.root+"datasets/"+i+"/display/?preview=True",edit:galaxy_config.root+"datasets/"+i+"/edit",download:galaxy_config.root+"datasets/"+i+"/display?to_ext="+this.get("file_ext"),report_error:galaxy_config.root+"dataset/errors?id="+i,rerun:galaxy_config.root+"tool_runner/rerun?id="+i,show_params:galaxy_config.root+"datasets/"+i+"/show_params",visualization:galaxy_config.root+"visualization",annotation:{get:galaxy_config.root+"dataset/get_annotation_async?id="+i,set:galaxy_config.root+"dataset/annotate_async?id="+i},tags:{get:galaxy_config.root+"tag/get_tagging_elt_async?item_id="+i+"&item_class=HistoryDatasetAssociation",set:galaxy_config.root+"tag/retag?item_id="+i+"&item_class=HistoryDatasetAssociation"},meta_download:galaxy_config.root+"dataset/get_metadata_file?hda_id="+i+"&metadata_name="};return h},initialize:function(h){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",d.STATES.NOT_VIEWABLE)}this._setUpListeners()},_setUpListeners:function(){this.on("change:state",function(i,h){this.log(this+" has changed state:",i,h);if(this.inReadyState()){this.trigger("state:ready",i,h,this.previous("state"))}})},toJSON:function(){var h=Backbone.Model.prototype.toJSON.call(this);h.misc_info=jQuery.trim(h.misc_info);return h},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(i,j){var h=true;if((!i)&&(this.get("deleted")||this.get("purged"))){h=false}if((!j)&&(!this.get("visible"))){h=false}return h},hidden:function(){return !this.get("visible")},inReadyState:function(){var h=_.contains(d.READY_STATES,this.get("state"));return(this.isDeletedOrPurged()||h)},hasDetails:function(){return _.has(this.attributes,"genome_build")},hasData:function(){return(this.get("file_size")>0)},"delete":function c(h){return this.save({deleted:true},h)},undelete:function a(h){return this.save({deleted:false},h)},hide:function b(h){return this.save({visible:false},h)},unhide:function g(h){return this.save({visible:true},h)},purge:function f(h){h=h||{};h.url=galaxy_config.root+"datasets/"+this.get("id")+"/purge_async";var i=this,j=jQuery.ajax(h);j.done(function(m,k,l){i.set("purged",true)});j.fail(function(o,k,n){var l=_l("Unable to purge this dataset");var m=("Removal of datasets by users is not allowed in this Galaxy instance");if(o.responseJSON&&o.responseJSON.error){l=o.responseJSON.error}else{if(o.responseText.indexOf(m)!==-1){l=m}}o.responseText=l;i.trigger("error",i,o,h,_l(l),{error:l})})},searchKeys:["name","file_ext","genome_build","misc_blurb","misc_info","annotation","tags"],search:function(h){var i=this;h=h.toLowerCase();return _.filter(this.searchKeys,function(k){var j=i.get(k);return(_.isString(j)&&j.toLowerCase().indexOf(h)!==-1)})},matches:function(h){return !!this.search(h).length},toString:function(){var h=this.get("id")||"";if(this.get("name")){h=this.get("hid")+' :"'+this.get("name")+'",'+h}return"HDA("+h+")"}});d.STATES={UPLOAD:"upload",QUEUED:"queued",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",PAUSED:"paused",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};d.READY_STATES=[d.STATES.NEW,d.STATES.OK,d.STATES.EMPTY,d.STATES.PAUSED,d.STATES.FAILED_METADATA,d.STATES.NOT_VIEWABLE,d.STATES.DISCARDED,d.STATES.ERROR];d.NOT_READY_STATES=[d.STATES.UPLOAD,d.STATES.QUEUED,d.STATES.RUNNING,d.STATES.SETTING_METADATA];var e=Backbone.Collection.extend(LoggableMixin).extend({model:d,urlRoot:galaxy_config.root+"api/histories",url:function(){return this.urlRoot+"/"+this.historyId+"/contents"},initialize:function(i,h){h=h||{};this.historyId=h.historyId},ids:function(){return this.map(function(h){return h.id})},notReady:function(){return this.filter(function(h){return !h.inReadyState()})},running:function(){var h=[];this.each(function(i){if(!i.inReadyState()){h.push(i.get("id"))}});return h},getByHid:function(h){return _.first(this.filter(function(i){return i.get("hid")===h}))},getVisible:function(h,i){return this.filter(function(j){return j.isVisible(h,i)})},fetchAllDetails:function(){return this.fetch({data:{details:"all"}})},matches:function(h){return this.filter(function(i){return i.matches(h)})},set:function(j,h){var i=this;j=_.map(j,function(l){var m=i.get(l.id);if(!m){return l}var k=m.toJSON();_.extend(k,l);return k});Backbone.Collection.prototype.set.call(this,j,h)},toString:function(){return("HDACollection()")}});return{HistoryDatasetAssociation:d,HDACollection:e}}); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d 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/dataset/hda-base","mvc/dataset/hda-edit"],function(d,b,a){var c=Backbone.View.extend(LoggableMixin).extend({HDAView:a.HDAEditView,tagName:"div",className:"history-panel",fxSpeed:400,events:{"click .icon-button.tags":"loadAndDisplayTags","click .message-container":"clearMessages"},datasetsSelector:".datasets-list",emptyMsgSelector:".empty-history-message",msgsSelector:".message-container",initialize:function(e){e=e||{};if(e.logger){this.logger=e.logger}this.log(this+".initialize:",e);this._setUpListeners();this.hdaViews={};this.indicator=new LoadingIndicator(this.$el);if(this.model){this._setUpWebStorage(e.initiallyExpanded,e.show_deleted,e.show_hidden);this._setUpModelEventHandlers()}if(e.onready){e.onready.call(this)}},_setUpListeners:function(){this.on("error",function(f,i,e,h,g){this.errorHandler(f,i,e,h,g)});this.on("loading-history",function(){this.showLoadingIndicator("loading history...")});this.on("loading-done",function(){this.hideLoadingIndicator()});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});this.on("switched-history current-history new-history",function(){if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});if(this.logger){this.on("all",function(e){this.log(this+"",arguments)},this)}},errorHandler:function(g,j,f,i,h){var e=this._parseErrorMessage(g,j,f,i,h);if(j&&j.status===0&&j.readyState===0){}else{if(j&&j.status===502){}else{if(!this.$el.find(this.msgsSelector).is(":visible")){this.once("rendered",function(){this.displayMessage("error",e.message,e.details)})}else{this.displayMessage("error",e.message,e.details)}}}},_parseErrorMessage:function(h,l,g,k,j){var f=Galaxy.currUser,e={message:this._bePolite(k),details:{user:(f instanceof User)?(f.toJSON()):(f+""),source:(h instanceof Backbone.Model)?(h.toJSON()):(h+""),xhr:l,options:(l)?(_.omit(g,"xhr")):(g)}};_.extend(e.details,j||{});if(l&&_.isFunction(l.getAllResponseHeaders)){var i=l.getAllResponseHeaders();i=_.compact(i.split("\n"));i=_.map(i,function(m){return m.split(": ")});e.details.xhr.responseHeaders=_.object(i)}return e},_bePolite:function(e){e=e||_l("An error occurred while getting updates from the server");return e+". "+_l("Please contact a Galaxy administrator if the problem persists.")},loadCurrentHistory:function(f){var e=this;return this.loadHistoryWithHDADetails("current",f).then(function(h,g){e.trigger("current-history",e)})},switchToHistory:function(h,g){var e=this,f=function(){return jQuery.post(galaxy_config.root+"api/histories/"+h+"/set_as_current")};return this.loadHistoryWithHDADetails(h,g,f).then(function(j,i){e.trigger("switched-history",e)})},createNewHistory:function(g){var e=this,f=function(){return jQuery.post(galaxy_config.root+"api/histories",{current:true})};return this.loadHistory(undefined,g,f).then(function(i,h){e.trigger("new-history",e)})},loadHistoryWithHDADetails:function(h,g,f,j){var e=this,i=function(k){return e.getExpandedHdaIds(k.id)};return this.loadHistory(h,g,f,j,i)},loadHistory:function(h,g,f,k,i){this.trigger("loading-history",this);g=g||{};var e=this;var j=d.History.getHistoryData(h,{historyFn:f,hdaFn:k,hdaDetailIds:g.initiallyExpanded||i});return this._loadHistoryFromXHR(j,g).fail(function(n,l,m){e.trigger("error",e,n,g,_l("An error was encountered while "+l),{historyId:h,history:m||{}})}).always(function(){e.trigger("loading-done",e)})},_loadHistoryFromXHR:function(g,f){var e=this;g.then(function(h,i){e.setModel(h,i,f)});g.fail(function(i,h){e.render()});return g},setModel:function(g,e,f){f=f||{};if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.hdas)}this.hdaViews={};if(Galaxy&&Galaxy.currUser){g.user=Galaxy.currUser.toJSON()}this.model=new d.History(g,e,f);this._setUpWebStorage(f.initiallyExpanded,f.show_deleted,f.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this);this.render();return this},refreshHdas:function(f,e){if(this.model){return this.model.refresh(f,e)}return $.when()},_setUpWebStorage:function(f,e,g){this.storage=new PersistentStorage(this._getStorageKey(this.model.get("id")),{expandedHdas:{},show_deleted:false,show_hidden:false});this.log(this+" (prev) storage:",JSON.stringify(this.storage.get(),null,2));if(f){this.storage.set("exandedHdas",f)}if((e===true)||(e===false)){this.storage.set("show_deleted",e)}if((g===true)||(g===false)){this.storage.set("show_hidden",g)}this.show_deleted=this.storage.get("show_deleted");this.show_hidden=this.storage.get("show_hidden");this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get())},_getStorageKey:function(e){if(!e){throw new Error("_getStorageKey needs valid id: "+e)}return("history:"+e)},clearWebStorage:function(){for(var e in sessionStorage){if(e.indexOf("history:")===0){sessionStorage.removeItem(e)}}},getStoredOptions:function(f){if(!f||f==="current"){return(this.storage)?(this.storage.get()):({})}var e=sessionStorage.getItem(this._getStorageKey(f));return(e===null)?({}):(JSON.parse(e))},getExpandedHdaIds:function(e){var f=this.getStoredOptions(e).expandedHdas;return((_.isEmpty(f))?([]):(_.keys(f)))},_setUpModelEventHandlers:function(){this.model.on("error error:hdas",function(f,h,e,g){this.errorHandler(f,h,e,g)},this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);if(Galaxy&&Galaxy.quotaMeter){this.listenTo(this.model,"change:nice_size",function(){Galaxy.quotaMeter.update()})}this.model.hdas.on("add",this.addHdaView,this);this.model.hdas.on("change:deleted",this.handleHdaDeletionChange,this);this.model.hdas.on("change:visible",this.handleHdaVisibleChange,this);this.model.hdas.on("change:purged",function(e){this.model.fetch()},this);this.model.hdas.on("state:ready",function(f,g,e){if((!f.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(this.hdaViews[f.id])}},this)},addHdaView:function(h){this.log("add."+this,h);var f=this;if(!h.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return}$({}).queue([function g(j){var i=f.$el.find(f.emptyMsgSelector);if(i.is(":visible")){i.fadeOut(f.fxSpeed,j)}else{j()}},function e(j){f.scrollToTop();var i=f.$el.find(f.datasetsSelector);f.createHdaView(h).$el.hide().prependTo(i).slideDown(f.fxSpeed)}])},createHdaView:function(g){var f=g.get("id"),e=this.storage.get("expandedHdas").get(f),h=new this.HDAView({model:g,expanded:e,hasUser:this.model.hasUser(),logger:this.logger});this._setUpHdaListeners(h);this.hdaViews[f]=h;return h.render()},_setUpHdaListeners:function(f){var e=this;f.on("body-expanded",function(g){e.storage.get("expandedHdas").set(g,true)});f.on("body-collapsed",function(g){e.storage.get("expandedHdas").deleteKey(g)});f.on("error",function(h,j,g,i){e.errorHandler(h,j,g,i)})},handleHdaDeletionChange:function(e){if(e.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(this.hdaViews[e.id])}},handleHdaVisibleChange:function(e){if(e.hidden()&&!this.storage.get("show_hidden")){this.removeHdaView(this.hdaViews[e.id])}},removeHdaView:function(f){if(!f){return}var e=this;f.$el.fadeOut(e.fxSpeed,function(){f.off();f.remove();delete e.hdaViews[f.model.id];if(_.isEmpty(e.hdaViews)){e.$el.find(e.emptyMsgSelector).fadeIn(e.fxSpeed,function(){e.trigger("empty-history",e)})}})},render:function(g){var e=this,f;if(this.model){f=this.renderModel()}else{f=this.renderWithoutModel()}$(e).queue("fx",[function(h){if(e.$el.is(":visible")){e.$el.fadeOut(e.fxSpeed,h)}else{h()}},function(h){e.$el.empty();if(f){e.$el.append(f.children())}e.$el.fadeIn(e.fxSpeed,h)},function(h){e._setUpBehaviours();if(g){g.call(this)}e.trigger("rendered",this)}]);return this},renderModel:function(){var e=$("<div/>");var f=(!Galaxy.currUser.isAnonymous())?(c.templates.historyPanel):(c.templates.anonHistoryPanel);e.append(f(this.model.toJSON()));e.find("[title]").tooltip({placement:"bottom"});if(!this.model.hdas.length||!this.renderItems(e.find(this.datasetsSelector))){e.find(this.emptyMsgSelector).show()}return e},renderWithoutModel:function(){var e=$("<div/>"),f=$("<div/>").addClass("message-container").css({"margin-left":"4px","margin-right":"4px"});return e.append(f)},renderItems:function(f){this.hdaViews={};var e=this,g=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"));_.each(g,function(h){f.prepend(e.createHdaView(h).$el)});return g.length},_setUpBehaviours:function(){if(!this.model||!Galaxy.currUser||Galaxy.currUser.isAnonymous()){return}var e=this,f=this.$el.find(".history-controls .annotation-display");this.$el.find(".history-controls .icon-button.annotate").click(function(){if(f.is(":hidden")){f.slideDown(e.fxSpeed)}else{f.slideUp(e.fxSpeed)}return false});this.$el.find(".history-name").make_text_editable({on_finish:function(g){e.$el.find(".history-name").text(g);e.model.save({name:g}).fail(function(){e.$el.find(".history-name").text(e.model.previous("name"))})}});this.$el.find(".history-controls .annotation").make_text_editable({use_textarea:true,on_finish:function(g){e.$el.find(".history-controls .annotation").text(g);e.model.save({annotation:g}).fail(function(){e.$el.find(".history-controls .annotation").text(e.model.previous("annotation"))})}})},updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(e){e.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},toggleShowDeleted:function(){this.storage.set("show_deleted",!this.storage.get("show_deleted"));this.render();return this.storage.get("show_deleted")},toggleShowHidden:function(){this.storage.set("show_hidden",!this.storage.get("show_hidden"));this.render();return this.storage.get("show_hidden")},loadAndDisplayTags:function(g){var e=this,f=this.$el.find(".history-controls .tags-display"),h=f.find(".tags");if(f.is(":hidden")){if(!jQuery.trim(h.html())){var i=jQuery.ajax(e.model.tagUrl());i.fail(function(l,j,k){e.log("Error loading tag area html",l,k,j);e.trigger("error",e,l,null,_l("Error loading tags"))});i.done(function(j){h.html(j);h.find("[title]").tooltip();f.slideDown(e.fxSpeed)})}else{f.slideDown(e.fxSpeed)}}else{f.slideUp(e.fxSpeed)}return false},showLoadingIndicator:function(f,e,g){e=(e!==undefined)?(e):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,g)}else{this.$el.fadeOut(e);this.indicator.show(f,e,g)}},hideLoadingIndicator:function(e,f){e=(e!==undefined)?(e):(this.fxSpeed);if(this.indicator){this.indicator.hide(e,f)}},displayMessage:function(j,k,i){var g=this;this.scrollToTop();var h=this.$el.find(this.msgsSelector),e=$("<div/>").addClass(j+"message").html(k);if(!_.isEmpty(i)){var f=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(g.messageToModalOptions(j,k,i));return false});e.append(" ",f)}return h.html(e)},messageToModalOptions:function(i,k,h){var e=this,j=$("<div/>"),g={title:"Details"};function f(l){l=_.omit(l,_.functions(l));return["<table>",_.map(l,function(n,m){n=(_.isObject(n))?(f(n)):(n);return'<tr><td style="vertical-align: top; color: grey">'+m+'</td><td style="padding-left: 8px">'+n+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(h)){g.body=j.append(f(h))}else{g.body=j.html(h)}g.buttons={Ok:function(){Galaxy.modal.hide();e.clearMessages()}};return g},clearMessages:function(){var e=this.$el.find(this.msgsSelector);e.empty()},scrollPosition:function(){return this.$el.parent().scrollTop()},scrollTo:function(e){this.$el.parent().scrollTop(e)},scrollToTop:function(){this.$el.parent().scrollTop(0);return this},scrollIntoView:function(f,g){if(!g){this.$el.parent().parent().scrollTop(f);return this}var e=window,h=this.$el.parent().parent(),j=$(e).innerHeight(),i=(j/2)-(g/2);$(h).scrollTop(f-i);return this},scrollToId:function(f){if((!f)||(!this.hdaViews[f])){return this}var e=this.hdaViews[f].$el;this.scrollIntoView(e.offset().top,e.outerHeight());return this},scrollToHid:function(e){var f=this.model.hdas.getByHid(e);if(!f){return this}return this.scrollToId(f.id)},connectToQuotaMeter:function(e){if(!e){return this}this.listenTo(e,"quota:over",this.showQuotaMessage);this.listenTo(e,"quota:under",this.hideQuotaMessage);this.on("rendered rendered:initial",function(){if(e&&e.isOverQuota()){this.showQuotaMessage()}});return this},showQuotaMessage:function(){var e=this.$el.find(".quota-message");if(e.is(":hidden")){e.slideDown(this.fxSpeed)}},hideQuotaMessage:function(){var e=this.$el.find(".quota-message");if(!e.is(":hidden")){e.slideUp(this.fxSpeed)}},connectToOptionsMenu:function(e){if(!e){return this}this.on("new-storage",function(g,f){if(e&&g){e.findItemByHtml(_l("Include Deleted Datasets")).checked=g.get("show_deleted");e.findItemByHtml(_l("Include Hidden Datasets")).checked=g.get("show_hidden")}});return this},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});c.templates={historyPanel:Handlebars.templates["template-history-historyPanel"],anonHistoryPanel:Handlebars.templates["template-history-historyPanel-anon"]};return{HistoryPanel:c}}); \ No newline at end of file +define(["mvc/history/history-model","mvc/dataset/hda-base","mvc/dataset/hda-edit"],function(d,b,a){var c=Backbone.View.extend(LoggableMixin).extend({HDAView:a.HDAEditView,tagName:"div",className:"history-panel",fxSpeed:"fast",datasetsSelector:".datasets-list",emptyMsgSelector:".empty-history-message",msgsSelector:".message-container",initialize:function(e){e=e||{};if(e.logger){this.logger=e.logger}this.log(this+".initialize:",e);this._setUpListeners();this.hdaViews={};this.indicator=new LoadingIndicator(this.$el);if(this.model){this._setUpWebStorage(e.initiallyExpanded,e.show_deleted,e.show_hidden);this._setUpModelEventHandlers()}if(e.onready){e.onready.call(this)}},_setUpListeners:function(){this.on("error",function(f,i,e,h,g){this.errorHandler(f,i,e,h,g)});this.on("loading-history",function(){this.showLoadingIndicator("loading history...")});this.on("loading-done",function(){this.hideLoadingIndicator()});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});this.on("switched-history current-history new-history",function(){if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});if(this.logger){this.on("all",function(e){this.log(this+"",arguments)},this)}},errorHandler:function(g,j,f,i,h){var e=this._parseErrorMessage(g,j,f,i,h);if(j&&j.status===0&&j.readyState===0){}else{if(j&&j.status===502){}else{if(!this.$el.find(this.msgsSelector).is(":visible")){this.once("rendered",function(){this.displayMessage("error",e.message,e.details)})}else{this.displayMessage("error",e.message,e.details)}}}},_parseErrorMessage:function(h,l,g,k,j){var f=Galaxy.currUser,e={message:this._bePolite(k),details:{user:(f instanceof User)?(f.toJSON()):(f+""),source:(h instanceof Backbone.Model)?(h.toJSON()):(h+""),xhr:l,options:(l)?(_.omit(g,"xhr")):(g)}};_.extend(e.details,j||{});if(l&&_.isFunction(l.getAllResponseHeaders)){var i=l.getAllResponseHeaders();i=_.compact(i.split("\n"));i=_.map(i,function(m){return m.split(": ")});e.details.xhr.responseHeaders=_.object(i)}return e},_bePolite:function(e){e=e||_l("An error occurred while getting updates from the server");return e+". "+_l("Please contact a Galaxy administrator if the problem persists.")},loadCurrentHistory:function(f){var e=this;return this.loadHistoryWithHDADetails("current",f).then(function(h,g){e.trigger("current-history",e)})},switchToHistory:function(h,g){var e=this,f=function(){return jQuery.post(galaxy_config.root+"api/histories/"+h+"/set_as_current")};return this.loadHistoryWithHDADetails(h,g,f).then(function(j,i){e.trigger("switched-history",e)})},createNewHistory:function(g){var e=this,f=function(){return jQuery.post(galaxy_config.root+"api/histories",{current:true})};return this.loadHistory(undefined,g,f).then(function(i,h){e.trigger("new-history",e)})},loadHistoryWithHDADetails:function(h,g,f,j){var e=this,i=function(k){return e.getExpandedHdaIds(k.id)};return this.loadHistory(h,g,f,j,i)},loadHistory:function(h,g,f,k,i){this.trigger("loading-history",this);g=g||{};var e=this;var j=d.History.getHistoryData(h,{historyFn:f,hdaFn:k,hdaDetailIds:g.initiallyExpanded||i});return this._loadHistoryFromXHR(j,g).fail(function(n,l,m){e.trigger("error",e,n,g,_l("An error was encountered while "+l),{historyId:h,history:m||{}})}).always(function(){e.trigger("loading-done",e)})},_loadHistoryFromXHR:function(g,f){var e=this;g.then(function(h,i){e.setModel(h,i,f)});g.fail(function(i,h){e.render()});return g},setModel:function(g,e,f){f=f||{};if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.hdas)}this.hdaViews={};if(Galaxy&&Galaxy.currUser){g.user=Galaxy.currUser.toJSON()}this.model=new d.History(g,e,f);this._setUpWebStorage(f.initiallyExpanded,f.show_deleted,f.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this);this.render();return this},refreshHdas:function(f,e){if(this.model){return this.model.refresh(f,e)}return $.when()},_setUpWebStorage:function(f,e,g){this.storage=new PersistentStorage(this._getStorageKey(this.model.get("id")),{expandedHdas:{},show_deleted:false,show_hidden:false});this.log(this+" (prev) storage:",JSON.stringify(this.storage.get(),null,2));if(f){this.storage.set("exandedHdas",f)}if((e===true)||(e===false)){this.storage.set("show_deleted",e)}if((g===true)||(g===false)){this.storage.set("show_hidden",g)}this.show_deleted=this.storage.get("show_deleted");this.show_hidden=this.storage.get("show_hidden");this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get())},_getStorageKey:function(e){if(!e){throw new Error("_getStorageKey needs valid id: "+e)}return("history:"+e)},clearWebStorage:function(){for(var e in sessionStorage){if(e.indexOf("history:")===0){sessionStorage.removeItem(e)}}},getStoredOptions:function(f){if(!f||f==="current"){return(this.storage)?(this.storage.get()):({})}var e=sessionStorage.getItem(this._getStorageKey(f));return(e===null)?({}):(JSON.parse(e))},getExpandedHdaIds:function(e){var f=this.getStoredOptions(e).expandedHdas;return((_.isEmpty(f))?([]):(_.keys(f)))},_setUpModelEventHandlers:function(){this.model.on("error error:hdas",function(f,h,e,g){this.errorHandler(f,h,e,g)},this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);if(Galaxy&&Galaxy.quotaMeter){this.listenTo(this.model,"change:nice_size",function(){Galaxy.quotaMeter.update()})}this.model.hdas.on("add",this.addHdaView,this);this.model.hdas.on("change:deleted",this.handleHdaDeletionChange,this);this.model.hdas.on("change:visible",this.handleHdaVisibleChange,this);this.model.hdas.on("change:purged",function(e){this.model.fetch()},this);this.model.hdas.on("state:ready",function(f,g,e){if((!f.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(this.hdaViews[f.id])}},this)},addHdaView:function(h){this.log("add."+this,h);var f=this;if(!h.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return}$({}).queue([function g(j){var i=f.$el.find(f.emptyMsgSelector);if(i.is(":visible")){i.fadeOut(f.fxSpeed,j)}else{j()}},function e(j){f.scrollToTop();var i=f.$el.find(f.datasetsSelector);f.createHdaView(h).$el.hide().prependTo(i).slideDown(f.fxSpeed)}])},createHdaView:function(g){var f=g.get("id"),e=this.storage.get("expandedHdas").get(f),h=new this.HDAView({model:g,expanded:e,hasUser:this.model.hasUser(),logger:this.logger});this._setUpHdaListeners(h);this.hdaViews[f]=h;return h.render()},_setUpHdaListeners:function(f){var e=this;f.on("body-expanded",function(g){e.storage.get("expandedHdas").set(g,true)});f.on("body-collapsed",function(g){e.storage.get("expandedHdas").deleteKey(g)});f.on("error",function(h,j,g,i){e.errorHandler(h,j,g,i)})},handleHdaDeletionChange:function(e){if(e.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(this.hdaViews[e.id])}},handleHdaVisibleChange:function(e){if(e.hidden()&&!this.storage.get("show_hidden")){this.removeHdaView(this.hdaViews[e.id])}},removeHdaView:function(f){if(!f){return}var e=this;f.$el.fadeOut(e.fxSpeed,function(){f.off();f.remove();delete e.hdaViews[f.model.id];if(_.isEmpty(e.hdaViews)){e.$el.find(e.emptyMsgSelector).fadeIn(e.fxSpeed,function(){e.trigger("empty-history",e)})}})},render:function(g){var e=this,f;if(this.model){f=this.renderModel()}else{f=this.renderWithoutModel()}$(e).queue("fx",[function(h){if(e.$el.is(":visible")){e.$el.fadeOut(e.fxSpeed,h)}else{h()}},function(h){e.$el.empty();if(f){e.$el.append(f.children())}e.$el.fadeIn(e.fxSpeed,h)},function(h){if(g){g.call(this)}e.trigger("rendered",this)}]);return this},renderWithoutModel:function(){var e=$("<div/>"),f=$("<div/>").addClass("message-container").css({"margin-left":"4px","margin-right":"4px"});return e.append(f)},renderModel:function(){var e=$("<div/>");if(Galaxy.currUser.isAnonymous()){e.append(c.templates.anonHistoryPanel(this.model.toJSON()))}else{e.append(c.templates.historyPanel(this.model.toJSON()));e.find(".history-secondary-actions").append([this._render_tagButton(),this._render_annotateButton()])}this._setUpBehaviours(e);if(!this.model.hdas.length||!this.renderHdas(e.find(this.datasetsSelector))){e.find(this.emptyMsgSelector).show()}return e},_render_tagButton:function(){return faIconButton({title:_l("Edit history tags"),classes:"history-tag-button",faIcon:"fa-tags"})},_render_annotateButton:function(){return faIconButton({title:_l("Edit history tags"),classes:"history-annotate-button",faIcon:"fa-comment"})},_setUpBehaviours:function(e){e=e||this.$el;e.find("[title]").tooltip({placement:"bottom"});if(!this.model||!Galaxy.currUser||Galaxy.currUser.isAnonymous()){return}var f=this,g=e.find(".history-controls .annotation-display");e.find(".history-controls .history-annotate-button").click(function(){if(g.is(":hidden")){var h=f.$el.find(".history-controls .annotation");h.text(jQuery.trim(h.text()));g.slideDown(f.fxSpeed)}else{g.slideUp(f.fxSpeed)}return false});e.find(".history-name").make_text_editable({on_finish:function(h){e.find(".history-name").text(h);f.model.save({name:h}).fail(function(){e.find(".history-name").text(f.model.previous("name"))})}});e.find(".history-controls .annotation").make_text_editable({use_textarea:true,on_finish:function(h){e.find(".history-controls .annotation").text(h);f.model.save({annotation:h}).fail(function(){e.find(".history-controls .annotation").text(f.model.previous("annotation"))})}})},renderHdas:function(f){this.hdaViews={};var e=this,g=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"));_.each(g,function(h){f.prepend(e.createHdaView(h).$el)});return g.length},events:{"click .history-tag-button":"loadAndDisplayTags","click .message-container":"clearMessages"},updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(e){e.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},toggleShowDeleted:function(){this.storage.set("show_deleted",!this.storage.get("show_deleted"));this.render();return this.storage.get("show_deleted")},toggleShowHidden:function(){this.storage.set("show_hidden",!this.storage.get("show_hidden"));this.render();return this.storage.get("show_hidden")},loadAndDisplayTags:function(g){var e=this,f=this.$el.find(".history-controls .tags-display"),h=f.find(".tags");if(f.is(":hidden")){if(!jQuery.trim(h.html())){var i=jQuery.ajax(e.model.tagUrl());i.fail(function(l,j,k){e.log("Error loading tag area html",l,k,j);e.trigger("error",e,l,null,_l("Error loading tags"))});i.done(function(j){h.html(j);h.find("[title]").tooltip();f.slideDown(e.fxSpeed)})}else{f.slideDown(e.fxSpeed)}}else{f.slideUp(e.fxSpeed)}return false},showLoadingIndicator:function(f,e,g){e=(e!==undefined)?(e):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,g)}else{this.$el.fadeOut(e);this.indicator.show(f,e,g)}},hideLoadingIndicator:function(e,f){e=(e!==undefined)?(e):(this.fxSpeed);if(this.indicator){this.indicator.hide(e,f)}},displayMessage:function(j,k,i){var g=this;this.scrollToTop();var h=this.$el.find(this.msgsSelector),e=$("<div/>").addClass(j+"message").html(k);if(!_.isEmpty(i)){var f=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(g.messageToModalOptions(j,k,i));return false});e.append(" ",f)}return h.html(e)},messageToModalOptions:function(i,k,h){var e=this,j=$("<div/>"),g={title:"Details"};function f(l){l=_.omit(l,_.functions(l));return["<table>",_.map(l,function(n,m){n=(_.isObject(n))?(f(n)):(n);return'<tr><td style="vertical-align: top; color: grey">'+m+'</td><td style="padding-left: 8px">'+n+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(h)){g.body=j.append(f(h))}else{g.body=j.html(h)}g.buttons={Ok:function(){Galaxy.modal.hide();e.clearMessages()}};return g},clearMessages:function(){var e=this.$el.find(this.msgsSelector);e.empty()},scrollPosition:function(){return this.$el.parent().scrollTop()},scrollTo:function(e){this.$el.parent().scrollTop(e)},scrollToTop:function(){this.$el.parent().scrollTop(0);return this},scrollIntoView:function(f,g){if(!g){this.$el.parent().parent().scrollTop(f);return this}var e=window,h=this.$el.parent().parent(),j=$(e).innerHeight(),i=(j/2)-(g/2);$(h).scrollTop(f-i);return this},scrollToId:function(f){if((!f)||(!this.hdaViews[f])){return this}var e=this.hdaViews[f].$el;this.scrollIntoView(e.offset().top,e.outerHeight());return this},scrollToHid:function(e){var f=this.model.hdas.getByHid(e);if(!f){return this}return this.scrollToId(f.id)},connectToQuotaMeter:function(e){if(!e){return this}this.listenTo(e,"quota:over",this.showQuotaMessage);this.listenTo(e,"quota:under",this.hideQuotaMessage);this.on("rendered rendered:initial",function(){if(e&&e.isOverQuota()){this.showQuotaMessage()}});return this},showQuotaMessage:function(){var e=this.$el.find(".quota-message");if(e.is(":hidden")){e.slideDown(this.fxSpeed)}},hideQuotaMessage:function(){var e=this.$el.find(".quota-message");if(!e.is(":hidden")){e.slideUp(this.fxSpeed)}},connectToOptionsMenu:function(e){if(!e){return this}this.on("new-storage",function(g,f){if(e&&g){e.findItemByHtml(_l("Include Deleted Datasets")).checked=g.get("show_deleted");e.findItemByHtml(_l("Include Hidden Datasets")).checked=g.get("show_hidden")}});return this},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});c.templates={historyPanel:Handlebars.templates["template-history-historyPanel"],anonHistoryPanel:Handlebars.templates["template-history-historyPanel-anon"]};return{HistoryPanel:c}}); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/mvc/ui.js --- a/static/scripts/packed/mvc/ui.js +++ b/static/scripts/packed/mvc/ui.js @@ -1,1 +1,1 @@ -var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.attributes);a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(this.model.attributes.on_click){this.model.attributes.on_click(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b||$("<div/>");this.options=a||[];var c=this;this.$button.click(function(d){c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body");this.$el.css(this._getShownPosition(a));this._setUpCloseBehavior();this.$el.show()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+e+'"'):(""),b=(d.checked)?('<span class="fa-icon-ok"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var b=this;var a=function(c){c.one("click.close_popup",function(){b.remove()})};a($(window.document));a($(window.top.document));_.each(window.top.frames,function(c){a($(c.document))})},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(j){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}var i;switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;case"demo":if(i===undefined||i.closed){i=window.open(j,k);i.creator=self}break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a}; \ No newline at end of file +var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b||$("<div/>");this.options=a||[];var c=this;this.$button.click(function(d){c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body");this.$el.css(this._getShownPosition(a));this._setUpCloseBehavior();this.$el.show()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+e+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var b=this;var a=function(c){c.one("click.close_popup",function(){b.remove()})};a($(window.document));a($(window.top.document));_.each(window.top.frames,function(c){a($(c.document))})},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((a.target)?(' target="'+a.target+'"'):("")),' href="',((a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c}; \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/templates/compiled/history-templates.js --- a/static/scripts/packed/templates/compiled/history-templates.js +++ b/static/scripts/packed/templates/compiled/history-templates.js @@ -1,1 +1,1 @@ -(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-body"]=b(function(j,v,t,o,C){this.compilerInfo=[4,">= 1.0.0"];t=this.merge(t,j.helpers);C=C||{};var u="",l,e="function",d=this.escapeExpression,s=this,c=t.blockHelperMissing;function r(G,F){var D="",E;D+="\n ";if(E=t.body){E=E.call(G,{hash:{},data:F})}else{E=G.body;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+='\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';return D}function q(G,F){var D="",E;D+='\n <div class="dataset-summary">\n ';E=t["if"].call(G,G.misc_blurb,{hash:{},inverse:s.noop,fn:s.program(4,p,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.data_type,{hash:{},inverse:s.noop,fn:s.program(6,n,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.metadata_dbkey,{hash:{},inverse:s.noop,fn:s.program(9,i,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.misc_info,{hash:{},inverse:s.noop,fn:s.program(12,A,F),data:F});if(E||E===0){D+=E}D+='\n </div>\n\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';E=t.unless.call(G,G.deleted,{hash:{},inverse:s.noop,fn:s.program(14,z,F),data:F});if(E||E===0){D+=E}D+="\n\n ";return D}function p(G,F){var D="",E;D+='\n <div class="dataset-blurb">\n <span class="value">';if(E=t.misc_blurb){E=E.call(G,{hash:{},data:F})}else{E=G.misc_blurb;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function n(H,G){var D="",F,E;D+='\n <div class="dataset-datatype">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(7,m,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">';if(F=t.data_type){F=F.call(H,{hash:{},data:G})}else{F=H.data_type;F=typeof F===e?F.apply(H):F}D+=d(F)+"</span>\n </div>\n ";return D}function m(E,D){return"format"}function i(H,G){var D="",F,E;D+='\n <div class="dataset-dbkey">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(10,B,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">\n ';if(F=t.metadata_dbkey){F=F.call(H,{hash:{},data:G})}else{F=H.metadata_dbkey;F=typeof F===e?F.apply(H):F}D+=d(F)+"\n </span>\n </div>\n ";return D}function B(E,D){return"database"}function A(G,F){var D="",E;D+='\n <div class="dataset-info">\n <span class="value">';if(E=t.misc_info){E=E.call(G,{hash:{},data:F})}else{E=G.misc_info;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function z(H,G){var D="",F,E;D+='\n \n <div class="tags-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(15,y,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(17,x,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div id="dataset-';if(F=t.id){F=F.call(H,{hash:{},data:G})}else{F=H.id;F=typeof F===e?F.apply(H):F}D+=d(F)+'-annotation" class="annotation editable-text"\n title="';E={hash:{},inverse:s.noop,fn:s.program(19,w,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='"></div>\n </div>\n\n <div class="dataset-display-applications">\n ';F=t.each.call(H,H.display_apps,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+="\n\n ";F=t.each.call(H,H.display_types,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+='\n </div>\n\n <div class="dataset-peek">\n ';F=t["if"].call(H,H.peek,{hash:{},inverse:s.noop,fn:s.program(25,f,G),data:G});if(F||F===0){D+=F}D+="\n </div>\n\n ";return D}function y(E,D){return"Tags"}function x(E,D){return"Annotation"}function w(E,D){return"Edit dataset annotation"}function k(G,F){var D="",E;D+='\n <div class="display-application">\n <span class="display-application-location">';if(E=t.label){E=E.call(G,{hash:{},data:F})}else{E=G.label;E=typeof E===e?E.apply(G):E}D+=d(E)+'</span>\n <span class="display-application-links">\n ';E=t.each.call(G,G.links,{hash:{},inverse:s.noop,fn:s.program(22,h,F),data:F});if(E||E===0){D+=E}D+="\n </span>\n </div>\n ";return D}function h(H,G){var D="",F,E;D+='\n <a target="';if(F=t.target){F=F.call(H,{hash:{},data:G})}else{F=H.target;F=typeof F===e?F.apply(H):F}D+=d(F)+'" href="';if(F=t.href){F=F.call(H,{hash:{},data:G})}else{F=H.href;F=typeof F===e?F.apply(H):F}D+=d(F)+'">';E={hash:{},inverse:s.noop,fn:s.program(23,g,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+="</a>\n ";return D}function g(F,E){var D;if(D=t.text){D=D.call(F,{hash:{},data:E})}else{D=F.text;D=typeof D===e?D.apply(F):D}return d(D)}function f(G,F){var D="",E;D+='\n <pre class="peek">';if(E=t.peek){E=E.call(G,{hash:{},data:F})}else{E=G.peek;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+="</pre>\n ";return D}u+='<div class="dataset-body">\n ';l=t["if"].call(v,v.body,{hash:{},inverse:s.program(3,q,C),fn:s.program(1,r,C),data:C});if(l||l===0){u+=l}u+="\n</div>";return u})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-skeleton"]=b(function(f,r,p,k,w){this.compilerInfo=[4,">= 1.0.0"];p=this.merge(p,f.helpers);w=w||{};var q="",h,e="function",d=this.escapeExpression,o=this,c=p.blockHelperMissing;function n(B,A){var x="",z,y;x+='\n <div class="errormessagesmall">\n ';y={hash:{},inverse:o.noop,fn:o.program(2,m,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+=":\n ";y={hash:{},inverse:o.noop,fn:o.program(4,l,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </div>\n ";return x}function m(y,x){return"There was an error getting the data for this dataset"}function l(z,y){var x;if(x=p.error){x=x.call(z,{hash:{},data:y})}else{x=z.error;x=typeof x===e?x.apply(z):x}return d(x)}function j(A,z){var x="",y;x+="\n ";y=p["if"].call(A,A.purged,{hash:{},inverse:o.program(10,v,z),fn:o.program(7,i,z),data:z});if(y||y===0){x+=y}x+="\n ";return x}function i(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(8,g,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </strong></div>\n\n ";return x}function g(y,x){return"This dataset has been deleted and removed from disk."}function v(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(11,u,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n \n Click <a href="javascript:void(0);" class="dataset-undelete">here</a> to undelete it\n or <a href="javascript:void(0);" class="dataset-purge">here</a> to immediately remove it from disk\n </strong></div>\n ';return x}function u(y,x){return"This dataset has been deleted."}function t(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(14,s,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n Click <a href="javascript:void(0);" class="dataset-unhide">here</a> to unhide it\n </strong></div>\n ';return x}function s(y,x){return"This dataset has been hidden."}q+='<div class="dataset hda">\n <div class="dataset-warnings">\n ';h=p["if"].call(r,r.error,{hash:{},inverse:o.noop,fn:o.program(1,n,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p["if"].call(r,r.deleted,{hash:{},inverse:o.noop,fn:o.program(6,j,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p.unless.call(r,r.visible,{hash:{},inverse:o.noop,fn:o.program(13,t,w),data:w});if(h||h===0){q+=h}q+='\n </div>\n\n <div class="dataset-primary-actions"></div>\n\n <div class="dataset-title-bar">\n <span class="dataset-state-icon state-icon"></span>\n <div class="dataset-title">\n <span class="hda-hid">';if(h=p.hid){h=h.call(r,{hash:{},data:w})}else{h=r.hid;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n <span class="dataset-name">';if(h=p.name){h=h.call(r,{hash:{},data:w})}else{h=r.name;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n </div>\n </div>\n <div class="clear"></div>\n\n <div class="dataset-body"></div>\n</div>';return q})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel-anon"]=b(function(g,r,p,k,u){this.compilerInfo=[4,">= 1.0.0"];p=this.merge(p,g.helpers);u=u||{};var q="",i,f,o=this,e="function",c=p.blockHelperMissing,d=this.escapeExpression;function n(z,y){var v="",x,w;v+='\n <div class="history-name" title="';w={hash:{},inverse:o.noop,fn:o.program(2,m,y),data:y};if(x=p.local){x=x.call(z,w)}else{x=z.local;x=typeof x===e?x.apply(z):x}if(!p.local){x=c.call(z,x,w)}if(x||x===0){v+=x}v+='">\n ';if(x=p.name){x=x.call(z,{hash:{},data:y})}else{x=z.name;x=typeof x===e?x.apply(z):x}v+=d(x)+"\n </div>\n ";return v}function m(w,v){return"You must be logged in to edit your history name"}function l(y,x){var v="",w;v+='\n <div class="history-size">';if(w=p.nice_size){w=w.call(y,{hash:{},data:x})}else{w=y.nice_size;w=typeof w===e?w.apply(y):w}v+=d(w)+"</div>\n ";return v}function j(y,x){var v="",w;v+='\n \n <div class="';if(w=p.status){w=w.call(y,{hash:{},data:x})}else{w=y.status;w=typeof w===e?w.apply(y):w}v+=d(w)+'message">';if(w=p.message){w=w.call(y,{hash:{},data:x})}else{w=y.message;w=typeof w===e?w.apply(y):w}v+=d(w)+"</div>\n ";return v}function h(w,v){return"You are over your disk quota"}function t(w,v){return"Tool execution is on hold until your disk usage drops below your allocated quota"}function s(w,v){return"Your history is empty. Click 'Get Data' on the left pane to start"}q+='<div class="history-controls">\n\n <div class="history-title">\n \n ';i=p["if"].call(r,r.name,{hash:{},inverse:o.noop,fn:o.program(1,n,u),data:u});if(i||i===0){q+=i}q+='\n </div>\n\n <div class="history-subtitle clear">\n ';i=p["if"].call(r,r.nice_size,{hash:{},inverse:o.noop,fn:o.program(4,l,u),data:u});if(i||i===0){q+=i}q+='\n </div>\n\n <div class="message-container">\n ';i=p["if"].call(r,r.message,{hash:{},inverse:o.noop,fn:o.program(6,j,u),data:u});if(i||i===0){q+=i}q+='\n </div>\n\n <div class="quota-message errormessage">\n ';f={hash:{},inverse:o.noop,fn:o.program(8,h,u),data:u};if(i=p.local){i=i.call(r,f)}else{i=r.local;i=typeof i===e?i.apply(r):i}if(!p.local){i=c.call(r,i,f)}if(i||i===0){q+=i}q+=".\n ";f={hash:{},inverse:o.noop,fn:o.program(10,t,u),data:u};if(i=p.local){i=i.call(r,f)}else{i=r.local;i=typeof i===e?i.apply(r):i}if(!p.local){i=c.call(r,i,f)}if(i||i===0){q+=i}q+='.\n </div>\n\n </div>\n\n \n <div class="datasets-list"></div>\n\n <div class="empty-history-message infomessagesmall">\n ';f={hash:{},inverse:o.noop,fn:o.program(12,s,u),data:u};if(i=p.local){i=i.call(r,f)}else{i=r.local;i=typeof i===e?i.apply(r):i}if(!p.local){i=c.call(r,i,f)}if(i||i===0){q+=i}q+="\n </div>";return q})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel"]=b(function(k,x,v,p,E){this.compilerInfo=[4,">= 1.0.0"];v=this.merge(v,k.helpers);E=E||{};var w="",n,h,t=this,e="function",c=v.blockHelperMissing,d=this.escapeExpression;function s(J,I){var F="",H,G;F+='\n <div class="history-name editable-text" title="';G={hash:{},inverse:t.noop,fn:t.program(2,r,I),data:I};if(H=v.local){H=H.call(J,G)}else{H=J.local;H=typeof H===e?H.apply(J):H}if(!v.local){H=c.call(J,H,G)}if(H||H===0){F+=H}F+='">\n ';if(H=v.name){H=H.call(J,{hash:{},data:I})}else{H=J.name;H=typeof H===e?H.apply(J):H}F+=d(H)+"\n </div>\n ";return F}function r(G,F){return"Click to rename history"}function q(I,H){var F="",G;F+='\n <div class="history-size">';if(G=v.nice_size){G=G.call(I,{hash:{},data:H})}else{G=I.nice_size;G=typeof G===e?G.apply(I):G}F+=d(G)+"</div>\n ";return F}function o(G,F){return"Edit history tags"}function m(G,F){return"Edit history annotation"}function D(J,I){var F="",H,G;F+='\n <div class="warningmessagesmall"><strong>\n ';G={hash:{},inverse:t.noop,fn:t.program(11,C,I),data:I};if(H=v.local){H=H.call(J,G)}else{H=J.local;H=typeof H===e?H.apply(J):H}if(!v.local){H=c.call(J,H,G)}if(H||H===0){F+=H}F+="\n </strong></div>\n ";return F}function C(G,F){return"You are currently viewing a deleted history!"}function B(I,H){var F="",G;F+='\n \n <div class="';if(G=v.status){G=G.call(I,{hash:{},data:H})}else{G=I.status;G=typeof G===e?G.apply(I):G}F+=d(G)+'message">';if(G=v.message){G=G.call(I,{hash:{},data:H})}else{G=I.message;G=typeof G===e?G.apply(I):G}F+=d(G)+"</div>\n ";return F}function A(G,F){return"You are over your disk quota"}function z(G,F){return"Tool execution is on hold until your disk usage drops below your allocated quota"}function y(G,F){return"Tags"}function l(G,F){return"Annotation"}function j(G,F){return"Click to edit annotation"}function i(I,H){var F="",G;F+="\n ";if(G=v.annotation){G=G.call(I,{hash:{},data:H})}else{G=I.annotation;G=typeof G===e?G.apply(I):G}F+=d(G)+"\n ";return F}function g(J,I){var F="",H,G;F+="\n <em>";G={hash:{},inverse:t.noop,fn:t.program(28,f,I),data:I};if(H=v.local){H=H.call(J,G)}else{H=J.local;H=typeof H===e?H.apply(J):H}if(!v.local){H=c.call(J,H,G)}if(H||H===0){F+=H}F+="</em>\n ";return F}function f(G,F){return"Describe or add notes to history"}function u(G,F){return"Your history is empty. Click 'Get Data' on the left pane to start"}w+='<div class="history-controls">\n\n <div class="history-title">\n ';n=v["if"].call(x,x.name,{hash:{},inverse:t.noop,fn:t.program(1,s,E),data:E});if(n||n===0){w+=n}w+='\n </div>\n\n <div class="history-subtitle clear">\n ';n=v["if"].call(x,x.nice_size,{hash:{},inverse:t.noop,fn:t.program(4,q,E),data:E});if(n||n===0){w+=n}w+='\n\n <div class="history-secondary-actions">\n <a title="';h={hash:{},inverse:t.noop,fn:t.program(6,o,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='"\n class="icon-button tags" href="javascript:void(0)"></a>\n <a title="';h={hash:{},inverse:t.noop,fn:t.program(8,m,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='"\n class="icon-button annotate" href="javascript:void(0)"></a>\n </div>\n </div>\n\n ';n=v["if"].call(x,x.deleted,{hash:{},inverse:t.noop,fn:t.program(10,D,E),data:E});if(n||n===0){w+=n}w+='\n\n <div class="message-container">\n ';n=v["if"].call(x,x.message,{hash:{},inverse:t.noop,fn:t.program(13,B,E),data:E});if(n||n===0){w+=n}w+='\n </div>\n\n <div class="quota-message errormessage">\n ';h={hash:{},inverse:t.noop,fn:t.program(15,A,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+=".\n ";h={hash:{},inverse:t.noop,fn:t.program(17,z,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='.\n </div>\n \n \n \n <div class="tags-display">\n <label class="prompt">';h={hash:{},inverse:t.noop,fn:t.program(19,y,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';h={hash:{},inverse:t.noop,fn:t.program(21,l,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='</label>\n <div class="annotation editable-text" title="';h={hash:{},inverse:t.noop,fn:t.program(23,j,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='">\n ';n=v["if"].call(x,x.annotation,{hash:{},inverse:t.program(27,g,E),fn:t.program(25,i,E),data:E});if(n||n===0){w+=n}w+='\n </div>\n </div>\n\n </div>\n\n \n <div class="datasets-list"></div>\n\n <div class="empty-history-message infomessagesmall">\n ';h={hash:{},inverse:t.noop,fn:t.program(30,u,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+="\n </div>";return w})})(); \ No newline at end of file +(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-body"]=b(function(j,v,t,o,C){this.compilerInfo=[4,">= 1.0.0"];t=this.merge(t,j.helpers);C=C||{};var u="",l,e="function",d=this.escapeExpression,s=this,c=t.blockHelperMissing;function r(G,F){var D="",E;D+='\n <div class="dataset-summary">\n ';if(E=t.body){E=E.call(G,{hash:{},data:F})}else{E=G.body;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+='\n </div>\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';return D}function q(G,F){var D="",E;D+='\n <div class="dataset-summary">\n ';E=t["if"].call(G,G.misc_blurb,{hash:{},inverse:s.noop,fn:s.program(4,p,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.data_type,{hash:{},inverse:s.noop,fn:s.program(6,n,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.metadata_dbkey,{hash:{},inverse:s.noop,fn:s.program(9,i,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.misc_info,{hash:{},inverse:s.noop,fn:s.program(12,A,F),data:F});if(E||E===0){D+=E}D+='\n </div>\n\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';E=t.unless.call(G,G.deleted,{hash:{},inverse:s.noop,fn:s.program(14,z,F),data:F});if(E||E===0){D+=E}D+="\n\n ";return D}function p(G,F){var D="",E;D+='\n <div class="dataset-blurb">\n <span class="value">';if(E=t.misc_blurb){E=E.call(G,{hash:{},data:F})}else{E=G.misc_blurb;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function n(H,G){var D="",F,E;D+='\n <div class="dataset-datatype">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(7,m,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">';if(F=t.data_type){F=F.call(H,{hash:{},data:G})}else{F=H.data_type;F=typeof F===e?F.apply(H):F}D+=d(F)+"</span>\n </div>\n ";return D}function m(E,D){return"format"}function i(H,G){var D="",F,E;D+='\n <div class="dataset-dbkey">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(10,B,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">\n ';if(F=t.metadata_dbkey){F=F.call(H,{hash:{},data:G})}else{F=H.metadata_dbkey;F=typeof F===e?F.apply(H):F}D+=d(F)+"\n </span>\n </div>\n ";return D}function B(E,D){return"database"}function A(G,F){var D="",E;D+='\n <div class="dataset-info">\n <span class="value">';if(E=t.misc_info){E=E.call(G,{hash:{},data:F})}else{E=G.misc_info;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function z(H,G){var D="",F,E;D+='\n \n <div class="tags-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(15,y,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(17,x,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div id="dataset-';if(F=t.id){F=F.call(H,{hash:{},data:G})}else{F=H.id;F=typeof F===e?F.apply(H):F}D+=d(F)+'-annotation" class="annotation editable-text"\n title="';E={hash:{},inverse:s.noop,fn:s.program(19,w,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='"></div>\n </div>\n\n <div class="dataset-display-applications">\n ';F=t.each.call(H,H.display_apps,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+="\n\n ";F=t.each.call(H,H.display_types,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+='\n </div>\n\n <div class="dataset-peek">\n ';F=t["if"].call(H,H.peek,{hash:{},inverse:s.noop,fn:s.program(25,f,G),data:G});if(F||F===0){D+=F}D+="\n </div>\n\n ";return D}function y(E,D){return"Tags"}function x(E,D){return"Annotation"}function w(E,D){return"Edit dataset annotation"}function k(G,F){var D="",E;D+='\n <div class="display-application">\n <span class="display-application-location">';if(E=t.label){E=E.call(G,{hash:{},data:F})}else{E=G.label;E=typeof E===e?E.apply(G):E}D+=d(E)+'</span>\n <span class="display-application-links">\n ';E=t.each.call(G,G.links,{hash:{},inverse:s.noop,fn:s.program(22,h,F),data:F});if(E||E===0){D+=E}D+="\n </span>\n </div>\n ";return D}function h(H,G){var D="",F,E;D+='\n <a target="';if(F=t.target){F=F.call(H,{hash:{},data:G})}else{F=H.target;F=typeof F===e?F.apply(H):F}D+=d(F)+'" href="';if(F=t.href){F=F.call(H,{hash:{},data:G})}else{F=H.href;F=typeof F===e?F.apply(H):F}D+=d(F)+'">';E={hash:{},inverse:s.noop,fn:s.program(23,g,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+="</a>\n ";return D}function g(F,E){var D;if(D=t.text){D=D.call(F,{hash:{},data:E})}else{D=F.text;D=typeof D===e?D.apply(F):D}return d(D)}function f(G,F){var D="",E;D+='\n <pre class="peek">';if(E=t.peek){E=E.call(G,{hash:{},data:F})}else{E=G.peek;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+="</pre>\n ";return D}u+='<div class="dataset-body">\n ';l=t["if"].call(v,v.body,{hash:{},inverse:s.program(3,q,C),fn:s.program(1,r,C),data:C});if(l||l===0){u+=l}u+="\n</div>";return u})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-body"]=b(function(j,v,t,o,C){this.compilerInfo=[4,">= 1.0.0"];t=this.merge(t,j.helpers);C=C||{};var u="",l,e="function",d=this.escapeExpression,s=this,c=t.blockHelperMissing;function r(G,F){var D="",E;D+='\n <div class="dataset-summary">\n ';if(E=t.body){E=E.call(G,{hash:{},data:F})}else{E=G.body;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+='\n </div>\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';return D}function q(G,F){var D="",E;D+='\n <div class="dataset-summary">\n ';E=t["if"].call(G,G.misc_blurb,{hash:{},inverse:s.noop,fn:s.program(4,p,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.data_type,{hash:{},inverse:s.noop,fn:s.program(6,n,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.metadata_dbkey,{hash:{},inverse:s.noop,fn:s.program(9,i,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.misc_info,{hash:{},inverse:s.noop,fn:s.program(12,A,F),data:F});if(E||E===0){D+=E}D+='\n </div>\n\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';E=t.unless.call(G,G.deleted,{hash:{},inverse:s.noop,fn:s.program(14,z,F),data:F});if(E||E===0){D+=E}D+="\n\n ";return D}function p(G,F){var D="",E;D+='\n <div class="dataset-blurb">\n <span class="value">';if(E=t.misc_blurb){E=E.call(G,{hash:{},data:F})}else{E=G.misc_blurb;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function n(H,G){var D="",F,E;D+='\n <div class="dataset-datatype">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(7,m,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">';if(F=t.data_type){F=F.call(H,{hash:{},data:G})}else{F=H.data_type;F=typeof F===e?F.apply(H):F}D+=d(F)+"</span>\n </div>\n ";return D}function m(E,D){return"format"}function i(H,G){var D="",F,E;D+='\n <div class="dataset-dbkey">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(10,B,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">\n ';if(F=t.metadata_dbkey){F=F.call(H,{hash:{},data:G})}else{F=H.metadata_dbkey;F=typeof F===e?F.apply(H):F}D+=d(F)+"\n </span>\n </div>\n ";return D}function B(E,D){return"database"}function A(G,F){var D="",E;D+='\n <div class="dataset-info">\n <span class="value">';if(E=t.misc_info){E=E.call(G,{hash:{},data:F})}else{E=G.misc_info;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function z(H,G){var D="",F,E;D+='\n \n <div class="tags-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(15,y,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(17,x,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div id="dataset-';if(F=t.id){F=F.call(H,{hash:{},data:G})}else{F=H.id;F=typeof F===e?F.apply(H):F}D+=d(F)+'-annotation" class="annotation editable-text"\n title="';E={hash:{},inverse:s.noop,fn:s.program(19,w,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='"></div>\n </div>\n\n <div class="dataset-display-applications">\n ';F=t.each.call(H,H.display_apps,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+="\n\n ";F=t.each.call(H,H.display_types,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+='\n </div>\n\n <div class="dataset-peek">\n ';F=t["if"].call(H,H.peek,{hash:{},inverse:s.noop,fn:s.program(25,f,G),data:G});if(F||F===0){D+=F}D+="\n </div>\n\n ";return D}function y(E,D){return"Tags"}function x(E,D){return"Annotation"}function w(E,D){return"Edit dataset annotation"}function k(G,F){var D="",E;D+='\n <div class="display-application">\n <span class="display-application-location">';if(E=t.label){E=E.call(G,{hash:{},data:F})}else{E=G.label;E=typeof E===e?E.apply(G):E}D+=d(E)+'</span>\n <span class="display-application-links">\n ';E=t.each.call(G,G.links,{hash:{},inverse:s.noop,fn:s.program(22,h,F),data:F});if(E||E===0){D+=E}D+="\n </span>\n </div>\n ";return D}function h(H,G){var D="",F,E;D+='\n <a target="';if(F=t.target){F=F.call(H,{hash:{},data:G})}else{F=H.target;F=typeof F===e?F.apply(H):F}D+=d(F)+'" href="';if(F=t.href){F=F.call(H,{hash:{},data:G})}else{F=H.href;F=typeof F===e?F.apply(H):F}D+=d(F)+'">';E={hash:{},inverse:s.noop,fn:s.program(23,g,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+="</a>\n ";return D}function g(F,E){var D;if(D=t.text){D=D.call(F,{hash:{},data:E})}else{D=F.text;D=typeof D===e?D.apply(F):D}return d(D)}function f(G,F){var D="",E;D+='\n <pre class="peek">';if(E=t.peek){E=E.call(G,{hash:{},data:F})}else{E=G.peek;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+="</pre>\n ";return D}u+='<div class="dataset-body">\n ';l=t["if"].call(v,v.body,{hash:{},inverse:s.program(3,q,C),fn:s.program(1,r,C),data:C});if(l||l===0){u+=l}u+="\n</div>";return u})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-skeleton"]=b(function(f,r,p,k,w){this.compilerInfo=[4,">= 1.0.0"];p=this.merge(p,f.helpers);w=w||{};var q="",h,e="function",d=this.escapeExpression,o=this,c=p.blockHelperMissing;function n(B,A){var x="",z,y;x+='\n <div class="errormessagesmall">\n ';y={hash:{},inverse:o.noop,fn:o.program(2,m,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+=":\n ";y={hash:{},inverse:o.noop,fn:o.program(4,l,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </div>\n ";return x}function m(y,x){return"There was an error getting the data for this dataset"}function l(z,y){var x;if(x=p.error){x=x.call(z,{hash:{},data:y})}else{x=z.error;x=typeof x===e?x.apply(z):x}return d(x)}function j(A,z){var x="",y;x+="\n ";y=p["if"].call(A,A.purged,{hash:{},inverse:o.program(10,v,z),fn:o.program(7,i,z),data:z});if(y||y===0){x+=y}x+="\n ";return x}function i(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(8,g,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </strong></div>\n\n ";return x}function g(y,x){return"This dataset has been deleted and removed from disk."}function v(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(11,u,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n \n Click <a href="javascript:void(0);" class="dataset-undelete">here</a> to undelete it\n or <a href="javascript:void(0);" class="dataset-purge">here</a> to immediately remove it from disk\n </strong></div>\n ';return x}function u(y,x){return"This dataset has been deleted."}function t(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(14,s,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n Click <a href="javascript:void(0);" class="dataset-unhide">here</a> to unhide it\n </strong></div>\n ';return x}function s(y,x){return"This dataset has been hidden."}q+='<div class="dataset hda">\n <div class="dataset-warnings">\n ';h=p["if"].call(r,r.error,{hash:{},inverse:o.noop,fn:o.program(1,n,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p["if"].call(r,r.deleted,{hash:{},inverse:o.noop,fn:o.program(6,j,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p.unless.call(r,r.visible,{hash:{},inverse:o.noop,fn:o.program(13,t,w),data:w});if(h||h===0){q+=h}q+='\n </div>\n\n <div class="dataset-primary-actions"></div>\n <div class="dataset-title-bar clear">\n <span class="dataset-state-icon state-icon"></span>\n <div class="dataset-title">\n <span class="hda-hid">';if(h=p.hid){h=h.call(r,{hash:{},data:w})}else{h=r.hid;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n <span class="dataset-name">';if(h=p.name){h=h.call(r,{hash:{},data:w})}else{h=r.name;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n </div>\n </div>\n\n <div class="dataset-body"></div>\n</div>';return q})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-skeleton"]=b(function(f,r,p,k,w){this.compilerInfo=[4,">= 1.0.0"];p=this.merge(p,f.helpers);w=w||{};var q="",h,e="function",d=this.escapeExpression,o=this,c=p.blockHelperMissing;function n(B,A){var x="",z,y;x+='\n <div class="errormessagesmall">\n ';y={hash:{},inverse:o.noop,fn:o.program(2,m,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+=":\n ";y={hash:{},inverse:o.noop,fn:o.program(4,l,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </div>\n ";return x}function m(y,x){return"There was an error getting the data for this dataset"}function l(z,y){var x;if(x=p.error){x=x.call(z,{hash:{},data:y})}else{x=z.error;x=typeof x===e?x.apply(z):x}return d(x)}function j(A,z){var x="",y;x+="\n ";y=p["if"].call(A,A.purged,{hash:{},inverse:o.program(10,v,z),fn:o.program(7,i,z),data:z});if(y||y===0){x+=y}x+="\n ";return x}function i(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(8,g,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </strong></div>\n\n ";return x}function g(y,x){return"This dataset has been deleted and removed from disk."}function v(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(11,u,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n \n Click <a href="javascript:void(0);" class="dataset-undelete">here</a> to undelete it\n or <a href="javascript:void(0);" class="dataset-purge">here</a> to immediately remove it from disk\n </strong></div>\n ';return x}function u(y,x){return"This dataset has been deleted."}function t(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(14,s,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n Click <a href="javascript:void(0);" class="dataset-unhide">here</a> to unhide it\n </strong></div>\n ';return x}function s(y,x){return"This dataset has been hidden."}q+='<div class="dataset hda">\n <div class="dataset-warnings">\n ';h=p["if"].call(r,r.error,{hash:{},inverse:o.noop,fn:o.program(1,n,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p["if"].call(r,r.deleted,{hash:{},inverse:o.noop,fn:o.program(6,j,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p.unless.call(r,r.visible,{hash:{},inverse:o.noop,fn:o.program(13,t,w),data:w});if(h||h===0){q+=h}q+='\n </div>\n\n <div class="dataset-primary-actions"></div>\n <div class="dataset-title-bar clear">\n <span class="dataset-state-icon state-icon"></span>\n <div class="dataset-title">\n <span class="hda-hid">';if(h=p.hid){h=h.call(r,{hash:{},data:w})}else{h=r.hid;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n <span class="dataset-name">';if(h=p.name){h=h.call(r,{hash:{},data:w})}else{h=r.name;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n </div>\n </div>\n\n <div class="dataset-body"></div>\n</div>';return q})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel-anon"]=b(function(g,r,p,k,u){this.compilerInfo=[4,">= 1.0.0"];p=this.merge(p,g.helpers);u=u||{};var q="",i,f,o=this,e="function",c=p.blockHelperMissing,d=this.escapeExpression;function n(z,y){var v="",x,w;v+='\n <div class="history-name" title="';w={hash:{},inverse:o.noop,fn:o.program(2,m,y),data:y};if(x=p.local){x=x.call(z,w)}else{x=z.local;x=typeof x===e?x.apply(z):x}if(!p.local){x=c.call(z,x,w)}if(x||x===0){v+=x}v+='">\n ';if(x=p.name){x=x.call(z,{hash:{},data:y})}else{x=z.name;x=typeof x===e?x.apply(z):x}v+=d(x)+"\n </div>\n ";return v}function m(w,v){return"You must be logged in to edit your history name"}function l(y,x){var v="",w;v+='\n <div class="history-size">';if(w=p.nice_size){w=w.call(y,{hash:{},data:x})}else{w=y.nice_size;w=typeof w===e?w.apply(y):w}v+=d(w)+"</div>\n ";return v}function j(y,x){var v="",w;v+='\n \n <div class="';if(w=p.status){w=w.call(y,{hash:{},data:x})}else{w=y.status;w=typeof w===e?w.apply(y):w}v+=d(w)+'message">';if(w=p.message){w=w.call(y,{hash:{},data:x})}else{w=y.message;w=typeof w===e?w.apply(y):w}v+=d(w)+"</div>\n ";return v}function h(w,v){return"You are over your disk quota"}function t(w,v){return"Tool execution is on hold until your disk usage drops below your allocated quota"}function s(w,v){return"Your history is empty. Click 'Get Data' on the left pane to start"}q+='<div class="history-controls">\n\n <div class="history-title">\n \n ';i=p["if"].call(r,r.name,{hash:{},inverse:o.noop,fn:o.program(1,n,u),data:u});if(i||i===0){q+=i}q+='\n </div>\n\n <div class="history-subtitle clear">\n ';i=p["if"].call(r,r.nice_size,{hash:{},inverse:o.noop,fn:o.program(4,l,u),data:u});if(i||i===0){q+=i}q+='\n </div>\n\n <div class="message-container">\n ';i=p["if"].call(r,r.message,{hash:{},inverse:o.noop,fn:o.program(6,j,u),data:u});if(i||i===0){q+=i}q+='\n </div>\n\n <div class="quota-message errormessage">\n ';f={hash:{},inverse:o.noop,fn:o.program(8,h,u),data:u};if(i=p.local){i=i.call(r,f)}else{i=r.local;i=typeof i===e?i.apply(r):i}if(!p.local){i=c.call(r,i,f)}if(i||i===0){q+=i}q+=".\n ";f={hash:{},inverse:o.noop,fn:o.program(10,t,u),data:u};if(i=p.local){i=i.call(r,f)}else{i=r.local;i=typeof i===e?i.apply(r):i}if(!p.local){i=c.call(r,i,f)}if(i||i===0){q+=i}q+='.\n </div>\n\n </div>\n\n \n <div class="datasets-list"></div>\n\n <div class="empty-history-message infomessagesmall">\n ';f={hash:{},inverse:o.noop,fn:o.program(12,s,u),data:u};if(i=p.local){i=i.call(r,f)}else{i=r.local;i=typeof i===e?i.apply(r):i}if(!p.local){i=c.call(r,i,f)}if(i||i===0){q+=i}q+="\n </div>";return q})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel"]=b(function(i,u,s,n,A){this.compilerInfo=[4,">= 1.0.0"];s=this.merge(s,i.helpers);A=A||{};var t="",k,f,r=this,e="function",c=s.blockHelperMissing,d=this.escapeExpression;function q(F,E){var B="",D,C;B+='\n <div class="history-name" title="';C={hash:{},inverse:r.noop,fn:r.program(2,p,E),data:E};if(D=s.local){D=D.call(F,C)}else{D=F.local;D=typeof D===e?D.apply(F):D}if(!s.local){D=c.call(F,D,C)}if(D||D===0){B+=D}B+='">\n ';if(D=s.name){D=D.call(F,{hash:{},data:E})}else{D=F.name;D=typeof D===e?D.apply(F):D}B+=d(D)+"\n </div>\n ";return B}function p(C,B){return"Click to rename history"}function o(E,D){var B="",C;B+='\n <div class="history-size">';if(C=s.nice_size){C=C.call(E,{hash:{},data:D})}else{C=E.nice_size;C=typeof C===e?C.apply(E):C}B+=d(C)+"</div>\n ";return B}function m(F,E){var B="",D,C;B+='\n <div class="warningmessagesmall"><strong>\n ';C={hash:{},inverse:r.noop,fn:r.program(7,l,E),data:E};if(D=s.local){D=D.call(F,C)}else{D=F.local;D=typeof D===e?D.apply(F):D}if(!s.local){D=c.call(F,D,C)}if(D||D===0){B+=D}B+="\n </strong></div>\n ";return B}function l(C,B){return"You are currently viewing a deleted history!"}function h(E,D){var B="",C;B+='\n \n <div class="';if(C=s.status){C=C.call(E,{hash:{},data:D})}else{C=E.status;C=typeof C===e?C.apply(E):C}B+=d(C)+'message">';if(C=s.message){C=C.call(E,{hash:{},data:D})}else{C=E.message;C=typeof C===e?C.apply(E):C}B+=d(C)+"</div>\n ";return B}function z(C,B){return"You are over your disk quota"}function y(C,B){return"Tool execution is on hold until your disk usage drops below your allocated quota"}function x(C,B){return"Tags"}function w(C,B){return"Annotation"}function v(C,B){return"Click to edit annotation"}function j(D,C){var B;if(B=s.annotation){B=B.call(D,{hash:{},data:C})}else{B=D.annotation;B=typeof B===e?B.apply(D):B}return d(B)}function g(C,B){return"Your history is empty. Click 'Get Data' on the left pane to start"}t+='<div class="history-controls">\n\n <div class="history-title">\n ';k=s["if"].call(u,u.name,{hash:{},inverse:r.noop,fn:r.program(1,q,A),data:A});if(k||k===0){t+=k}t+='\n </div>\n\n <div class="history-subtitle clear">\n ';k=s["if"].call(u,u.nice_size,{hash:{},inverse:r.noop,fn:r.program(4,o,A),data:A});if(k||k===0){t+=k}t+='\n\n <div class="history-secondary-actions">\n </div>\n </div>\n\n ';k=s["if"].call(u,u.deleted,{hash:{},inverse:r.noop,fn:r.program(6,m,A),data:A});if(k||k===0){t+=k}t+='\n\n <div class="message-container">\n ';k=s["if"].call(u,u.message,{hash:{},inverse:r.noop,fn:r.program(9,h,A),data:A});if(k||k===0){t+=k}t+='\n </div>\n\n <div class="quota-message errormessage">\n ';f={hash:{},inverse:r.noop,fn:r.program(11,z,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+=".\n ";f={hash:{},inverse:r.noop,fn:r.program(13,y,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+='.\n </div>\n \n \n \n <div class="tags-display">\n <label class="prompt">';f={hash:{},inverse:r.noop,fn:r.program(15,x,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';f={hash:{},inverse:r.noop,fn:r.program(17,w,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+='</label>\n <div class="annotation" title="';f={hash:{},inverse:r.noop,fn:r.program(19,v,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+='"\n \n >';k=s["if"].call(u,u.annotation,{hash:{},inverse:r.noop,fn:r.program(21,j,A),data:A});if(k||k===0){t+=k}t+='</div>\n </div>\n\n </div>\n\n \n <div class="datasets-list"></div>\n\n <div class="empty-history-message infomessagesmall">\n ';f={hash:{},inverse:r.noop,fn:r.program(23,g,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+="\n </div>";return t})})();(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel"]=b(function(k,w,u,p,C){this.compilerInfo=[4,">= 1.0.0"];u=this.merge(u,k.helpers);C=C||{};var v="",m,g,t=this,e="function",c=u.blockHelperMissing,d=this.escapeExpression;function s(H,G){var D="",F,E;D+='\n <div class="history-name" title="';E={hash:{},inverse:t.noop,fn:t.program(2,r,G),data:G};if(F=u.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!u.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='">\n ';if(F=u.name){F=F.call(H,{hash:{},data:G})}else{F=H.name;F=typeof F===e?F.apply(H):F}D+=d(F)+"\n </div>\n ";return D}function r(E,D){return"Click to rename history"}function q(G,F){var D="",E;D+='\n <div class="history-size">';if(E=u.nice_size){E=E.call(G,{hash:{},data:F})}else{E=G.nice_size;E=typeof E===e?E.apply(G):E}D+=d(E)+"</div>\n ";return D}function o(H,G){var D="",F,E;D+='\n <div class="warningmessagesmall"><strong>\n ';E={hash:{},inverse:t.noop,fn:t.program(7,n,G),data:G};if(F=u.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!u.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+="\n </strong></div>\n ";return D}function n(E,D){return"You are currently viewing a deleted history!"}function j(G,F){var D="",E;D+='\n \n <div class="';if(E=u.status){E=E.call(G,{hash:{},data:F})}else{E=G.status;E=typeof E===e?E.apply(G):E}D+=d(E)+'message">';if(E=u.message){E=E.call(G,{hash:{},data:F})}else{E=G.message;E=typeof E===e?E.apply(G):E}D+=d(E)+"</div>\n ";return D}function B(E,D){return"You are over your disk quota"}function A(E,D){return"Tool execution is on hold until your disk usage drops below your allocated quota"}function z(E,D){return"Tags"}function y(E,D){return"Annotation"}function x(E,D){return"Click to edit annotation"}function l(G,F){var D="",E;D+="\n ";if(E=u.annotation){E=E.call(G,{hash:{},data:F})}else{E=G.annotation;E=typeof E===e?E.apply(G):E}D+=d(E)+"\n ";return D}function i(H,G){var D="",F,E;D+="\n <em>";E={hash:{},inverse:t.noop,fn:t.program(24,h,G),data:G};if(F=u.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!u.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+="</em>\n ";return D}function h(E,D){return"Describe or add notes to history"}function f(E,D){return"Your history is empty. Click 'Get Data' on the left pane to start"}v+='<div class="history-controls">\n\n <div class="history-title">\n ';m=u["if"].call(w,w.name,{hash:{},inverse:t.noop,fn:t.program(1,s,C),data:C});if(m||m===0){v+=m}v+='\n </div>\n\n <div class="history-subtitle clear">\n ';m=u["if"].call(w,w.nice_size,{hash:{},inverse:t.noop,fn:t.program(4,q,C),data:C});if(m||m===0){v+=m}v+='\n\n <div class="history-secondary-actions">\n </div>\n </div>\n\n ';m=u["if"].call(w,w.deleted,{hash:{},inverse:t.noop,fn:t.program(6,o,C),data:C});if(m||m===0){v+=m}v+='\n\n <div class="message-container">\n ';m=u["if"].call(w,w.message,{hash:{},inverse:t.noop,fn:t.program(9,j,C),data:C});if(m||m===0){v+=m}v+='\n </div>\n\n <div class="quota-message errormessage">\n ';g={hash:{},inverse:t.noop,fn:t.program(11,B,C),data:C};if(m=u.local){m=m.call(w,g)}else{m=w.local;m=typeof m===e?m.apply(w):m}if(!u.local){m=c.call(w,m,g)}if(m||m===0){v+=m}v+=".\n ";g={hash:{},inverse:t.noop,fn:t.program(13,A,C),data:C};if(m=u.local){m=m.call(w,g)}else{m=w.local;m=typeof m===e?m.apply(w):m}if(!u.local){m=c.call(w,m,g)}if(m||m===0){v+=m}v+='.\n </div>\n \n \n \n <div class="tags-display">\n <label class="prompt">';g={hash:{},inverse:t.noop,fn:t.program(15,z,C),data:C};if(m=u.local){m=m.call(w,g)}else{m=w.local;m=typeof m===e?m.apply(w):m}if(!u.local){m=c.call(w,m,g)}if(m||m===0){v+=m}v+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';g={hash:{},inverse:t.noop,fn:t.program(17,y,C),data:C};if(m=u.local){m=m.call(w,g)}else{m=w.local;m=typeof m===e?m.apply(w):m}if(!u.local){m=c.call(w,m,g)}if(m||m===0){v+=m}v+='</label>\n <div class="annotation" title="';g={hash:{},inverse:t.noop,fn:t.program(19,x,C),data:C};if(m=u.local){m=m.call(w,g)}else{m=w.local;m=typeof m===e?m.apply(w):m}if(!u.local){m=c.call(w,m,g)}if(m||m===0){v+=m}v+='">\n ';m=u["if"].call(w,w.annotation,{hash:{},inverse:t.program(23,i,C),fn:t.program(21,l,C),data:C});if(m||m===0){v+=m}v+='\n </div>\n </div>\n\n </div>\n\n \n <div class="datasets-list"></div>\n\n <div class="empty-history-message infomessagesmall">\n ';g={hash:{},inverse:t.noop,fn:t.program(26,f,C),data:C};if(m=u.local){m=m.call(w,g)}else{m=w.local;m=typeof m===e?m.apply(w):m}if(!u.local){m=c.call(w,m,g)}if(m||m===0){v+=m}v+="\n </div>";return v})})(); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/templates/compiled/template-hda-body.js --- a/static/scripts/packed/templates/compiled/template-hda-body.js +++ b/static/scripts/packed/templates/compiled/template-hda-body.js @@ -1,1 +1,1 @@ -(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-body"]=b(function(j,v,t,o,C){this.compilerInfo=[4,">= 1.0.0"];t=this.merge(t,j.helpers);C=C||{};var u="",l,e="function",d=this.escapeExpression,s=this,c=t.blockHelperMissing;function r(G,F){var D="",E;D+="\n ";if(E=t.body){E=E.call(G,{hash:{},data:F})}else{E=G.body;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+='\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';return D}function q(G,F){var D="",E;D+='\n <div class="dataset-summary">\n ';E=t["if"].call(G,G.misc_blurb,{hash:{},inverse:s.noop,fn:s.program(4,p,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.data_type,{hash:{},inverse:s.noop,fn:s.program(6,n,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.metadata_dbkey,{hash:{},inverse:s.noop,fn:s.program(9,i,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.misc_info,{hash:{},inverse:s.noop,fn:s.program(12,A,F),data:F});if(E||E===0){D+=E}D+='\n </div>\n\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';E=t.unless.call(G,G.deleted,{hash:{},inverse:s.noop,fn:s.program(14,z,F),data:F});if(E||E===0){D+=E}D+="\n\n ";return D}function p(G,F){var D="",E;D+='\n <div class="dataset-blurb">\n <span class="value">';if(E=t.misc_blurb){E=E.call(G,{hash:{},data:F})}else{E=G.misc_blurb;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function n(H,G){var D="",F,E;D+='\n <div class="dataset-datatype">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(7,m,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">';if(F=t.data_type){F=F.call(H,{hash:{},data:G})}else{F=H.data_type;F=typeof F===e?F.apply(H):F}D+=d(F)+"</span>\n </div>\n ";return D}function m(E,D){return"format"}function i(H,G){var D="",F,E;D+='\n <div class="dataset-dbkey">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(10,B,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">\n ';if(F=t.metadata_dbkey){F=F.call(H,{hash:{},data:G})}else{F=H.metadata_dbkey;F=typeof F===e?F.apply(H):F}D+=d(F)+"\n </span>\n </div>\n ";return D}function B(E,D){return"database"}function A(G,F){var D="",E;D+='\n <div class="dataset-info">\n <span class="value">';if(E=t.misc_info){E=E.call(G,{hash:{},data:F})}else{E=G.misc_info;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function z(H,G){var D="",F,E;D+='\n \n <div class="tags-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(15,y,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(17,x,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div id="dataset-';if(F=t.id){F=F.call(H,{hash:{},data:G})}else{F=H.id;F=typeof F===e?F.apply(H):F}D+=d(F)+'-annotation" class="annotation editable-text"\n title="';E={hash:{},inverse:s.noop,fn:s.program(19,w,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='"></div>\n </div>\n\n <div class="dataset-display-applications">\n ';F=t.each.call(H,H.display_apps,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+="\n\n ";F=t.each.call(H,H.display_types,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+='\n </div>\n\n <div class="dataset-peek">\n ';F=t["if"].call(H,H.peek,{hash:{},inverse:s.noop,fn:s.program(25,f,G),data:G});if(F||F===0){D+=F}D+="\n </div>\n\n ";return D}function y(E,D){return"Tags"}function x(E,D){return"Annotation"}function w(E,D){return"Edit dataset annotation"}function k(G,F){var D="",E;D+='\n <div class="display-application">\n <span class="display-application-location">';if(E=t.label){E=E.call(G,{hash:{},data:F})}else{E=G.label;E=typeof E===e?E.apply(G):E}D+=d(E)+'</span>\n <span class="display-application-links">\n ';E=t.each.call(G,G.links,{hash:{},inverse:s.noop,fn:s.program(22,h,F),data:F});if(E||E===0){D+=E}D+="\n </span>\n </div>\n ";return D}function h(H,G){var D="",F,E;D+='\n <a target="';if(F=t.target){F=F.call(H,{hash:{},data:G})}else{F=H.target;F=typeof F===e?F.apply(H):F}D+=d(F)+'" href="';if(F=t.href){F=F.call(H,{hash:{},data:G})}else{F=H.href;F=typeof F===e?F.apply(H):F}D+=d(F)+'">';E={hash:{},inverse:s.noop,fn:s.program(23,g,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+="</a>\n ";return D}function g(F,E){var D;if(D=t.text){D=D.call(F,{hash:{},data:E})}else{D=F.text;D=typeof D===e?D.apply(F):D}return d(D)}function f(G,F){var D="",E;D+='\n <pre class="peek">';if(E=t.peek){E=E.call(G,{hash:{},data:F})}else{E=G.peek;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+="</pre>\n ";return D}u+='<div class="dataset-body">\n ';l=t["if"].call(v,v.body,{hash:{},inverse:s.program(3,q,C),fn:s.program(1,r,C),data:C});if(l||l===0){u+=l}u+="\n</div>";return u})})(); \ No newline at end of file +(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-body"]=b(function(j,v,t,o,C){this.compilerInfo=[4,">= 1.0.0"];t=this.merge(t,j.helpers);C=C||{};var u="",l,e="function",d=this.escapeExpression,s=this,c=t.blockHelperMissing;function r(G,F){var D="",E;D+='\n <div class="dataset-summary">\n ';if(E=t.body){E=E.call(G,{hash:{},data:F})}else{E=G.body;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+='\n </div>\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';return D}function q(G,F){var D="",E;D+='\n <div class="dataset-summary">\n ';E=t["if"].call(G,G.misc_blurb,{hash:{},inverse:s.noop,fn:s.program(4,p,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.data_type,{hash:{},inverse:s.noop,fn:s.program(6,n,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.metadata_dbkey,{hash:{},inverse:s.noop,fn:s.program(9,i,F),data:F});if(E||E===0){D+=E}D+="\n\n ";E=t["if"].call(G,G.misc_info,{hash:{},inverse:s.noop,fn:s.program(12,A,F),data:F});if(E||E===0){D+=E}D+='\n </div>\n\n <div class="dataset-actions clear">\n <div class="left"></div>\n <div class="right"></div>\n </div>\n\n ';E=t.unless.call(G,G.deleted,{hash:{},inverse:s.noop,fn:s.program(14,z,F),data:F});if(E||E===0){D+=E}D+="\n\n ";return D}function p(G,F){var D="",E;D+='\n <div class="dataset-blurb">\n <span class="value">';if(E=t.misc_blurb){E=E.call(G,{hash:{},data:F})}else{E=G.misc_blurb;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function n(H,G){var D="",F,E;D+='\n <div class="dataset-datatype">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(7,m,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">';if(F=t.data_type){F=F.call(H,{hash:{},data:G})}else{F=H.data_type;F=typeof F===e?F.apply(H):F}D+=d(F)+"</span>\n </div>\n ";return D}function m(E,D){return"format"}function i(H,G){var D="",F,E;D+='\n <div class="dataset-dbkey">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(10,B,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <span class="value">\n ';if(F=t.metadata_dbkey){F=F.call(H,{hash:{},data:G})}else{F=H.metadata_dbkey;F=typeof F===e?F.apply(H):F}D+=d(F)+"\n </span>\n </div>\n ";return D}function B(E,D){return"database"}function A(G,F){var D="",E;D+='\n <div class="dataset-info">\n <span class="value">';if(E=t.misc_info){E=E.call(G,{hash:{},data:F})}else{E=G.misc_info;E=typeof E===e?E.apply(G):E}D+=d(E)+"</span>\n </div>\n ";return D}function z(H,G){var D="",F,E;D+='\n \n <div class="tags-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(15,y,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';E={hash:{},inverse:s.noop,fn:s.program(17,x,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='</label>\n <div id="dataset-';if(F=t.id){F=F.call(H,{hash:{},data:G})}else{F=H.id;F=typeof F===e?F.apply(H):F}D+=d(F)+'-annotation" class="annotation editable-text"\n title="';E={hash:{},inverse:s.noop,fn:s.program(19,w,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+='"></div>\n </div>\n\n <div class="dataset-display-applications">\n ';F=t.each.call(H,H.display_apps,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+="\n\n ";F=t.each.call(H,H.display_types,{hash:{},inverse:s.noop,fn:s.program(21,k,G),data:G});if(F||F===0){D+=F}D+='\n </div>\n\n <div class="dataset-peek">\n ';F=t["if"].call(H,H.peek,{hash:{},inverse:s.noop,fn:s.program(25,f,G),data:G});if(F||F===0){D+=F}D+="\n </div>\n\n ";return D}function y(E,D){return"Tags"}function x(E,D){return"Annotation"}function w(E,D){return"Edit dataset annotation"}function k(G,F){var D="",E;D+='\n <div class="display-application">\n <span class="display-application-location">';if(E=t.label){E=E.call(G,{hash:{},data:F})}else{E=G.label;E=typeof E===e?E.apply(G):E}D+=d(E)+'</span>\n <span class="display-application-links">\n ';E=t.each.call(G,G.links,{hash:{},inverse:s.noop,fn:s.program(22,h,F),data:F});if(E||E===0){D+=E}D+="\n </span>\n </div>\n ";return D}function h(H,G){var D="",F,E;D+='\n <a target="';if(F=t.target){F=F.call(H,{hash:{},data:G})}else{F=H.target;F=typeof F===e?F.apply(H):F}D+=d(F)+'" href="';if(F=t.href){F=F.call(H,{hash:{},data:G})}else{F=H.href;F=typeof F===e?F.apply(H):F}D+=d(F)+'">';E={hash:{},inverse:s.noop,fn:s.program(23,g,G),data:G};if(F=t.local){F=F.call(H,E)}else{F=H.local;F=typeof F===e?F.apply(H):F}if(!t.local){F=c.call(H,F,E)}if(F||F===0){D+=F}D+="</a>\n ";return D}function g(F,E){var D;if(D=t.text){D=D.call(F,{hash:{},data:E})}else{D=F.text;D=typeof D===e?D.apply(F):D}return d(D)}function f(G,F){var D="",E;D+='\n <pre class="peek">';if(E=t.peek){E=E.call(G,{hash:{},data:F})}else{E=G.peek;E=typeof E===e?E.apply(G):E}if(E||E===0){D+=E}D+="</pre>\n ";return D}u+='<div class="dataset-body">\n ';l=t["if"].call(v,v.body,{hash:{},inverse:s.program(3,q,C),fn:s.program(1,r,C),data:C});if(l||l===0){u+=l}u+="\n</div>";return u})})(); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/templates/compiled/template-hda-skeleton.js --- a/static/scripts/packed/templates/compiled/template-hda-skeleton.js +++ b/static/scripts/packed/templates/compiled/template-hda-skeleton.js @@ -1,1 +1,1 @@ -(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-skeleton"]=b(function(f,r,p,k,w){this.compilerInfo=[4,">= 1.0.0"];p=this.merge(p,f.helpers);w=w||{};var q="",h,e="function",d=this.escapeExpression,o=this,c=p.blockHelperMissing;function n(B,A){var x="",z,y;x+='\n <div class="errormessagesmall">\n ';y={hash:{},inverse:o.noop,fn:o.program(2,m,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+=":\n ";y={hash:{},inverse:o.noop,fn:o.program(4,l,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </div>\n ";return x}function m(y,x){return"There was an error getting the data for this dataset"}function l(z,y){var x;if(x=p.error){x=x.call(z,{hash:{},data:y})}else{x=z.error;x=typeof x===e?x.apply(z):x}return d(x)}function j(A,z){var x="",y;x+="\n ";y=p["if"].call(A,A.purged,{hash:{},inverse:o.program(10,v,z),fn:o.program(7,i,z),data:z});if(y||y===0){x+=y}x+="\n ";return x}function i(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(8,g,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </strong></div>\n\n ";return x}function g(y,x){return"This dataset has been deleted and removed from disk."}function v(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(11,u,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n \n Click <a href="javascript:void(0);" class="dataset-undelete">here</a> to undelete it\n or <a href="javascript:void(0);" class="dataset-purge">here</a> to immediately remove it from disk\n </strong></div>\n ';return x}function u(y,x){return"This dataset has been deleted."}function t(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(14,s,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n Click <a href="javascript:void(0);" class="dataset-unhide">here</a> to unhide it\n </strong></div>\n ';return x}function s(y,x){return"This dataset has been hidden."}q+='<div class="dataset hda">\n <div class="dataset-warnings">\n ';h=p["if"].call(r,r.error,{hash:{},inverse:o.noop,fn:o.program(1,n,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p["if"].call(r,r.deleted,{hash:{},inverse:o.noop,fn:o.program(6,j,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p.unless.call(r,r.visible,{hash:{},inverse:o.noop,fn:o.program(13,t,w),data:w});if(h||h===0){q+=h}q+='\n </div>\n\n <div class="dataset-primary-actions"></div>\n\n <div class="dataset-title-bar">\n <span class="dataset-state-icon state-icon"></span>\n <div class="dataset-title">\n <span class="hda-hid">';if(h=p.hid){h=h.call(r,{hash:{},data:w})}else{h=r.hid;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n <span class="dataset-name">';if(h=p.name){h=h.call(r,{hash:{},data:w})}else{h=r.name;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n </div>\n </div>\n <div class="clear"></div>\n\n <div class="dataset-body"></div>\n</div>';return q})})(); \ No newline at end of file +(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-hda-skeleton"]=b(function(f,r,p,k,w){this.compilerInfo=[4,">= 1.0.0"];p=this.merge(p,f.helpers);w=w||{};var q="",h,e="function",d=this.escapeExpression,o=this,c=p.blockHelperMissing;function n(B,A){var x="",z,y;x+='\n <div class="errormessagesmall">\n ';y={hash:{},inverse:o.noop,fn:o.program(2,m,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+=":\n ";y={hash:{},inverse:o.noop,fn:o.program(4,l,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </div>\n ";return x}function m(y,x){return"There was an error getting the data for this dataset"}function l(z,y){var x;if(x=p.error){x=x.call(z,{hash:{},data:y})}else{x=z.error;x=typeof x===e?x.apply(z):x}return d(x)}function j(A,z){var x="",y;x+="\n ";y=p["if"].call(A,A.purged,{hash:{},inverse:o.program(10,v,z),fn:o.program(7,i,z),data:z});if(y||y===0){x+=y}x+="\n ";return x}function i(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(8,g,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+="\n </strong></div>\n\n ";return x}function g(y,x){return"This dataset has been deleted and removed from disk."}function v(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(11,u,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n \n Click <a href="javascript:void(0);" class="dataset-undelete">here</a> to undelete it\n or <a href="javascript:void(0);" class="dataset-purge">here</a> to immediately remove it from disk\n </strong></div>\n ';return x}function u(y,x){return"This dataset has been deleted."}function t(B,A){var x="",z,y;x+='\n <div class="warningmessagesmall"><strong>\n ';y={hash:{},inverse:o.noop,fn:o.program(14,s,A),data:A};if(z=p.local){z=z.call(B,y)}else{z=B.local;z=typeof z===e?z.apply(B):z}if(!p.local){z=c.call(B,z,y)}if(z||z===0){x+=z}x+='\n \n Click <a href="javascript:void(0);" class="dataset-unhide">here</a> to unhide it\n </strong></div>\n ';return x}function s(y,x){return"This dataset has been hidden."}q+='<div class="dataset hda">\n <div class="dataset-warnings">\n ';h=p["if"].call(r,r.error,{hash:{},inverse:o.noop,fn:o.program(1,n,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p["if"].call(r,r.deleted,{hash:{},inverse:o.noop,fn:o.program(6,j,w),data:w});if(h||h===0){q+=h}q+="\n\n ";h=p.unless.call(r,r.visible,{hash:{},inverse:o.noop,fn:o.program(13,t,w),data:w});if(h||h===0){q+=h}q+='\n </div>\n\n <div class="dataset-primary-actions"></div>\n <div class="dataset-title-bar clear">\n <span class="dataset-state-icon state-icon"></span>\n <div class="dataset-title">\n <span class="hda-hid">';if(h=p.hid){h=h.call(r,{hash:{},data:w})}else{h=r.hid;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n <span class="dataset-name">';if(h=p.name){h=h.call(r,{hash:{},data:w})}else{h=r.name;h=typeof h===e?h.apply(r):h}q+=d(h)+'</span>\n </div>\n </div>\n\n <div class="dataset-body"></div>\n</div>';return q})})(); \ No newline at end of file diff -r 8c78de92633e5474b6a9107595042868fe250679 -r 31b15f0d3e808741f2cf49156f9569973b3bda1d static/scripts/packed/templates/compiled/template-history-historyPanel.js --- a/static/scripts/packed/templates/compiled/template-history-historyPanel.js +++ b/static/scripts/packed/templates/compiled/template-history-historyPanel.js @@ -1,1 +1,1 @@ -(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel"]=b(function(k,x,v,p,E){this.compilerInfo=[4,">= 1.0.0"];v=this.merge(v,k.helpers);E=E||{};var w="",n,h,t=this,e="function",c=v.blockHelperMissing,d=this.escapeExpression;function s(J,I){var F="",H,G;F+='\n <div class="history-name editable-text" title="';G={hash:{},inverse:t.noop,fn:t.program(2,r,I),data:I};if(H=v.local){H=H.call(J,G)}else{H=J.local;H=typeof H===e?H.apply(J):H}if(!v.local){H=c.call(J,H,G)}if(H||H===0){F+=H}F+='">\n ';if(H=v.name){H=H.call(J,{hash:{},data:I})}else{H=J.name;H=typeof H===e?H.apply(J):H}F+=d(H)+"\n </div>\n ";return F}function r(G,F){return"Click to rename history"}function q(I,H){var F="",G;F+='\n <div class="history-size">';if(G=v.nice_size){G=G.call(I,{hash:{},data:H})}else{G=I.nice_size;G=typeof G===e?G.apply(I):G}F+=d(G)+"</div>\n ";return F}function o(G,F){return"Edit history tags"}function m(G,F){return"Edit history annotation"}function D(J,I){var F="",H,G;F+='\n <div class="warningmessagesmall"><strong>\n ';G={hash:{},inverse:t.noop,fn:t.program(11,C,I),data:I};if(H=v.local){H=H.call(J,G)}else{H=J.local;H=typeof H===e?H.apply(J):H}if(!v.local){H=c.call(J,H,G)}if(H||H===0){F+=H}F+="\n </strong></div>\n ";return F}function C(G,F){return"You are currently viewing a deleted history!"}function B(I,H){var F="",G;F+='\n \n <div class="';if(G=v.status){G=G.call(I,{hash:{},data:H})}else{G=I.status;G=typeof G===e?G.apply(I):G}F+=d(G)+'message">';if(G=v.message){G=G.call(I,{hash:{},data:H})}else{G=I.message;G=typeof G===e?G.apply(I):G}F+=d(G)+"</div>\n ";return F}function A(G,F){return"You are over your disk quota"}function z(G,F){return"Tool execution is on hold until your disk usage drops below your allocated quota"}function y(G,F){return"Tags"}function l(G,F){return"Annotation"}function j(G,F){return"Click to edit annotation"}function i(I,H){var F="",G;F+="\n ";if(G=v.annotation){G=G.call(I,{hash:{},data:H})}else{G=I.annotation;G=typeof G===e?G.apply(I):G}F+=d(G)+"\n ";return F}function g(J,I){var F="",H,G;F+="\n <em>";G={hash:{},inverse:t.noop,fn:t.program(28,f,I),data:I};if(H=v.local){H=H.call(J,G)}else{H=J.local;H=typeof H===e?H.apply(J):H}if(!v.local){H=c.call(J,H,G)}if(H||H===0){F+=H}F+="</em>\n ";return F}function f(G,F){return"Describe or add notes to history"}function u(G,F){return"Your history is empty. Click 'Get Data' on the left pane to start"}w+='<div class="history-controls">\n\n <div class="history-title">\n ';n=v["if"].call(x,x.name,{hash:{},inverse:t.noop,fn:t.program(1,s,E),data:E});if(n||n===0){w+=n}w+='\n </div>\n\n <div class="history-subtitle clear">\n ';n=v["if"].call(x,x.nice_size,{hash:{},inverse:t.noop,fn:t.program(4,q,E),data:E});if(n||n===0){w+=n}w+='\n\n <div class="history-secondary-actions">\n <a title="';h={hash:{},inverse:t.noop,fn:t.program(6,o,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='"\n class="icon-button tags" href="javascript:void(0)"></a>\n <a title="';h={hash:{},inverse:t.noop,fn:t.program(8,m,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='"\n class="icon-button annotate" href="javascript:void(0)"></a>\n </div>\n </div>\n\n ';n=v["if"].call(x,x.deleted,{hash:{},inverse:t.noop,fn:t.program(10,D,E),data:E});if(n||n===0){w+=n}w+='\n\n <div class="message-container">\n ';n=v["if"].call(x,x.message,{hash:{},inverse:t.noop,fn:t.program(13,B,E),data:E});if(n||n===0){w+=n}w+='\n </div>\n\n <div class="quota-message errormessage">\n ';h={hash:{},inverse:t.noop,fn:t.program(15,A,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+=".\n ";h={hash:{},inverse:t.noop,fn:t.program(17,z,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='.\n </div>\n \n \n \n <div class="tags-display">\n <label class="prompt">';h={hash:{},inverse:t.noop,fn:t.program(19,y,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';h={hash:{},inverse:t.noop,fn:t.program(21,l,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='</label>\n <div class="annotation editable-text" title="';h={hash:{},inverse:t.noop,fn:t.program(23,j,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+='">\n ';n=v["if"].call(x,x.annotation,{hash:{},inverse:t.program(27,g,E),fn:t.program(25,i,E),data:E});if(n||n===0){w+=n}w+='\n </div>\n </div>\n\n </div>\n\n \n <div class="datasets-list"></div>\n\n <div class="empty-history-message infomessagesmall">\n ';h={hash:{},inverse:t.noop,fn:t.program(30,u,E),data:E};if(n=v.local){n=n.call(x,h)}else{n=x.local;n=typeof n===e?n.apply(x):n}if(!v.local){n=c.call(x,n,h)}if(n||n===0){w+=n}w+="\n </div>";return w})})(); \ No newline at end of file +(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-history-historyPanel"]=b(function(i,u,s,n,A){this.compilerInfo=[4,">= 1.0.0"];s=this.merge(s,i.helpers);A=A||{};var t="",k,f,r=this,e="function",c=s.blockHelperMissing,d=this.escapeExpression;function q(F,E){var B="",D,C;B+='\n <div class="history-name" title="';C={hash:{},inverse:r.noop,fn:r.program(2,p,E),data:E};if(D=s.local){D=D.call(F,C)}else{D=F.local;D=typeof D===e?D.apply(F):D}if(!s.local){D=c.call(F,D,C)}if(D||D===0){B+=D}B+='">\n ';if(D=s.name){D=D.call(F,{hash:{},data:E})}else{D=F.name;D=typeof D===e?D.apply(F):D}B+=d(D)+"\n </div>\n ";return B}function p(C,B){return"Click to rename history"}function o(E,D){var B="",C;B+='\n <div class="history-size">';if(C=s.nice_size){C=C.call(E,{hash:{},data:D})}else{C=E.nice_size;C=typeof C===e?C.apply(E):C}B+=d(C)+"</div>\n ";return B}function m(F,E){var B="",D,C;B+='\n <div class="warningmessagesmall"><strong>\n ';C={hash:{},inverse:r.noop,fn:r.program(7,l,E),data:E};if(D=s.local){D=D.call(F,C)}else{D=F.local;D=typeof D===e?D.apply(F):D}if(!s.local){D=c.call(F,D,C)}if(D||D===0){B+=D}B+="\n </strong></div>\n ";return B}function l(C,B){return"You are currently viewing a deleted history!"}function h(E,D){var B="",C;B+='\n \n <div class="';if(C=s.status){C=C.call(E,{hash:{},data:D})}else{C=E.status;C=typeof C===e?C.apply(E):C}B+=d(C)+'message">';if(C=s.message){C=C.call(E,{hash:{},data:D})}else{C=E.message;C=typeof C===e?C.apply(E):C}B+=d(C)+"</div>\n ";return B}function z(C,B){return"You are over your disk quota"}function y(C,B){return"Tool execution is on hold until your disk usage drops below your allocated quota"}function x(C,B){return"Tags"}function w(C,B){return"Annotation"}function v(C,B){return"Click to edit annotation"}function j(D,C){var B;if(B=s.annotation){B=B.call(D,{hash:{},data:C})}else{B=D.annotation;B=typeof B===e?B.apply(D):B}return d(B)}function g(C,B){return"Your history is empty. Click 'Get Data' on the left pane to start"}t+='<div class="history-controls">\n\n <div class="history-title">\n ';k=s["if"].call(u,u.name,{hash:{},inverse:r.noop,fn:r.program(1,q,A),data:A});if(k||k===0){t+=k}t+='\n </div>\n\n <div class="history-subtitle clear">\n ';k=s["if"].call(u,u.nice_size,{hash:{},inverse:r.noop,fn:r.program(4,o,A),data:A});if(k||k===0){t+=k}t+='\n\n <div class="history-secondary-actions">\n </div>\n </div>\n\n ';k=s["if"].call(u,u.deleted,{hash:{},inverse:r.noop,fn:r.program(6,m,A),data:A});if(k||k===0){t+=k}t+='\n\n <div class="message-container">\n ';k=s["if"].call(u,u.message,{hash:{},inverse:r.noop,fn:r.program(9,h,A),data:A});if(k||k===0){t+=k}t+='\n </div>\n\n <div class="quota-message errormessage">\n ';f={hash:{},inverse:r.noop,fn:r.program(11,z,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+=".\n ";f={hash:{},inverse:r.noop,fn:r.program(13,y,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+='.\n </div>\n \n \n \n <div class="tags-display">\n <label class="prompt">';f={hash:{},inverse:r.noop,fn:r.program(15,x,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+='</label>\n <div class="tags"></div>\n </div>\n\n \n <div class="annotation-display">\n <label class="prompt">';f={hash:{},inverse:r.noop,fn:r.program(17,w,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+='</label>\n <div class="annotation" title="';f={hash:{},inverse:r.noop,fn:r.program(19,v,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+='"\n \n >';k=s["if"].call(u,u.annotation,{hash:{},inverse:r.noop,fn:r.program(21,j,A),data:A});if(k||k===0){t+=k}t+='</div>\n </div>\n\n </div>\n\n \n <div class="datasets-list"></div>\n\n <div class="empty-history-message infomessagesmall">\n ';f={hash:{},inverse:r.noop,fn:r.program(23,g,A),data:A};if(k=s.local){k=k.call(u,f)}else{k=u.local;k=typeof k===e?k.apply(u):k}if(!s.local){k=c.call(u,k,f)}if(k||k===0){t+=k}t+="\n </div>";return t})})(); \ No newline at end of file This diff is so big that we needed to truncate the remainder. https://bitbucket.org/galaxy/galaxy-central/commits/d8b4e3a8518a/ Changeset: d8b4e3a8518a User: dannon Date: 2013-10-31 13:13:19 Summary: Merge Affected #: 10 files diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee lib/tool_shed/galaxy_install/repository_util.py --- a/lib/tool_shed/galaxy_install/repository_util.py +++ b/lib/tool_shed/galaxy_install/repository_util.py @@ -94,22 +94,23 @@ def get_installed_repositories_from_repository_dependencies( trans, repository_dependencies_dict ): installed_repositories = [] - for rd_key, rd_vals in repository_dependencies_dict.items(): - if rd_key in [ 'root_key', 'description' ]: - continue - # rd_key is something like: 'http://localhost:9009__ESEP__package_rdkit_2012_12__ESEP__test__ESEP__d635ff...' - # rd_val is something like: [['http://localhost:9009', 'package_numpy_1_7', 'test', 'cddd64ecd985', 'True']] - repository_components_tuple = container_util.get_components_from_key( rd_key ) - components_list = suc.extract_components_from_tuple( repository_components_tuple ) - tool_shed, name, owner, changeset_revision = components_list[ 0:4 ] - installed_repository = suc.get_tool_shed_repository_by_shed_name_owner_changeset_revision( trans.app, tool_shed, name, owner, changeset_revision ) - if installed_repository not in installed_repositories: - installed_repositories.append( installed_repository ) - for rd_val in rd_vals: - tool_shed, name, owner, changeset_revision = rd_val[ 0:4 ] + if repository_dependencies_dict and isinstance( repository_dependencies_dict, dict ): + for rd_key, rd_vals in repository_dependencies_dict.items(): + if rd_key in [ 'root_key', 'description' ]: + continue + # rd_key is something like: 'http://localhost:9009__ESEP__package_rdkit_2012_12__ESEP__test__ESEP__d635ff...' + # rd_val is something like: [['http://localhost:9009', 'package_numpy_1_7', 'test', 'cddd64ecd985', 'True']] + repository_components_tuple = container_util.get_components_from_key( rd_key ) + components_list = suc.extract_components_from_tuple( repository_components_tuple ) + tool_shed, name, owner, changeset_revision = components_list[ 0:4 ] installed_repository = suc.get_tool_shed_repository_by_shed_name_owner_changeset_revision( trans.app, tool_shed, name, owner, changeset_revision ) if installed_repository not in installed_repositories: installed_repositories.append( installed_repository ) + for rd_val in rd_vals: + tool_shed, name, owner, changeset_revision = rd_val[ 0:4 ] + installed_repository = suc.get_tool_shed_repository_by_shed_name_owner_changeset_revision( trans.app, tool_shed, name, owner, changeset_revision ) + if installed_repository not in installed_repositories: + installed_repositories.append( installed_repository ) return installed_repositories def get_prior_install_required_dict( trans, tsr_ids, repo_info_dicts ): diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee lib/tool_shed/galaxy_install/tool_dependencies/install_util.py --- a/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py +++ b/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py @@ -836,7 +836,7 @@ pass return returncode, message -def set_environment( app, elem, tool_shed_repository ): +def set_environment( app, elem, tool_shed_repository, attr_tups_of_dependencies_for_install ): """ Create a ToolDependency to set an environment variable. This is different from the process used to set an environment variable that is associated with a package. An example entry in a tool_dependencies.xml file is:: @@ -854,42 +854,47 @@ tool_dependency = None env_var_version = elem.get( 'version', '1.0' ) for env_var_elem in elem: + # Althoug we're in a loop here, this method will always return only a single ToolDependency or None. + env_var_name = env_var_elem.get( 'name', None ) # The value of env_var_name must match the text value of at least 1 <requirement> tag in the tool config's <requirements> tag set whose # "type" attribute is "set_environment" (e.g., <requirement type="set_environment">R_SCRIPT_PATH</requirement>). - env_var_name = env_var_elem.get( 'name', None ) env_var_action = env_var_elem.get( 'action', None ) if env_var_name and env_var_action: - install_dir = get_tool_dependency_install_dir( app=app, - repository_name=tool_shed_repository.name, - repository_owner=tool_shed_repository.owner, - repository_changeset_revision=tool_shed_repository.installed_changeset_revision, - tool_dependency_type='set_environment', - tool_dependency_name=env_var_name, - tool_dependency_version=None ) - tool_shed_repository_install_dir = get_tool_shed_repository_install_dir( app, tool_shed_repository ) - env_var_dict = td_common_util.create_env_var_dict( env_var_elem, tool_shed_repository_install_dir=tool_shed_repository_install_dir ) - if env_var_dict: - if not os.path.exists( install_dir ): - os.makedirs( install_dir ) - tool_dependency = tool_dependency_util.create_or_update_tool_dependency( app=app, - tool_shed_repository=tool_shed_repository, - name=env_var_name, - version=None, - type='set_environment', - status=app.model.ToolDependency.installation_status.INSTALLING, - set_status=True ) - env_entry, env_file = td_common_util.create_or_update_env_shell_file( install_dir, env_var_dict ) - if env_var_version == '1.0': - # Handle setting environment variables using a fabric method. - fabric_util.file_append( env_entry, env_file, skip_if_contained=True, make_executable=True ) - sa_session.refresh( tool_dependency ) - if tool_dependency.status != app.model.ToolDependency.installation_status.ERROR: - tool_dependency.status = app.model.ToolDependency.installation_status.INSTALLED - sa_session.add( tool_dependency ) - sa_session.flush() - print 'Environment variable ', env_var_name, 'set in', install_dir - else: - raise NotImplementedError( 'Only set_environment version 1.0 is currently supported (i.e., change your tag to be <set_environment version="1.0">).' ) + # Tool dependencies of type "set_environmnet" always have the version attribute set to None. + attr_tup = ( env_var_name, None, 'set_environment' ) + if attr_tup in attr_tups_of_dependencies_for_install: + install_dir = get_tool_dependency_install_dir( app=app, + repository_name=tool_shed_repository.name, + repository_owner=tool_shed_repository.owner, + repository_changeset_revision=tool_shed_repository.installed_changeset_revision, + tool_dependency_type='set_environment', + tool_dependency_name=env_var_name, + tool_dependency_version=None ) + tool_shed_repository_install_dir = get_tool_shed_repository_install_dir( app, tool_shed_repository ) + env_var_dict = td_common_util.create_env_var_dict( env_var_elem, tool_shed_repository_install_dir=tool_shed_repository_install_dir ) + if env_var_dict: + if not os.path.exists( install_dir ): + os.makedirs( install_dir ) + tool_dependency = tool_dependency_util.create_or_update_tool_dependency( app=app, + tool_shed_repository=tool_shed_repository, + name=env_var_name, + version=None, + type='set_environment', + status=app.model.ToolDependency.installation_status.INSTALLING, + set_status=True ) + env_entry, env_file = td_common_util.create_or_update_env_shell_file( install_dir, env_var_dict ) + if env_var_version == '1.0': + # Handle setting environment variables using a fabric method. + fabric_util.file_append( env_entry, env_file, skip_if_contained=True, make_executable=True ) + sa_session.refresh( tool_dependency ) + if tool_dependency.status != app.model.ToolDependency.installation_status.ERROR: + tool_dependency.status = app.model.ToolDependency.installation_status.INSTALLED + sa_session.add( tool_dependency ) + sa_session.flush() + print 'Environment variable ', env_var_name, 'set in', install_dir + else: + raise NotImplementedError( 'Only set_environment version 1.0 is currently supported (i.e., change your tag to be <set_environment version="1.0">).' ) + return tool_dependency def strip_path( fpath ): if not fpath: diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee lib/tool_shed/util/common_install_util.py --- a/lib/tool_shed/util/common_install_util.py +++ b/lib/tool_shed/util/common_install_util.py @@ -483,24 +483,22 @@ app.model.ToolDependency.installation_status.ERROR ]: installed_tool_dependencies.append( tool_dependency ) elif elem.tag == 'set_environment': - env_var_name = elem.get( 'name', None ) - if env_var_name: - # Tool dependencies of type "set_environmnet" always have the version attribute set to None. - attr_tup = ( env_var_name, None, 'set_environment' ) - if attr_tup in attr_tups_of_dependencies_for_install: - try: - tool_dependency = set_environment( app, elem, tool_shed_repository ) - except Exception, e: - error_message = "Error setting environment for tool dependency: %s" % str( e ) - log.debug( error_message ) - if tool_dependency: - tool_dependency.status = app.model.ToolDependency.installation_status.ERROR - tool_dependency.error_message = error_message - sa_session.add( tool_dependency ) - sa_session.flush() - if tool_dependency and tool_dependency.status in [ app.model.ToolDependency.installation_status.INSTALLED, - app.model.ToolDependency.installation_status.ERROR ]: - installed_tool_dependencies.append( tool_dependency ) + # <set_environment version="1.0"> + # <environment_variable name="R_SCRIPT_PATH"action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable> + # </set_environment> + try: + tool_dependency = set_environment( app, elem, tool_shed_repository, attr_tups_of_dependencies_for_install ) + except Exception, e: + error_message = "Error setting environment for tool dependency: %s" % str( e ) + log.debug( error_message ) + if tool_dependency: + tool_dependency.status = app.model.ToolDependency.installation_status.ERROR + tool_dependency.error_message = error_message + sa_session.add( tool_dependency ) + sa_session.flush() + if tool_dependency and tool_dependency.status in [ app.model.ToolDependency.installation_status.INSTALLED, + app.model.ToolDependency.installation_status.ERROR ]: + installed_tool_dependencies.append( tool_dependency ) return installed_tool_dependencies def repository_dependency_needed_only_for_compiling_tool_dependency( repository, repository_dependency ): diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee static/scripts/mvc/base-mvc.js --- a/static/scripts/mvc/base-mvc.js +++ b/static/scripts/mvc/base-mvc.js @@ -233,7 +233,7 @@ return $( html ).css( options.css || { 'position' : 'fixed', - 'margin' : '6px 0px 0px 10px', + 'margin' : '12px 0px 0px 10px', 'opacity' : '0.85' }).hide(); } diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee static/scripts/packed/mvc/base-mvc.js --- a/static/scripts/packed/mvc/base-mvc.js +++ b/static/scripts/packed/mvc/base-mvc.js @@ -1,1 +1,1 @@ -var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){var a=this.logger.log;if(typeof this.logger.log==="object"){a=Function.prototype.bind.call(this.logger.log,this.logger)}return a.apply(this.logger,arguments)}return undefined}};var PersistentStorage=function(k,g){if(!k){throw ("PersistentStorage needs storageKey argument")}g=g||{};var i=sessionStorage,c=function j(m){var n=this.getItem(m);return(n!==null)?(JSON.parse(this.getItem(m))):(null)},b=function e(m,n){return this.setItem(m,JSON.stringify(n))},d=function f(m){return this.removeItem(m)};function a(n,m){n=n||{};m=m||null;return{get:function(o){if(o===undefined){return n}else{if(n.hasOwnProperty(o)){return(jQuery.type(n[o])==="object")?(new a(n[o],this)):(n[o])}}return undefined},set:function(o,p){n[o]=p;this._save();return this},deleteKey:function(o){delete n[o];this._save();return this},_save:function(){return m._save()},toString:function(){return("StorageRecursionHelper("+n+")")}}}var l={},h=c.call(i,k);if(h===null||h===undefined){h=jQuery.extend(true,{},g);b.call(i,k,h)}l=new a(h);jQuery.extend(l,{_save:function(m){return b.call(i,k,l.get())},destroy:function(){return d.call(i,k)},toString:function(){return"PersistentStorage("+k+")"}});return l};function LoadingIndicator(a,c){c=c||{};var b=this;function d(){var e=['<div class="loading-indicator">','<span class="fa fa-spinner fa-spin fa-lg" style="color: grey"></span>','<span style="margin-left: 8px; color: grey"><i>loading...</i></span>',"</div>"].join("\n");return $(e).css(c.css||{position:"fixed",margin:"6px 0px 0px 10px",opacity:"0.85"}).hide()}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}; \ No newline at end of file +var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){var a=this.logger.log;if(typeof this.logger.log==="object"){a=Function.prototype.bind.call(this.logger.log,this.logger)}return a.apply(this.logger,arguments)}return undefined}};var PersistentStorage=function(k,g){if(!k){throw ("PersistentStorage needs storageKey argument")}g=g||{};var i=sessionStorage,c=function j(m){var n=this.getItem(m);return(n!==null)?(JSON.parse(this.getItem(m))):(null)},b=function e(m,n){return this.setItem(m,JSON.stringify(n))},d=function f(m){return this.removeItem(m)};function a(n,m){n=n||{};m=m||null;return{get:function(o){if(o===undefined){return n}else{if(n.hasOwnProperty(o)){return(jQuery.type(n[o])==="object")?(new a(n[o],this)):(n[o])}}return undefined},set:function(o,p){n[o]=p;this._save();return this},deleteKey:function(o){delete n[o];this._save();return this},_save:function(){return m._save()},toString:function(){return("StorageRecursionHelper("+n+")")}}}var l={},h=c.call(i,k);if(h===null||h===undefined){h=jQuery.extend(true,{},g);b.call(i,k,h)}l=new a(h);jQuery.extend(l,{_save:function(m){return b.call(i,k,l.get())},destroy:function(){return d.call(i,k)},toString:function(){return"PersistentStorage("+k+")"}});return l};function LoadingIndicator(a,c){c=c||{};var b=this;function d(){var e=['<div class="loading-indicator">','<span class="fa fa-spinner fa-spin fa-lg" style="color: grey"></span>','<span style="margin-left: 8px; color: grey"><i>loading...</i></span>',"</div>"].join("\n");return $(e).css(c.css||{position:"fixed",margin:"12px 0px 0px 10px",opacity:"0.85"}).hide()}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}; \ No newline at end of file diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee static/style/blue/base.css --- a/static/style/blue/base.css +++ b/static/style/blue/base.css @@ -1530,43 +1530,48 @@ .history-panel .dataset:last-child{border-width:1px 0px 1px 0px} .history-panel .empty-history-message{display:none;margin:0px 10px 0px 10px} .history-panel .tag-button{display:inline-block;height:20px;margin:2px 2px 0px 0px;border:1px solid grey;border-radius:3px 10px 10px 3px;padding:2px 4px 2px 4px;background-color:#EEE;line-height:13px}.history-panel .tag-button .tag-name{margin-right:2px} -.dataset{border:1px solid #bfbfbf}.dataset [class$=messagesmall]{margin:8px 10px 4px 8px;font-size:90%} -.dataset .dataset-title-bar{cursor:pointer;padding:6px 10px 6px 8px}.dataset .dataset-title-bar .dataset-state-icon{display:inline-block;vertical-align:middle;line-height:16px;width:16px;height:16px;background-position:0 1px;background-repeat:no-repeat} +.dataset{border:1px solid #bfbfbf}.dataset .vertical-spacing{margin-bottom:8px} +.dataset .info-section{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px} +.dataset .dataset-padding{padding:6px 10px 6px 8px} +.dataset [class$=messagesmall]{margin:6px 10px 2px 8px;font-size:90%} +.dataset .dataset-title-bar{cursor:pointer;padding:6px 10px 6px 8px} .dataset .dataset-title-bar .dataset-title{display:inline;font-weight:bold;text-decoration:underline;word-break:normal;line-height:16px} -.dataset .dataset-primary-actions{float:right;margin:6px 10px 0px 0px}.dataset .dataset-primary-actions .icon-btn{margin-left:2px} -.dataset .vertical-padding{padding-bottom:8px} +.dataset .dataset-primary-actions{float:right;margin:6px 10px 0}.dataset .dataset-primary-actions .icon-btn{margin-left:2px} .dataset .dataset-body{display:none;background-color:rgba(255,255,255,0.30000000000000004);padding:6px 10px 6px 8px}.dataset .dataset-body [class$=messagesmall]{margin:0px 0px 8px 0px} -.dataset .dataset-body .dataset-summary{padding-bottom:8px} .dataset .dataset-body label{margin:0px;padding:0px;font-weight:normal} .dataset .dataset-body .prompt{font-weight:normal;font-style:italic;font-size:90%;color:#555} .dataset .dataset-body .prompt:after{content:':'} -.dataset .dataset-body .dataset-datatype,.dataset .dataset-body .dataset-dbkey{display:inline}.dataset .dataset-body .dataset-datatype .value,.dataset .dataset-body .dataset-dbkey .value{font-weight:bold} -.dataset .dataset-body .dataset-datatype .value:after{content:','} -.dataset .dataset-body .dataset-dbkey:after{content:' ';display:none;margin-bottom:32px} -.dataset .dataset-body .dataset-info{margin-top:4px;border-radius:3px;border:1px solid rgba(153,153,153,0.5);padding:4px}.dataset .dataset-body .dataset-info .value{white-space:pre-line} -.dataset .dataset-body .dataset-actions{margin-bottom:4px}.dataset .dataset-body .dataset-actions .left{float:left}.dataset .dataset-body .dataset-actions .left .icon-btn{margin-right:2px} +.dataset .dataset-body .dataset-summary{margin-bottom:8px}.dataset .dataset-body .dataset-summary .dataset-blurb{margin-bottom:2px} +.dataset .dataset-body .dataset-summary .dataset-datatype,.dataset .dataset-body .dataset-summary .dataset-dbkey{display:inline}.dataset .dataset-body .dataset-summary .dataset-datatype .value,.dataset .dataset-body .dataset-summary .dataset-dbkey .value{font-weight:bold} +.dataset .dataset-body .dataset-summary .dataset-datatype .value:after{content:','} +.dataset .dataset-body .dataset-summary .dataset-dbkey:after{content:' ';display:block;margin-bottom:8px} +.dataset .dataset-body .dataset-summary .dataset-info{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px}.dataset .dataset-body .dataset-summary .dataset-info .value{white-space:pre-line} +.dataset .dataset-body .dataset-actions .left{float:left}.dataset .dataset-body .dataset-actions .left .icon-btn{margin-right:2px} .dataset .dataset-body .dataset-actions .left .icon-btn-group{margin-right:2px}.dataset .dataset-body .dataset-actions .left .icon-btn-group .icon-btn{margin-right:0} +.dataset .dataset-body .dataset-actions .left:not(:empty){margin-bottom:8px} .dataset .dataset-body .dataset-actions .right{float:right}.dataset .dataset-body .dataset-actions .right .icon-btn{margin-left:2px} -.dataset .dataset-body .tags-display{display:none;padding-bottom:8px} -.dataset .dataset-body .annotation-display{display:none;padding-bottom:8px}.dataset .dataset-body .annotation-display .annotation{border-radius:3px;border:1px solid rgba(153,153,153,0.5);padding:4px;white-space:pre-line} +.dataset .dataset-body .tags-display{display:none;margin-bottom:8px} +.dataset .dataset-body .annotation-display{display:none;margin-bottom:8px}.dataset .dataset-body .annotation-display .annotation{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px;white-space:pre-line} .dataset .dataset-body .annotation-display textarea{margin:0px 0px 2px 0px;display:block;border-radius:3px;width:100%} -.dataset .dataset-body .dataset-peek pre.peek{width:100%;margin-top:8px;border-radius:3px;background:white;color:black;font-size:10px;overflow:auto}.dataset .dataset-body .dataset-peek pre.peek th{color:white;background:#5f6990} +.dataset .dataset-body .dataset-display-applications .display-application:last-child{margin-bottom:8px} +.dataset .dataset-body .dataset-peek{margin-bottom:8px}.dataset .dataset-body .dataset-peek pre.peek{width:100%;margin:0px;border-radius:3px;background:white;color:black;font-size:10px;overflow:auto}.dataset .dataset-body .dataset-peek pre.peek th{color:white;background:#5f6990} .dataset .dataset-body .dataset-peek pre.peek table,.dataset .dataset-body .dataset-peek pre.peek th,.dataset .dataset-body .dataset-peek pre.peek tr,.dataset .dataset-body .dataset-peek pre.peek td{font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:10px} .dataset .icon-btn-group{display:inline-block}.dataset .icon-btn-group .icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none} .dataset .icon-btn-group .icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px} .dataset .icon-btn-group .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px} -.dataset.state-new{background:#eee}.dataset.state-new .state-icon{font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.dataset.state-new .state-icon:before{content:"\f071"} +.dataset .state-icon{font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;vertical-align:middle;width:16px;height:16px;line-height:16px;text-align:center;font-size:16px} +.state-icon-error{background-color:white;border-radius:8px}.state-icon-error:before{font-size:20px;line-height:16px;color:red;content:"\f057"} +.state-icon-running{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)} 100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)} 100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)} 100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)} 100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)} 100%{transform:rotate(359deg)}}.state-icon-running:before{content:"\f110"} +.state-icon-upload{overflow:hidden}.state-icon-upload:before{display:inline-block;-webkit-animation:eclipse 2s infinite linear;-moz-animation:eclipse 2s infinite linear;-o-animation:eclipse 2s infinite linear;animation:eclipse 2s infinite linear;content:"\f062"}@-moz-keyframes eclipse{0%{-moz-transform:translate(0, 16px)} 100%{-moz-transform:translate(0, -16px)}}@-webkit-keyframes eclipse{0%{-webkit-transform:translate(0, 16px)} 100%{-webkit-transform:translate(0, -16px)}}@-o-keyframes eclipse{0%{-o-transform:translate(0, 16px)} 100%{-o-transform:translate(0, -16px)}}@-ms-keyframes eclipse{0%{-ms-transform:translate(0, 16px)} 100%{-ms-transform:translate(0, -16px)}}@keyframes eclipse{0%{transform:translate(0, 16px)} 100%{transform:translate(0, -16px)}} .dataset.state-ok,.dataset.state-failed_metadata{background:#aff1af}.dataset.state-ok .state-icon,.dataset.state-failed_metadata .state-icon{display:none} -.dataset.state-error{background:#f9c7c5}.dataset.state-error .state-icon{background-image:url(sprite-history-states.png);background-position:0px -15px;width:15px;height:15px;height:15px} -.dataset.state-empty{background:#f9c7c5}.dataset.state-empty .state-icon{background-image:url(sprite-history-states.png);background-position:0px 0px;width:15px;height:15px;height:15px} -.dataset.state-running{background:#ffc}.dataset.state-running .state-icon{background-image:url(data_running.gif)} -.dataset.state-running .dataset-title-bar.spinner .state-icon{background:url(data_running.gif) 0 1px no-repeat !important} -.dataset.state-setting_metadata{background:#ffc}.dataset.state-setting_metadata .state-icon{background-image:url(data_running.gif)} -.dataset.state-upload{background:#a6e4f7}.dataset.state-upload .state-icon{background-image:url(data_upload.gif)} -.dataset.state-queued{background:#eee}.dataset.state-queued .state-icon{background-image:url(sprite-history-states.png);background-position:0px -45px;width:15px;height:15px;height:15px} -.dataset.state-discarded{background:#eee}.dataset.state-discarded .state-icon{line-height:16px;font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.dataset.state-discarded .state-icon:before{content:"\f05e"} -.dataset.state-noPermission{background:#eee;filter:alpha(opacity=60);-moz-opacity:.60;opacity:.60}.dataset.state-noPermission .state-icon{line-height:16px;font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.dataset.state-noPermission .state-icon:before{content:"\f05e"} +.dataset.state-error,.dataset.state-empty{background:#f9c7c5}.dataset.state-error .state-icon,.dataset.state-empty .state-icon{background-color:white;border-radius:8px}.dataset.state-error .state-icon:before,.dataset.state-empty .state-icon:before{font-size:20px;line-height:16px;color:red;content:"\f057"} +.dataset.state-upload{background:#a6e4f7}.dataset.state-upload .state-icon{overflow:hidden}.dataset.state-upload .state-icon:before{display:inline-block;-webkit-animation:eclipse 2s infinite linear;-moz-animation:eclipse 2s infinite linear;-o-animation:eclipse 2s infinite linear;animation:eclipse 2s infinite linear;content:"\f062"}@-moz-keyframes eclipse{0%{-moz-transform:translate(0, 16px)} 100%{-moz-transform:translate(0, -16px)}}@-webkit-keyframes eclipse{0%{-webkit-transform:translate(0, 16px)} 100%{-webkit-transform:translate(0, -16px)}}@-o-keyframes eclipse{0%{-o-transform:translate(0, 16px)} 100%{-o-transform:translate(0, -16px)}}@-ms-keyframes eclipse{0%{-ms-transform:translate(0, 16px)} 100%{-ms-transform:translate(0, -16px)}}@keyframes eclipse{0%{transform:translate(0, 16px)} 100%{transform:translate(0, -16px)}} +.dataset.state-queued{background:#eee}.dataset.state-queued .state-icon:before{content:"\f017"} +.dataset.state-running,.dataset.state-setting_metadata{background:#ffc}.dataset.state-running .state-icon,.dataset.state-setting_metadata .state-icon{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)} 100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)} 100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)} 100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)} 100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)} 100%{transform:rotate(359deg)}}.dataset.state-running .state-icon:before,.dataset.state-setting_metadata .state-icon:before{content:"\f110"} .dataset.state-paused{background:#d9edf7}.dataset.state-paused .state-icon:before{content:"\f04c"} +.dataset.state-discarded{background:#eee}.dataset.state-discarded .state-icon:before{content:"\f014"} +.dataset.state-noPermission{background:#eee;filter:alpha(opacity=60);-moz-opacity:.60;opacity:.60}.dataset.state-noPermission .state-icon{font-size:20px}.dataset.state-noPermission .state-icon:before{content:"\f023"} +.dataset.state-new{background:#eee}.dataset.state-new .state-icon:before{content:"\f06a"} .hda .hda-hid:after{content:':'} body.historyPage{background:#dfe5f9;color:#000;margin:5px;border:0;padding:0} div.historyLinks{margin:5px 5px} diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee static/style/src/less/history.less --- a/static/style/src/less/history.less +++ b/static/style/src/less/history.less @@ -186,21 +186,41 @@ .dataset { border: 1px solid @border-default-color; + // body mixins + @vertical-gap: 8px; + .vertical-spacing { + margin-bottom: @vertical-gap; + } + .info-section { + border-radius: 3px; + border: 1px solid fadeout( @layout-border-color, 70% ); + //background-color: fadeout( white, 60% ); + padding: 4px; + } + @spacing-top : 6px; + @spacing-right : 10px; + @spacing-bottom : 6px; + @spacing-left : 8px; + .dataset-padding { + padding: @spacing-top @spacing-right @spacing-bottom @spacing-left; + } + [class$=messagesmall] { - margin: 8px 10px 4px 8px; + margin: @spacing-top @spacing-right ( @spacing-bottom - 4 ) @spacing-left; font-size: 90%; } + .dataset-title-bar { cursor: pointer; - padding: 6px 10px 6px 8px; + .dataset-padding; .dataset-state-icon { - display: inline-block; - vertical-align: middle; - line-height: 16px; - width: 16px; - height: 16px; - background-position: 0 1px; - background-repeat: no-repeat; + //display: inline-block; + //vertical-align: middle; + //line-height: 16px; + //width: 16px; + //height: 16px; + //background-position: 0 1px; + //background-repeat: no-repeat; } .dataset-title { display: inline; @@ -213,27 +233,20 @@ .dataset-primary-actions { float: right; - margin: 6px 10px 0px 0px; + margin: @spacing-top @spacing-right 0; .icon-btn { margin-left: @icon-btn-margin; } } - //TODO: use :empty or :not(:empty) - .vertical-padding { - padding-bottom: 8px; - } .dataset-body { display: none; background-color: fadeout( white, 70% ); - padding: 6px 10px 6px 8px; + .dataset-padding; [class$=messagesmall] { margin: 0px 0px 8px 0px; } - .dataset-summary { - .vertical-padding; - } label { margin: 0px; @@ -246,38 +259,39 @@ font-size: 90%; color: #555; } - .prompt:after { content: ':'; } - .dataset-datatype, .dataset-dbkey { - display: inline; - .value { - font-weight: bold; + + .dataset-summary { + .dataset-blurb { + margin-bottom: 2px; } - } - .dataset-datatype .value:after { - content: ','; - } - .dataset-dbkey:after { - content: ' '; - display: none; - margin-bottom: 32px; - } - - .dataset-info { - margin-top: 4px; - border-radius: 3px; - border: 1px solid fadeout( @layout-border-color, 50% ); - //background-color: fadeout( white, 60% ); - padding: 4px; - .value { - white-space: pre-line; + .dataset-datatype, .dataset-dbkey { + display: inline; + .value { + font-weight: bold; + } } + .dataset-datatype .value:after { + content: ','; + } + .dataset-dbkey:after { + content: ' '; + display: block; + .vertical-spacing; + } + .dataset-info { + .info-section; + .value { + white-space: pre-line; + } + } + // handle the last vertical gap in the parent as summary is used in other states as well (w/o info) + .vertical-spacing; } .dataset-actions { - margin-bottom: 4px; .left { float: left; .icon-btn { @@ -289,6 +303,11 @@ margin-right: 0; } } + &:not(:empty) { + // can't use :empty on dataset-actions - will always have left & right, so + // add gap to left (more likely to have children) + .vertical-spacing; + } } .right { float: right; @@ -301,16 +320,13 @@ //TODO: move these out .tags-display { display: none; - .vertical-padding; + .vertical-spacing; } .annotation-display { display: none; - .vertical-padding; + .vertical-spacing; .annotation { - border-radius: 3px; - border: 1px solid fadeout( @layout-border-color, 50% ); - //background-color: fadeout( white, 60% ); - padding: 4px; + .info-section; white-space: pre-line; } textarea { @@ -321,21 +337,30 @@ } } - .dataset-peek pre.peek { - width: 100%; - margin-top: 8px; - border-radius: 3px; - background: white; - color: black; - font-size: 10px; - overflow: auto; - th { - color: white; - background: @panel-primary-heading-bg; + .dataset-display-applications { + .display-application:last-child { + .vertical-spacing; } - table, th, tr, td { - font-family: @font-family-monospace; + } + + .dataset-peek { + .vertical-spacing; + pre.peek { + width: 100%; + margin: 0px; + border-radius: 3px; + background: white; + color: black; font-size: 10px; + overflow: auto; + th { + color: white; + background: @panel-primary-heading-bg; + } + table, th, tr, td { + font-family: @font-family-monospace; + font-size: 10px; + } } } } @@ -360,18 +385,95 @@ } -// Default history item appearance -// Change background/border color depending on state -.dataset.state-new { - background: @state-default-bg; - .state-icon { - .fa-icon; - &:before { - content: "\f071"; - } +.dataset .state-icon { + .fa-icon; + display: inline-block; + vertical-align: middle; + width: 16px; + height: 16px; + line-height: 16px; + text-align: center; + font-size: 16px; +} + +.state-icon-error { + background-color: white; + border-radius: 8px; + &:before { + font-size: 20px; + line-height: 16px; + color: red; + content: @fa-var-times-circle; } } +.state-icon-running { + //TODO: couldn't find a way to do this with fa/spinning.less as mixin + -webkit-animation: spin 2s infinite linear; + -moz-animation: spin 2s infinite linear; + -o-animation: spin 2s infinite linear; + animation: spin 2s infinite linear; + + @-moz-keyframes spin { + 0% { -moz-transform: rotate(0deg); } + 100% { -moz-transform: rotate(359deg); } + } + @-webkit-keyframes spin { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(359deg); } + } + @-o-keyframes spin { + 0% { -o-transform: rotate(0deg); } + 100% { -o-transform: rotate(359deg); } + } + @-ms-keyframes spin { + 0% { -ms-transform: rotate(0deg); } + 100% { -ms-transform: rotate(359deg); } + } + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(359deg); } + } + &:before { + content: @fa-var-spinner; + } +} + +.state-icon-upload { + overflow: hidden; + + &:before { + display: inline-block; + -webkit-animation: eclipse 2s infinite linear; + -moz-animation: eclipse 2s infinite linear; + -o-animation: eclipse 2s infinite linear; + animation: eclipse 2s infinite linear; + + @-moz-keyframes eclipse { + 0% { -moz-transform: translate(0px,16px); } + 100% { -moz-transform: translate(0px,-16px); } + } + @-webkit-keyframes eclipse { + 0% { -webkit-transform: translate(0px,16px); } + 100% { -webkit-transform: translate(0px,-16px); } + } + @-o-keyframes eclipse { + 0% { -o-transform: translate(0px,16px); } + 100% { -o-transform: translate(0px,-16px); } + } + @-ms-keyframes eclipse { + 0% { -ms-transform: translate(0px,16px); } + 100% { -ms-transform: translate(0px,-16px); } + } + @keyframes eclipse { + 0% { transform: translate(0px,16px); } + 100% { transform: translate(0px,-16px); } + } + content: @fa-var-arrow-up; + } +} + +// Change background/border color depending on state .dataset.state-ok, .dataset.state-failed_metadata { background: @state-success-bg; .state-icon { @@ -379,59 +481,52 @@ } } -.dataset.state-error { - background: @state-danger-bg; - .state-icon { - .sprite(@data_error); - } -} - +.dataset.state-error, .dataset.state-empty { background: @state-danger-bg; .state-icon { - .sprite(@data_empty); - } -} - -.dataset.state-running { - background: @state-running-bg; - .state-icon { - background-image: url(data_running.gif); - } -} -// Special case for showing the spinner but not changing the background -.dataset.state-running .dataset-title-bar.spinner .state-icon { - background: url(data_running.gif) 0 1px no-repeat !important; -} - -.dataset.state-setting_metadata { - background: @state-running-bg; - .state-icon { - background-image: url(data_running.gif); + .state-icon-error; } } .dataset.state-upload { background: @state-info-bg; .state-icon { - background-image: url(data_upload.gif); + .state-icon-upload; } } .dataset.state-queued { background: @state-default-bg; .state-icon { - .sprite(@data_queued); + &:before { + content: @fa-var-clock-o; + } + } +} + +.dataset.state-running, +.dataset.state-setting_metadata { + background: @state-running-bg; + .state-icon { + .state-icon-running; + } +} + +.dataset.state-paused { + background: @state-paused-bg; + .state-icon { + &:before { + content: @fa-var-pause; + } } } .dataset.state-discarded { background: @state-default-bg; .state-icon { - line-height: 16px; - .fa-icon; &:before { - content: "\f05e"; + content: @fa-var-trash-o; } } } @@ -442,24 +537,23 @@ -moz-opacity: .60; opacity: .60; .state-icon { - line-height: 16px; - .fa-icon; + font-size: 20px; &:before { - content: "\f05e"; + content: @fa-var-lock; } } } -.dataset.state-paused { - background: @state-paused-bg; +.dataset.state-new { + background: @state-default-bg; .state-icon { - //.@fa-css-prefix; &:before { - content: "\f04c"; + content: @fa-var-exclamation-circle; } } } + // ---------------------------------------------------------------------------- hdas .hda .hda-hid:after { content: ':'; diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee test/tool_shed/functional/test_1100_install_repository_with_complex_dependencies.py --- a/test/tool_shed/functional/test_1100_install_repository_with_complex_dependencies.py +++ b/test/tool_shed/functional/test_1100_install_repository_with_complex_dependencies.py @@ -58,7 +58,7 @@ commit_message='Uploaded tool_dependencies.xml.', strings_displayed=[ 'This repository currently contains a single file named <b>tool_dependencies.xml</b>' ], strings_not_displayed=[] ) - self.display_manage_repository_page( repository, strings_displayed=[ 'Tool dependencies', 'may not be', 'in this repository' ] ) + self.display_manage_repository_page( repository, strings_displayed=[ 'Tool dependencies', 'type should be set to' ] ) def test_0010_create_bwa_base_repository( self ): '''Create and populate bwa_base_0100.''' diff -r 31b15f0d3e808741f2cf49156f9569973b3bda1d -r d8b4e3a8518a7b3efc575bfb7625a93203e998ee test/tool_shed/functional/test_1230_uninstall_reinstall_repository_with_dependency_revisions.py --- a/test/tool_shed/functional/test_1230_uninstall_reinstall_repository_with_dependency_revisions.py +++ b/test/tool_shed/functional/test_1230_uninstall_reinstall_repository_with_dependency_revisions.py @@ -136,9 +136,13 @@ # repository, and this should add datatypes to the datatypes registry. If that is the case, verify that datatypes # have been added, otherwise verify that the count is unchanged. if running_standalone: - assert current_datatypes == base_datatypes_count + repository_datatypes_count, 'Installing emboss did not add new datatypes.' + assert current_datatypes == base_datatypes_count + repository_datatypes_count, \ + 'Installing emboss resulted in unexpected count in datatypes registry, expected: %s, actual: %s, original: %s, added from repo: %s' % \ + ( str( base_datatypes_count + repository_datatypes_count ), str( current_datatypes ), str( base_datatypes_count ), str( repository_datatypes_count ) ) else: - assert current_datatypes == base_datatypes_count, 'Installing emboss added new datatypes.' + assert current_datatypes == base_datatypes_count, \ + 'Installing emboss added new datatypes, current datatypes: %s, original datatypes: %s' % \ + ( str( current_datatypes ), str( base_datatypes_count ) ) def test_0015_uninstall_emboss_repository( self ): '''Uninstall the emboss repository.''' 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.