2 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/c4e19939b6a3/ Changeset: c4e19939b6a3 User: dannon Date: 2014-08-28 23:21:03 Summary: Remove option for the (long since deprecated in favor of Data Managers) data_admin interface from admin Affected #: 1 file diff -r 03e9b373ec42cf727a5d735876f55ab442f73310 -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 templates/webapps/galaxy/admin/index.mako --- a/templates/webapps/galaxy/admin/index.mako +++ b/templates/webapps/galaxy/admin/index.mako @@ -66,9 +66,6 @@ <div class="toolTitle"><a href="${h.url_for( controller='admin', action='quotas' )}" target="galaxy_main">Manage quotas</a></div> %endif <div class="toolTitle"><a href="${h.url_for( controller='library_admin', action='browse_libraries' )}" target="galaxy_main">Manage data libraries</a></div> - %if trans.app.config.enable_beta_job_managers: - <div class="toolTitle"><a href="${h.url_for( controller='data_admin', action='manage_data' )}" target="galaxy_main">Manage local data</a></div> - %endif <div class="toolTitle"><a href="${h.url_for( controller='data_manager' )}" target="galaxy_main">Manage local data (beta)</a></div></div></div> https://bitbucket.org/galaxy/galaxy-central/commits/11e6f0627812/ Changeset: 11e6f0627812 User: dannon Date: 2014-08-28 23:21:42 Summary: Merge. Affected #: 25 files diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 .hgtags --- a/.hgtags +++ b/.hgtags @@ -18,4 +18,4 @@ 81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04 2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10 ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11 -7e22f35798522100ff03e1fdd4eced962b292360 latest_2014.08.11 +109b170188e97fbfc2c998ec174aff9546dd1bd8 latest_2014.08.11 diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 lib/galaxy/dataset_collections/structure.py --- a/lib/galaxy/dataset_collections/structure.py +++ b/lib/galaxy/dataset_collections/structure.py @@ -35,9 +35,9 @@ return self._walk_collections( dict_map( lambda hdca: hdca.collection, hdca_dict ) ) def _walk_collections( self, collection_dict ): - for ( identifier, substructure ) in self.children: + for index, ( identifier, substructure ) in enumerate( self.children ): def element( collection ): - return collection[ identifier ] + return collection[ index ] if substructure.is_leaf: yield dict_map( element, collection_dict ) diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 lib/galaxy/web/base/controller.py --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -27,7 +27,7 @@ from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, TextArea, TextField from galaxy.web.form_builder import build_select_field, HistoryField, PasswordField, WorkflowField, WorkflowMappingField from galaxy.workflow.modules import module_factory, WorkflowModuleInjector, MissingToolException -from galaxy.model.orm import eagerload, eagerload_all, desc +from galaxy.model.orm import eagerload, eagerload_all, desc, not_ from galaxy.security.validate_user_input import validate_publicname from galaxy.util.sanitize_html import sanitize_html from galaxy.model.item_attrs import Dictifiable, UsesAnnotations @@ -2683,7 +2683,7 @@ item = self.get_item( trans, id ) if item: # Only update slug if slug is not already in use. - if trans.sa_session.query( item.__class__ ).filter_by( user=item.user, slug=new_slug, importable=True ).count() == 0: + if trans.sa_session.query( item.__class__ ).filter_by( user=item.user, slug=new_slug ).count() == 0: item.slug = new_slug trans.sa_session.flush() @@ -2718,7 +2718,9 @@ # add integer to end. new_slug = slug_base count = 1 - while sa_session.query( item.__class__ ).filter_by( user=item.user, slug=new_slug, importable=True ).count() != 0: + # Ensure unique across model class and user and don't include this item + # in the check in case it has previously been assigned a valid slug. + while sa_session.query( item.__class__ ).filter( item.__class__.user == item.user, item.__class__.slug == new_slug, item.__class__.id != item.id).count() != 0: # Slug taken; choose a new slug based on count. This approach can # handle numerous items with the same name gracefully. new_slug = '%s-%i' % ( slug_base, count ) diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 lib/galaxy/webapps/galaxy/api/libraries.py --- a/lib/galaxy/webapps/galaxy/api/libraries.py +++ b/lib/galaxy/webapps/galaxy/api/libraries.py @@ -342,6 +342,7 @@ raise exceptions.InternalServerError( 'Error loading from the database.' + str(e)) return role + @expose_api def set_permissions( self, trans, encoded_library_id, **kwd ): """ @@ -385,7 +386,11 @@ action = kwd.get( 'action', None ) if action is None: - raise exceptions.RequestParameterMissingException( 'The mandatory parameter "action" is missing.' ) + payload = kwd.get( 'payload', None ) + if payload is not None: + return self.set_permissions_old( trans, library, payload, **kwd ) + else: + raise exceptions.RequestParameterMissingException( 'The mandatory parameter "action" is missing.' ) elif action == 'remove_restrictions': trans.app.security_agent.make_library_public( library ) if not trans.app.security_agent.library_is_public( library ): @@ -397,7 +402,6 @@ invalid_access_roles_names = [] for role_id in new_access_roles_ids: role = self._load_role( trans, role_id ) - # Check whether role is in the set of allowed roles valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, library, is_library_access=True ) if role in valid_roles: valid_access_roles.append( role ) @@ -411,7 +415,6 @@ invalid_add_roles_names = [] for role_id in new_add_roles_ids: role = self._load_role( trans, role_id ) - # Check whether role is in the set of allowed roles valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, library ) if role in valid_roles: valid_add_roles.append( role ) @@ -425,7 +428,6 @@ invalid_manage_roles_names = [] for role_id in new_manage_roles_ids: role = self._load_role( trans, role_id ) - # Check whether role is in the set of allowed roles valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, library ) if role in valid_roles: valid_manage_roles.append( role ) @@ -439,7 +441,6 @@ invalid_modify_roles_names = [] for role_id in new_modify_roles_ids: role = self._load_role( trans, role_id ) - # Check whether role is in the set of allowed roles valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, library ) if role in valid_roles: valid_modify_roles.append( role ) @@ -454,6 +455,9 @@ permissions.update( { trans.app.security_agent.permitted_actions.LIBRARY_MODIFY : valid_modify_roles } ) trans.app.security_agent.set_all_library_permissions( trans, library, permissions ) + trans.sa_session.refresh( library ) + # Copy the permissions to the root folder + trans.app.security_agent.copy_library_permissions( trans, library, library.root_folder ) else: raise exceptions.RequestParameterInvalidException( 'The mandatory parameter "action" has an invalid value.' 'Allowed values are: "remove_restrictions", set_permissions"' ) @@ -486,3 +490,25 @@ return dict( access_library_role_list=access_library_role_list, modify_library_role_list=modify_library_role_list, manage_library_role_list=manage_library_role_list, add_library_item_role_list=add_library_item_role_list ) + def set_permissions_old( self, trans, library, payload, **kwd ): + """ + *** old implementation for backward compatibility *** + + POST /api/libraries/{encoded_library_id}/permissions + Updates the library permissions. + """ + params = galaxy.util.Params( payload ) + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + role_params = params.get( k + '_in', [] ) + in_roles = [ trans.sa_session.query( trans.app.model.Role ).get( trans.security.decode_id( x ) ) for x in galaxy.util.listify( role_params ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + trans.app.security_agent.set_all_library_permissions( trans, library, permissions ) + trans.sa_session.refresh( library ) + # Copy the permissions to the root folder + trans.app.security_agent.copy_library_permissions( trans, library, library.root_folder ) + message = "Permissions updated for library '%s'." % library.name + + item = library.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id , 'root_folder_id' : trans.security.encode_id } ) + return item + diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 lib/galaxy/webapps/galaxy/api/permissions.py --- a/lib/galaxy/webapps/galaxy/api/permissions.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -API operations on the permissions of a library. -""" -import logging, os, string, shutil, urllib, re, socket -from cgi import escape, FieldStorage -import galaxy.util -from galaxy import util, datatypes, jobs, web -from galaxy.web.base.controller import * -from galaxy.util.sanitize_html import sanitize_html -from galaxy.model.orm import * - -log = logging.getLogger( __name__ ) - - -class PermissionsController( BaseAPIController ): - - # Method not ideally named - @web.expose_api - def create( self, trans, library_id, payload, **kwd ): - """ - POST /api/libraries/{encoded_library_id}/permissions - Updates the library permissions. - """ - if not trans.user_is_admin(): - trans.response.status = 403 - return "You are not authorized to update library permissions." - - params = galaxy.util.Params( payload ) - try: - decoded_library_id = trans.security.decode_id( library_id ) - except TypeError: - trans.response.status = 400 - return "Malformed library id ( %s ) specified, unable to decode." % str( library_id ) - - try: - library = trans.sa_session.query( trans.app.model.Library ).get( decoded_library_id ) - except: - library = None - - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - role_params = params.get( k + '_in', [] ) - in_roles = [ trans.sa_session.query( trans.app.model.Role ).get( trans.security.decode_id( x ) ) for x in galaxy.util.listify( role_params ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - trans.app.security_agent.set_all_library_permissions( trans, library, permissions ) - trans.sa_session.refresh( library ) - # Copy the permissions to the root folder - trans.app.security_agent.copy_library_permissions( trans, library, library.root_folder ) - message = "Permissions updated for library '%s'." % library.name - - item = library.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id , 'root_folder_id' : trans.security.encode_id } ) - return item diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/mvc/collection/paired-collection-creator.js --- a/static/scripts/mvc/collection/paired-collection-creator.js +++ b/static/scripts/mvc/collection/paired-collection-creator.js @@ -27,11 +27,14 @@ className : 'dataset paired', initialize : function( attributes ){ + //console.debug( 'PairView.initialize:', attributes ); this.pair = attributes.pair || {}; }, render : function(){ - this.$el.attr( 'draggable', true ) + this.$el + .attr( 'draggable', true ) + .data( 'pair', this.pair ) .html( _.template([ '<span class="forward-dataset-name flex-column"><%= pair.forward.name %></span>', '<span class="pair-name-column flex-column">', @@ -40,7 +43,51 @@ '<span class="reverse-dataset-name flex-column"><%= pair.reverse.name %></span>' ].join(''), { pair: this.pair })) .addClass( 'flex-column-container' ); + +//TODO: would be good to get the unpair-btn into this view - but haven't found a way with css + return this; + }, + + events : { + 'dragstart' : '_dragstart', + 'dragend' : '_dragend', + 'dragover' : '_sendToParent', + 'drop' : '_sendToParent' + }, + + /** dragging pairs for re-ordering */ + _dragstart : function( ev ){ + //console.debug( this, '_dragstartPair', ev ); + ev.currentTarget.style.opacity = '0.4'; + if( ev.originalEvent ){ ev = ev.originalEvent; } + + ev.dataTransfer.effectAllowed = 'move'; + ev.dataTransfer.setData( 'text/plain', JSON.stringify( this.pair ) ); + + //ev.dataTransfer.setDragImage( null, 0, 0 ); + + // the canvas can be used to create the image + //ev.dataTransfer.setDragImage( canvasCrossHairs(), 25, 25 ); + + //console.debug( 'ev.dataTransfer:', ev.dataTransfer ); + this.$el.parent().trigger( 'pair.dragstart', [ this ] ); + }, + /** dragging pairs for re-ordering */ + _dragend : function( ev ){ + //console.debug( this, '_dragendPair', ev ); + ev.currentTarget.style.opacity = '1.0'; + this.$el.parent().trigger( 'pair.dragend', [ this ] ); + }, + + /** manually bubble up an event to the parent/container */ + _sendToParent : function( ev ){ + this.$el.parent().trigger( ev ); + }, + + /** string rep */ + toString : function(){ + return 'PairView(' + this.pair.name + ')'; } }); @@ -106,6 +153,9 @@ /** is the paired panel shown? */ this.pairedPanelHidden = false; + /** DOM elements currently being dragged */ + this.$dragging = null; + this._dataSetUp(); this._setUpBehaviors(); @@ -929,8 +979,17 @@ 'mousedown .flexible-partition-drag' : '_startPartitionDrag', // paired 'click .paired-columns .dataset.paired' : 'selectPair', + 'click .paired-columns' : 'clearSelectedPaired', 'click .paired-columns .pair-name' : '_clickPairName', 'click .unpair-btn' : '_clickUnpair', + // paired - drop target + //'dragenter .paired-columns' : '_dragenterPairedColumns', + //'dragleave .paired-columns .column-datasets': '_dragleavePairedColumns', + 'dragover .paired-columns .column-datasets' : '_dragoverPairedColumns', + 'drop .paired-columns .column-datasets' : '_dropPairedColumns', + + 'pair.dragstart .paired-columns .column-datasets' : '_pairDragstart', + 'pair.dragend .paired-columns .column-datasets' : '_pairDragend', // footer 'change .remove-extensions' : function( ev ){ this.toggleExtensions(); }, @@ -1226,9 +1285,15 @@ // ........................................................................ paired /** select a pair when clicked */ selectPair : function( ev ){ + ev.stopPropagation(); $( ev.currentTarget ).toggleClass( 'selected' ); }, + /** deselect all pairs */ + clearSelectedPaired : function( ev ){ + this.$( '.paired-columns .dataset.selected' ).removeClass( 'selected' ); + }, + /** rename a pair when the pair name is clicked */ _clickPairName : function( ev ){ ev.stopPropagation(); @@ -1255,6 +1320,94 @@ this._unpair( this.paired[ pairIndex ] ); }, + // ........................................................................ paired - drag and drop re-ordering + //_dragenterPairedColumns : function( ev ){ + // console.debug( '_dragenterPairedColumns:', ev ); + //}, + //_dragleavePairedColumns : function( ev ){ + // //console.debug( '_dragleavePairedColumns:', ev ); + //}, + /** track the mouse drag over the paired list adding a placeholder to show where the drop would occur */ + _dragoverPairedColumns : function( ev ){ + //console.debug( '_dragoverPairedColumns:', ev ); + ev.preventDefault(); + + var $list = this.$( '.paired-columns .column-datasets' ), + offset = $list.offset(); + //console.debug( ev.originalEvent.clientX, ev.originalEvent.clientY ); + var $nearest = this._getNearestPairedDatasetLi( ev.originalEvent.clientY ); + //console.debug( ev.originalEvent.clientX - offset.left, ev.originalEvent.clientY - offset.top ); + + $( '.paired-drop-placeholder' ).remove(); + var $placeholder = $( '<div class="paired-drop-placeholder"></div>') + if( !$nearest.size() ){ + $list.append( $placeholder ); + } else { + $nearest.before( $placeholder ); + } + }, + /** get the nearest *previous* paired dataset PairView based on the mouse's Y coordinate. + * If the y is at the end of the list, return an empty jQuery object. + */ + _getNearestPairedDatasetLi : function( y ){ + var WIGGLE = 4, + lis = this.$( '.paired-columns .column-datasets li' ).toArray(); +//TODO: better way? + for( var i=0; i<lis.length; i++ ){ + var $li = $( lis[i] ), + top = $li.offset().top, + halfHeight = Math.floor( $li.outerHeight() / 2 ) + WIGGLE; + if( top + halfHeight > y && top - halfHeight < y ){ + //console.debug( y, top + halfHeight, top - halfHeight ) + return $li; + } + } + return $(); + }, + /** drop (dragged/selected PairViews) onto the list, re-ordering both the DOM and the internal array of pairs */ + _dropPairedColumns : function( ev ){ + // both required for firefox + ev.preventDefault(); + ev.dataTransfer.dropEffect = 'move'; + + var $nearest = this._getNearestPairedDatasetLi( ev.originalEvent.clientY ); + if( $nearest.size() ){ + this.$dragging.insertBefore( $nearest ); + + } else { + // no nearest before - insert after last element (unpair button) + this.$dragging.insertAfter( this.$( '.paired-columns .unpair-btn' ).last() ); + } + // resync the creator's list of paired based on the new DOM order + this._syncPairsToDom(); + return false; + }, + /** resync the creator's list of paired based on the DOM order of pairs */ + _syncPairsToDom : function(){ + var newPaired = []; +//TODO: ugh + this.$( '.paired-columns .dataset.paired' ).each( function(){ + newPaired.push( $( this ).data( 'pair' ) ); + }); + //console.debug( newPaired ); + this.paired = newPaired; + this._renderPaired(); + }, + /** drag communication with pair sub-views: dragstart */ + _pairDragstart : function( ev, pair ){ + //console.debug( '_pairDragstart', ev, pair ) + // auto select the pair causing the event and move all selected + pair.$el.addClass( 'selected' ); + var $selected = this.$( '.paired-columns .dataset.selected' ); + this.$dragging = $selected; + }, + /** drag communication with pair sub-views: dragend - remove the placeholder */ + _pairDragend : function( ev, pair ){ + //console.debug( '_pairDragend', ev, pair ) + $( '.paired-drop-placeholder' ).remove(); + this.$dragging = null; + }, + // ........................................................................ footer toggleExtensions : function( force ){ var creator = this; diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/mvc/tools/tools-form.js --- a/static/scripts/mvc/tools/tools-form.js +++ b/static/scripts/mvc/tools/tools-form.js @@ -1,8 +1,8 @@ define(['mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'mvc/citation/citation-model', 'mvc/citation/citation-view', - 'mvc/tools', 'mvc/tools/tools-template', 'mvc/tools/tools-datasets', 'mvc/tools/tools-section'], + 'mvc/tools', 'mvc/tools/tools-template', 'mvc/tools/tools-datasets', 'mvc/tools/tools-section', 'mvc/tools/tools-tree'], function(Portlet, Ui, CitationModel, CitationView, - Tools, ToolTemplate, ToolDatasets, ToolSection) { + Tools, ToolTemplate, ToolDatasets, ToolSection, ToolTree) { // create tool model var Model = Backbone.Model.extend({ @@ -29,6 +29,18 @@ id : options.id }); + // creates a tree/json structure from the input form + this.tree = new ToolTree(this); + + // reset field list + this.field_list = {}; + + // reset sequential input definition list + this.input_list = {}; + + // create data model + this.data = new Backbone.Model(); + // initialize datasets this.datasets = new ToolDatasets({ success: function() { @@ -39,13 +51,6 @@ // initialize tool form _initializeToolForm: function() { - - // reset field list - this.field_list = {}; - - // reset sequential input definition list - this.inputs_sequential = {}; - // fetch model and render form var self = this; this.model.fetch({ @@ -67,6 +72,7 @@ title : 'Execute', floating : 'clear', onclick : function() { + console.log(self.tree.create(self)); } }) } @@ -107,8 +113,25 @@ // append tool section self.portlet.append(self.section.$el); + + // trigger refresh + self.refresh(); } }); + }, + + // refresh + refresh: function() { + // recreate tree structure + this.tree.refresh(); + + // trigger change + for (var id in this.field_list) { + this.field_list[id].trigger('change'); + } + + // log + console.debug('tools-form::refresh() - Recreated tree structure. Refresh.'); } }); diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/mvc/tools/tools-section.js --- a/static/scripts/mvc/tools/tools-section.js +++ b/static/scripts/mvc/tools/tools-section.js @@ -1,4 +1,5 @@ -define(['mvc/ui/ui-table', 'mvc/ui/ui-misc', 'mvc/ui/ui-tabs'], function(Table, Ui, Tabs) { +define(['utils/utils', 'mvc/ui/ui-table', 'mvc/ui/ui-misc', 'mvc/ui/ui-tabs'], + function(Utils, Table, Ui, Tabs) { // create form view var View = Backbone.View.extend({ @@ -13,6 +14,13 @@ // link datasets this.datasets = app.datasets; + // link data model + this.data = app.data; + + // add table class for tr tag + // this assist in transforming the form into a json structure + options.cls_tr = 'form-row'; + // create table this.table = new Table.View(options); @@ -28,98 +36,155 @@ // reset table this.table.delAll(); - // model - var data = new Backbone.Model(); - // load settings elements into table - for (var id in this.inputs) { - this._add(this.inputs[id], data); - } - - // trigger change - for (var id in this.app.field_list) { - this.app.field_list[id].trigger('change'); + for (var i in this.inputs) { + this._add(this.inputs[i], this.data); } }, // add table row - _add: function(inputs_def, data) { + _add: function(input, data) { // link this var self = this; + // clone definition + var input_def = jQuery.extend(true, {}, input); + + // create unique id + input_def.id = Utils.uuid(); + + // add to sequential list of inputs + this.app.input_list[input_def.id] = input_def; + // identify field type - var type = inputs_def.type; + var type = input_def.type; switch(type) { // conditional field case 'conditional': - // add label to input definition root - inputs_def.label = inputs_def.test_param.label; - - // add id to input definition root - inputs_def.name = inputs_def.test_param.name; - - // build options field - this._addRow('conditional', inputs_def, data); - - // add fields - for (var i in inputs_def.cases) { - // create sub section - var sub_section = new View(this.app, { - inputs : inputs_def.cases[i].inputs, - cls : 'ui-table-plain' - }); - - // append sub section - this.table.add(''); - this.table.add(sub_section.$el); - this.table.append(inputs_def.name + '_formsection_' + i); - } + this._addConditional(input_def, data); break; // repeat block case 'repeat': - // create tab field - var tabs = new Tabs.View({ - title_new : 'Add Group', - onnew : function() { - // create sub section - var sub_section = new View(self.app, { - inputs : inputs_def.inputs, - cls : 'ui-table-plain' - }); + this._addRepeat(input_def); + break; + // default single element row + default: + this._addRow(type, input_def, data); + } + }, + + // add conditional block + _addConditional: function(input_def, data) { + // add label to input definition root + input_def.label = input_def.test_param.label; + + // add value to input definition root + input_def.value = input_def.test_param.value; + + // build options field + this._addRow('conditional', input_def, data); + + // add fields + for (var i in input_def.cases) { + // create id tag + var sub_section_id = input_def.id + '-section-' + i; + + // create sub section + var sub_section = new View(this.app, { + inputs : input_def.cases[i].inputs, + cls : 'ui-table-plain' + }); + + // append sub section + this.table.add(''); + this.table.add(sub_section.$el); + this.table.append(sub_section_id); + } + }, + + // add repeat block + _addRepeat: function(input_def) { + // link this + var self = this; + + // + // create tab field + // + var tabs = new Tabs.View({ + title_new : 'Add ' + input_def.title, + max : input_def.max, + onnew : function() { + // create id tag + var sub_section_id = input_def.id + '-section-' + Utils.uuid(); + + // create sub section + var sub_section = new View(self.app, { + inputs : input_def.inputs, + cls : 'ui-table-plain' + }); + + // add new tab + tabs.add({ + id : sub_section_id, + title : input_def.title, + $el : sub_section.$el, + ondel : function() { + // delete tab + tabs.del(sub_section_id); - // create id tag - var sub_section_id = inputs_def.name + '_formsection_' + tabs.size(); - - // add new tab - tabs.add({ - id : sub_section_id, - title : 'Repeat', - $el : sub_section.$el, - ondel : function() { - tabs.del(sub_section_id); - } - }); + // retitle tabs + tabs.retitle(input_def.title); - // show tab - tabs.show(sub_section_id); + // trigger refresh + self.app.refresh(); } }); - // append sub section - this.table.add(inputs_def.title); - this.table.add(tabs.$el); - this.table.append(inputs_def.name); - break; - // default single element row - default: - this._addRow(type, inputs_def, data); + // retitle tabs + tabs.retitle(input_def.title); + + // show tab + tabs.show(sub_section_id); + + // trigger refresh + self.app.refresh(); + } + }); + + // + // add min number of tabs + // + for (var i = 0; i < input_def.min; i++) { + // create id tag + var sub_section_id = input_def.id + '-section-' + Utils.uuid(); + + // create sub section + var sub_section = new View(self.app, { + inputs : input_def.inputs, + cls : 'ui-table-plain' + }); + + // add tab + tabs.add({ + id : sub_section_id, + title : input_def.title, + $el : sub_section.$el + }); } + + // retitle tabs + tabs.retitle(input_def.title); + + // append sub section + this.table.add(''); + this.table.add(tabs.$el); + this.table.append(input_def.id); }, // add table row - _addRow: function(field_type, inputs_def, data) { + _addRow: function(field_type, input_def, data) { // get id - var id = inputs_def.name; + var id = input_def.id; // field wrapper var field = null; @@ -128,37 +193,42 @@ switch(field_type) { // text input field case 'text' : - field = this._field_text(inputs_def, data); + field = this._field_text(input_def, data); break; // select field case 'select' : - field = this._field_select(inputs_def, data); + field = this._field_select(input_def, data); break; // radiobox field case 'radiobutton' : - field = this._field_radio(inputs_def, data); + field = this._field_radio(input_def, data); break; // dataset case 'data': - field = this._field_data(inputs_def, data); + field = this._field_data(input_def, data); break; // dataset column case 'data_column': - field = this._field_column(inputs_def, data); + field = this._field_column(input_def, data); break; // text area field case 'textarea' : - field = this._field_textarea(inputs_def, data); + field = this._field_textarea(input_def, data); break; // conditional select field case 'conditional': - field = this._field_conditional(inputs_def, data); + field = this._field_conditional(input_def, data); + break; + + // hidden field + case 'hidden': + field = this._field_hidden(input_def, data); break; } @@ -170,68 +240,37 @@ // set value if (!data.get(id)) { - data.set(id, inputs_def.value); + data.set(id, input_def.value); } field.value(data.get(id)); // add to field list this.app.field_list[id] = field; - // add to input definition into sequential list - this.app.inputs_sequential[id] = inputs_def; - // combine field and info var $input = $('<div/>'); $input.append(field.$el); - if (inputs_def.help) { - $input.append('<div class="ui-table-form-info">' + inputs_def.help + '</div>'); + if (input_def.help) { + $input.append('<div class="ui-table-form-info">' + input_def.help + '</div>'); } - // add row to table - this.table.add('<span class="ui-table-form-title">' + inputs_def.label + '</span>', '25%'); + // create table row + this.table.add('<span class="ui-table-form-title">' + input_def.label + '</span>', '20%'); this.table.add($input); - // add to table + // append to table this.table.append(id); - - // show/hide - if (inputs_def.hide) { - this.table.get(id).hide(); - } - }, - - // text input field - _field_text : function(inputs_def, data) { - var id = inputs_def.name; - return new Ui.Input({ - id : 'field-' + id, - value : data.get(id), - onchange : function(value) { - data.set(id, value); - } - }); - }, - - // text area - _field_textarea : function(inputs_def, data) { - var id = inputs_def.name; - return new Ui.Textarea({ - id : 'field-' + id, - onchange : function() { - data.set(id, field.value()); - } - }); }, // conditional input field - _field_conditional : function(inputs_def, data) { + _field_conditional : function(input_def, data) { // link this var self = this; // configure options fields var options = []; - for (var i in inputs_def.test_param.options) { - var option = inputs_def.test_param.options[i]; + for (var i in input_def.test_param.options) { + var option = input_def.test_param.options[i]; options.push({ label: option[0], value: option[1] @@ -239,7 +278,7 @@ } // select field - var id = inputs_def.name; + var id = input_def.id; return new Ui.Select.View({ id : 'field-' + id, data : options, @@ -249,19 +288,29 @@ data.set(id, value); // check value in order to hide/show options - for (var i in inputs_def.cases) { + for (var i in input_def.cases) { // get case - var case_def = inputs_def.cases[i]; + var case_def = input_def.cases[i]; // identify subsection name - var section_id = inputs_def.name + '_formsection_' + i; - + var section_id = input_def.id + '-section-' + i; + // identify row var section_row = self.table.get(section_id); - // check - if (case_def.value == value) { - section_row.show(); + // check if non-hidden elements exist + var nonhidden = false; + for (var j in case_def.inputs) { + var type = case_def.inputs[j].type; + if (type && type !== 'hidden') { + nonhidden = true; + break; + } + } + + // show/hide sub form + if (case_def.value == value && nonhidden) { + section_row.fadeIn('fast'); } else { section_row.hide(); } @@ -271,12 +320,12 @@ }, // data input field - _field_data : function(inputs_def, data) { + _field_data : function(input_def, data) { // link this var self = this; // get element id - var id = inputs_def.name; + var id = input_def.id; // get datasets var datasets = this.datasets.filterType(); @@ -299,11 +348,8 @@ // update value data.set(id, value); - // find referenced columns - var column_list = _.where(self.app.inputs_sequential, { - data_ref : id, - type : 'data_column' - }); + // get referenced columns + var column_list = self.app.tree.findReferences(id); // find selected dataset var dataset = self.datasets.filter(value); @@ -333,10 +379,12 @@ // update referenced columns for (var i in column_list) { - var column_field = self.app.field_list[column_list[i].name] + var column_field = self.app.field_list[column_list[i]] if (column_field) { column_field.update(columns); - column_field.value(column_field.first()); + if (!column_field.exists(column_field.value())) { + column_field.value(column_field.first()); + } } } } else { @@ -348,8 +396,8 @@ }, // column selection field - _field_column : function (inputs_def, data) { - var id = inputs_def.name; + _field_column : function (input_def, data) { + var id = input_def.id; return new Ui.Select.View({ id : 'field-' + id, value : data.get(id), @@ -360,11 +408,11 @@ }, // select field - _field_select : function (inputs_def, data) { + _field_select : function (input_def, data) { // configure options fields var options = []; - for (var i in inputs_def.options) { - var option = inputs_def.options[i]; + for (var i in input_def.options) { + var option = input_def.options[i]; options.push({ label: option[0], value: option[1] @@ -373,12 +421,12 @@ // identify display type var SelectClass = Ui.Select; - if (inputs_def.display == 'checkboxes') { + if (input_def.display == 'checkboxes') { SelectClass = Ui.Checkbox; } // select field - var id = inputs_def.name; + var id = input_def.id; return new SelectClass.View({ id : 'field-' + id, data : options, @@ -389,17 +437,49 @@ }); }, - // radio field - _field_radio : function(inputs_def, data) { - var id = inputs_def.name; - return new Ui.RadioButton({ + // text input field + _field_text : function(input_def, data) { + var id = input_def.id; + return new Ui.Input({ id : 'field-' + id, - data : inputs_def.data, value : data.get(id), onchange : function(value) { data.set(id, value); } }); + }, + + // text area + _field_textarea : function(input_def, data) { + var id = input_def.id; + return new Ui.Textarea({ + id : 'field-' + id, + onchange : function() { + data.set(id, field.value()); + } + }); + }, + + // radio field + _field_radio : function(input_def, data) { + var id = input_def.id; + return new Ui.RadioButton({ + id : 'field-' + id, + data : input_def.data, + value : data.get(id), + onchange : function(value) { + data.set(id, value); + } + }); + }, + + // hidden field + _field_hidden : function(input_def, data) { + var id = input_def.id; + return new Ui.Hidden({ + id : 'field-' + id, + value : data.get(id) + }); } }); diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/mvc/tools/tools-tree.js --- /dev/null +++ b/static/scripts/mvc/tools/tools-tree.js @@ -0,0 +1,142 @@ +// dependencies +define([], function() { + +// tool form tree +return Backbone.Model.extend({ + // initialize + initialize: function(app) { + // link app + this.app = app; + }, + + // creates tree structure + refresh: function() { + // check if section is available + if (!this.app.section) { + return {}; + } + + // create dictionary + this.dict = {}; + + // create xml object + this.xml = $('<div/>'); + + // fill dictionary + this._iterate(this.app.section.$el, this.dict, this.xml); + }, + + // iterate + _iterate: function(parent, dict, xml) { + // get child nodes + var self = this; + var children = $(parent).children(); + children.each(function() { + // get child element + var child = this; + + // get id + var id = $(child).attr('id'); + + // create new branch + if ($(child).hasClass('form-row') || $(child).hasClass('tab-pane')) { + // create sub dictionary + dict[id] = {}; + + // add input element if it exists + var input = self.app.input_list[id]; + if (input) { + dict[id] = { + input : input + } + } + + // create xml element + var $el = $('<div id="' + id + '"/>'); + + // append xml + xml.append($el); + + // fill sub dictionary + self._iterate(child, dict[id], $el); + } else { + self._iterate(child, dict, xml); + } + }); + }, + + // find referenced elements + findReferences: function(identifier) { + // referenced elements + var referenced = []; + + // link this + var self = this; + + // iterate + function search (name, parent) { + // get child nodes + var children = $(parent).children(); + + // create list of referenced elements + var list = []; + + // a node level is skipped if a reference of higher priority was found + var skip = false; + + // verify that hierarchy level is referenced by target identifier + children.each(function() { + // get child element + var child = this; + + // get id + var id = $(child).attr('id'); + + // skip target element + if (id !== identifier) { + // get input element + var input = self.app.input_list[id]; + if (input) { + // check for new reference definition with higher priority + if (input.name == name) { + // skip iteration for this branch + skip = true; + return false; + } + + // check for referenced element + if (input.data_ref == name) { + list.push(id); + } + } + } + }); + + // skip iteration + if (!skip) { + // merge temporary list with result + referenced = referenced.concat(list); + + // continue iteration + children.each(function() { + search(name, this); + }); + } + } + + // get initial node + var node = this.xml.find('#' + identifier); + if (node.length > 0) { + // get parent input element + var input = this.app.input_list[identifier]; + if (input) { + search(input.name, node.parent()); + } + } + + // return + return referenced; + } +}); + +}); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/mvc/ui.js --- a/static/scripts/mvc/ui.js +++ b/static/scripts/mvc/ui.js @@ -574,6 +574,8 @@ self.show = function( msg, speed, callback ){ msg = msg || 'loading...'; speed = speed || 'fast'; + // remove previous + $where.parent().find( '.loading-indicator' ).remove(); // since position is fixed - we insert as sibling self.$indicator = render().insertBefore( $where ); self.message( msg ); diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/mvc/ui/ui-misc.js --- a/static/scripts/mvc/ui/ui-misc.js +++ b/static/scripts/mvc/ui/ui-misc.js @@ -409,6 +409,35 @@ } }); +// plugin +var Hidden = Backbone.View.extend({ + // options + optionsDefault: { + value : '' + }, + + // initialize + initialize : function(options) { + // configure options + this.options = Utils.merge(options, this.optionsDefault); + + // create new element + this.setElement(this._template(this.options)); + }, + + // value + value : function (new_val) { + if (new_val !== undefined) { + this.$el.val(new_val); + } + return this.$el.val(); + }, + + // element + _template: function(options) { + return '<hidden id="' + options.id + '" value="' + options.value + '"/>'; + } +}); // return return { @@ -426,6 +455,7 @@ Checkbox : Checkbox, Searchbox : Searchbox, Select : Select, - Textarea : Textarea + Textarea : Textarea, + Hidden : Hidden } }); diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/mvc/ui/ui-table.js --- a/static/scripts/mvc/ui/ui-table.js +++ b/static/scripts/mvc/ui/ui-table.js @@ -17,7 +17,8 @@ onchange : null, ondblclick : null, onconfirm : null, - cls : 'ui-table' + cls : 'ui-table', + cls_tr : '' }, // events @@ -43,7 +44,7 @@ this.setElement($el); // initialize row - this.row = $('<tr></tr>'); + this.row = this._row(); }, // add header cell @@ -156,13 +157,18 @@ } // row - this.row = $('<tr></tr>'); + this.row = this._row(); // row count this.row_count++; this._refresh(); }, + // create new row + _row: function() { + return $('<tr class="' + this.options.cls_tr + '"></tr>'); + }, + // onclick _onclick: function(e) { // get values diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/mvc/ui/ui-tabs.js --- a/static/scripts/mvc/ui/ui-tabs.js +++ b/static/scripts/mvc/ui/ui-tabs.js @@ -7,7 +7,9 @@ optionsDefault: { title_new : '', operations : null, - onnew : null + onnew : null, + min : null, + max : null }, // initialize @@ -96,12 +98,17 @@ this.$content.append($tab_content); // activate this tab if this is the first tab - if (_.size(this.list) == 1) { + if (this.size() == 1) { $tab_title.addClass('active'); $tab_content.addClass('active'); this.first_tab = id; } + // hide add tab + if (this.options.max && this.size() >= this.options.max) { + this.$el.find('#new-tab').hide(); + } + // add click event to remove tab if (options.ondel) { var $del_icon = $tab_title.find('#delete'); @@ -132,7 +139,7 @@ del: function(id) { // delete tab from dom this.$el.find('#tab-' + id).remove(); - this.$el.find('#tab-content-' + id).remove(); + this.$el.find('#' + id).remove(); // check if first tab has been deleted if (this.first_tab == id) { @@ -143,14 +150,22 @@ if (this.first_tab != null) { this.show(this.first_tab); } + + // delete from list + if (this.list[id]) { + delete this.list[id]; + } + + // show add tab + if (this.size() < this.options.max) { + this.$el.find('#new-tab').show(); + } }, // delete tab delRemovable: function() { for (var id in this.list) { - if (this.list[id]) { - this.del(id); - } + this.del(id); } }, @@ -165,7 +180,7 @@ this.$el.find('.tab-element').removeClass('active'); this.$el.find('.tab-pane').removeClass('active'); this.$el.find('#tab-' + id).addClass('active'); - this.$el.find('#tab-content-' + id).addClass('active'); + this.$el.find('#' + id).addClass('active'); } }, @@ -201,6 +216,14 @@ return $el.html(); }, + // retitle + retitle: function(new_title) { + var index = 0; + for (var id in this.list) { + this.title(id, ++index + ': ' + new_title); + } + }, + // fill template _template: function(options) { return '<div class="ui-tabs tabbable tabs-left">' + @@ -224,8 +247,8 @@ // fill template tab _template_tab: function(options) { var tmpl = '<li id="tab-' + options.id + '" class="tab-element">' + - '<a id="tab-title-link-' + options.id + '" title="" href="#tab-content-' + options.id + '" data-original-title="">' + - '<span id="tab-title-text-' + options.id + '">' + options.title + '</span>'; + '<a id="tab-title-link-' + options.id + '" title="" href="#' + options.id + '" data-original-title="">' + + '<span id="tab-title-text-' + options.id + '" class="tab-title-text">' + options.title + '</span>'; if (options.ondel) { tmpl += '<i id="delete" class="ui-tabs-delete fa fa-minus-circle"/>'; @@ -239,7 +262,7 @@ // fill template tab content _template_tab_content: function(options) { - return '<div id="tab-content-' + options.id + '" class="tab-pane"/>'; + return '<div id="' + options.id + '" class="tab-pane"/>'; } }); diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/packed/mvc/collection/paired-collection-creator.js --- a/static/scripts/packed/mvc/collection/paired-collection-creator.js +++ b/static/scripts/packed/mvc/collection/paired-collection-creator.js @@ -1,1 +1,1 @@ -define(["utils/levenshtein","mvc/base-mvc","utils/localization"],function(g,a,d){var f=Backbone.View.extend(a.LoggableMixin).extend({tagName:"li",className:"dataset paired",initialize:function(h){this.pair=h.pair||{}},render:function(){this.$el.attr("draggable",true).html(_.template(['<span class="forward-dataset-name flex-column"><%= pair.forward.name %></span>','<span class="pair-name-column flex-column">','<span class="pair-name"><%= pair.name %></span>',"</span>",'<span class="reverse-dataset-name flex-column"><%= pair.reverse.name %></span>'].join(""),{pair:this.pair})).addClass("flex-column-container");return this}});var e=Backbone.View.extend(a.LoggableMixin).extend({className:"collection-creator flex-row-container",initialize:function(h){h=_.defaults(h,{datasets:[],filters:this.DEFAULT_FILTERS,automaticallyPair:true,matchPercentage:1,strategy:"lcs"});this.initialList=h.datasets;this.historyId=h.historyId;this.filters=this.commonFilters[h.filters]||this.commonFilters[this.DEFAULT_FILTERS];if(_.isArray(h.filters)){this.filters=h.filters}this.automaticallyPair=h.automaticallyPair;this.matchPercentage=h.matchPercentage;this.strategy=this.strategies[h.strategy]||this.strategies[this.DEFAULT_STRATEGY];if(_.isFunction(h.strategy)){this.strategy=h.strategy}this.removeExtensions=true;this.oncancel=h.oncancel;this.oncreate=h.oncreate;this.unpairedPanelHidden=false;this.pairedPanelHidden=false;this._dataSetUp();this._setUpBehaviors()},commonFilters:{none:["",""],illumina:["_1","_2"]},DEFAULT_FILTERS:"illumina",strategies:{lcs:"autoPairLCSs",levenshtein:"autoPairLevenshtein"},DEFAULT_STRATEGY:"lcs",_dataSetUp:function(){this.paired=[];this.unpaired=[];this.selectedIds=[];this._sortInitialList();this._ensureIds();this.unpaired=this.initialList.slice(0);if(this.automaticallyPair){this.autoPair()}},_sortInitialList:function(){this._sortDatasetList(this.initialList)},_sortDatasetList:function(h){h.sort(function(j,i){return naturalSort(j.name,i.name)});return h},_ensureIds:function(){this.initialList.forEach(function(h){if(!h.hasOwnProperty("id")){h.id=_.uniqueId()}});return this.initialList},_splitByFilters:function(j){var i=[],h=[];this.unpaired.forEach(function(k){if(this._filterFwdFn(k)){i.push(k)}if(this._filterRevFn(k)){h.push(k)}}.bind(this));return[i,h]},_filterFwdFn:function(i){var h=new RegExp(this.filters[0]);return h.test(i.name)},_filterRevFn:function(i){var h=new RegExp(this.filters[1]);return h.test(i.name)},_addToUnpaired:function(i){var h=function(j,l){if(j===l){return j}var k=Math.floor((l-j)/2)+j,m=naturalSort(i.name,this.unpaired[k].name);if(m<0){return h(j,k)}else{if(m>0){return h(k+1,l)}}while(this.unpaired[k]&&this.unpaired[k].name===i.name){k++}return k}.bind(this);this.unpaired.splice(h(0,this.unpaired.length),0,i)},autoPair:function(h){h=h||this.strategy;this.simpleAutoPair();return this[h].call(this)},simpleAutoPair:function(){var n=0,l,r=this._splitByFilters(),h=r[0],q=r[1],p,s,k=false;while(n<h.length){var m=h[n];p=m.name.replace(this.filters[0],"");k=false;for(l=0;l<q.length;l++){var o=q[l];s=o.name.replace(this.filters[1],"");if(m!==o&&p===s){k=true;this._pair(h.splice(n,1)[0],q.splice(l,1)[0],{silent:true});break}}if(!k){n+=1}}},autoPairLevenshtein:function(){var o=0,m,t=this._splitByFilters(),h=t[0],r=t[1],q,v,k,s,l;while(o<h.length){var n=h[o];q=n.name.replace(this.filters[0],"");l=Number.MAX_VALUE;for(m=0;m<r.length;m++){var p=r[m];v=p.name.replace(this.filters[1],"");if(n!==p){if(q===v){s=m;l=0;break}k=levenshteinDistance(q,v);if(k<l){s=m;l=k}}}var u=1-(l/(Math.max(q.length,v.length)));if(u>=this.matchPercentage){this._pair(h.splice(o,1)[0],r.splice(s,1)[0],{silent:true});if(h.length<=0||r.length<=0){return}}else{o+=1}}},autoPairLCSs:function(){var m=0,k,t=this._splitByFilters(),h=t[0],r=t[1],q,w,v,s,o;if(!h.length||!r.length){return}while(m<h.length){var l=h[m];q=l.name.replace(this.filters[0],"");o=0;for(k=0;k<r.length;k++){var p=r[k];w=p.name.replace(this.filters[1],"");if(l!==p){if(q===w){s=k;o=q.length;break}var n=this._naiveStartingAndEndingLCS(q,w);v=n.length;if(v>o){s=k;o=v}}}var u=o/(Math.min(q.length,w.length));if(u>=this.matchPercentage){this._pair(h.splice(m,1)[0],r.splice(s,1)[0],{silent:true});if(h.length<=0||r.length<=0){return}}else{m+=1}}},_naiveStartingAndEndingLCS:function(m,k){var n="",o="",l=0,h=0;while(l<m.length&&l<k.length){if(m[l]!==k[l]){break}n+=m[l];l+=1}if(l===m.length){return m}if(l===k.length){return k}l=(m.length-1);h=(k.length-1);while(l>=0&&h>=0){if(m[l]!==k[h]){break}o=[m[l],o].join("");l-=1;h-=1}return n+o},_pair:function(j,h,i){i=i||{};var k=this._createPair(j,h,i.name);this.paired.push(k);this.unpaired=_.without(this.unpaired,j,h);if(!i.silent){this.trigger("pair:new",k)}return k},_createPair:function(j,h,i){if(!(j&&h)||(j===h)){throw new Error("Bad pairing: "+[JSON.stringify(j),JSON.stringify(h)])}i=i||this._guessNameForPair(j,h);return{forward:j,name:i,reverse:h}},_guessNameForPair:function(j,h,k){k=(k!==undefined)?(k):(this.removeExtensions);var i=this._naiveStartingAndEndingLCS(j.name.replace(this.filters[0],""),h.name.replace(this.filters[1],""));if(k){var l=i.lastIndexOf(".");if(l>0){i=i.slice(0,l)}}return i||(j.name+" & "+h.name)},_unpair:function(i,h){h=h||{};if(!i){throw new Error("Bad pair: "+JSON.stringify(i))}this.paired=_.without(this.paired,i);this._addToUnpaired(i.forward);this._addToUnpaired(i.reverse);if(!h.silent){this.trigger("pair:unpair",[i])}return i},unpairAll:function(){var h=[];while(this.paired.length){h.push(this._unpair(this.paired[0],{silent:true}))}this.trigger("pair:unpair",h)},_pairToJSON:function(h){return{collection_type:"paired",src:"new_collection",name:h.name,element_identifiers:[{name:"forward",id:h.forward.id,src:"hda"},{name:"reverse",id:h.reverse.id,src:"hda"}]}},createList:function(){var j=this,i;if(j.historyId){i="/api/histories/"+this.historyId+"/contents/dataset_collections"}var h={type:"dataset_collection",collection_type:"list:paired",name:_.escape(j.$(".collection-name").val()),element_identifiers:j.paired.map(function(k){return j._pairToJSON(k)})};return jQuery.ajax(i,{type:"POST",contentType:"application/json",dataType:"json",data:JSON.stringify(h)}).fail(function(m,k,l){j._ajaxErrHandler(m,k,l)}).done(function(k,l,m){j.trigger("collection:created",k,l,m);if(typeof j.oncreate==="function"){j.oncreate.call(this,k,l,m)}})},_ajaxErrHandler:function(k,h,j){this.error(k,h,j);var i=d("An error occurred while creating this collection");if(k){if(k.readyState===0&&k.status===0){i+=": "+d("Galaxy could not be reached and may be updating.")+d(" Try again in a few minutes.")}else{if(k.responseJSON){i+="<br /><pre>"+JSON.stringify(k.responseJSON)+"</pre>"}else{i+=": "+j}}}creator._showAlert(i,"alert-danger")},render:function(h,i){this.$el.empty().html(e.templates.main());this._renderHeader(h);this._renderMiddle(h);this._renderFooter(h);this._addPluginComponents();return this},_renderHeader:function(i,j){var h=this.$(".header").empty().html(e.templates.header()).find(".help-content").prepend($(e.templates.helpContent()));this._renderFilters();return h},_renderFilters:function(){return this.$(".forward-column .column-header input").val(this.filters[0]).add(this.$(".reverse-column .column-header input").val(this.filters[1]))},_renderMiddle:function(i,j){var h=this.$(".middle").empty().html(e.templates.middle());if(this.unpairedPanelHidden){this.$(".unpaired-columns").hide()}else{if(this.pairedPanelHidden){this.$(".paired-columns").hide()}}this._renderUnpaired();this._renderPaired();return h},_renderUnpaired:function(m,n){var k=this,l,i,h=[],j=this._splitByFilters();this.$(".forward-column .title").text([j[0].length,d("unpaired forward")].join(" "));this.$(".forward-column .unpaired-info").text(this._renderUnpairedDisplayStr(this.unpaired.length-j[0].length));this.$(".reverse-column .title").text([j[1].length,d("unpaired reverse")].join(" "));this.$(".reverse-column .unpaired-info").text(this._renderUnpairedDisplayStr(this.unpaired.length-j[1].length));this.$(".unpaired-columns .column-datasets").empty();this.$(".autopair-link").toggle(this.unpaired.length!==0);if(this.unpaired.length===0){this._renderUnpairedEmpty();return}i=j[1].map(function(p,o){if((j[0][o]!==undefined)&&(j[0][o]!==p)){h.push(k._renderPairButton())}return k._renderUnpairedDataset(p)});l=j[0].map(function(o){return k._renderUnpairedDataset(o)});if(!l.length&&!i.length){this._renderUnpairedNotShown();return}this.$(".unpaired-columns .forward-column .column-datasets").append(l).add(this.$(".unpaired-columns .paired-column .column-datasets").append(h)).add(this.$(".unpaired-columns .reverse-column .column-datasets").append(i));this._adjUnpairedOnScrollbar()},_renderUnpairedDisplayStr:function(h){return["(",h," ",d("filtered out"),")"].join("")},_renderUnpairedDataset:function(h){return $("<li/>").attr("id","dataset-"+h.id).addClass("dataset unpaired").attr("draggable",true).addClass(h.selected?"selected":"").append($("<span/>").addClass("dataset-name").text(h.name)).data("dataset",h)},_renderPairButton:function(){return $("<li/>").addClass("dataset unpaired").append($("<span/>").addClass("dataset-name").text(d("Pair these datasets")))},_renderUnpairedEmpty:function(){var h=$('<div class="empty-message"></div>').text("("+d("no remaining unpaired datasets")+")");this.$(".unpaired-columns .paired-column .column-datasets").empty().prepend(h);return h},_renderUnpairedNotShown:function(){var h=$('<div class="empty-message"></div>').text("("+d("no datasets were found matching the current filters")+")");this.$(".unpaired-columns .paired-column .column-datasets").empty().prepend(h);return h},_adjUnpairedOnScrollbar:function(){var k=this.$(".unpaired-columns").last(),l=this.$(".unpaired-columns .reverse-column .dataset").first();if(!l.size()){return}var h=k.offset().left+k.outerWidth(),j=l.offset().left+l.outerWidth(),i=Math.floor(h)-Math.floor(j);this.$(".unpaired-columns .forward-column").css("margin-left",(i>0)?i:0)},_renderPaired:function(i,j){this.$(".paired-column-title .title").text([this.paired.length,d("paired")].join(" "));this.$(".unpair-all-link").toggle(this.paired.length!==0);if(this.paired.length===0){this._renderPairedEmpty();return}else{this.$(".remove-extensions-link").show()}this.$(".paired-columns .column-datasets").empty();var h=this;this.paired.forEach(function(m,k){var l=new f({pair:m});h.$(".paired-columns .column-datasets").append(l.render().$el).append(['<button class="unpair-btn">','<span class="fa fa-unlink" title="',d("Unpair"),'"></span>',"</button>"].join(""))})},_renderPairedEmpty:function(){var h=$('<div class="empty-message"></div>').text("("+d("no paired datasets yet")+")");this.$(".paired-columns .column-datasets").empty().prepend(h);return h},_renderFooter:function(i,j){var h=this.$(".footer").empty().html(e.templates.footer());this.$(".remove-extensions").prop("checked",this.removeExtensions);if(typeof this.oncancel==="function"){this.$(".cancel-create.btn").show()}return h},_addPluginComponents:function(){this._chooseFiltersPopover(".choose-filters-link");this.$(".help-content i").hoverhighlight(".collection-creator","rgba( 64, 255, 255, 1.0 )")},_chooseFiltersPopover:function(h){function i(l,k){return['<button class="filter-choice btn" ','data-forward="',l,'" data-reverse="',k,'">',d("Forward"),": ",l,", ",d("Reverse"),": ",k,"</button>"].join("")}var j=$(_.template(['<div class="choose-filters">','<div class="help">',d("Choose from the following filters to change which unpaired reads are shown in the display"),":</div>",i("_1","_2"),i("_R1","_R2"),"</div>"].join(""),{}));return this.$(h).popover({container:".collection-creator",placement:"bottom",html:true,content:j})},_validationWarning:function(i,h){var j="validation-warning";if(i==="name"){i=this.$(".collection-name").add(this.$(".collection-name-prompt"));this.$(".collection-name").focus().select()}if(h){i=i||this.$("."+j);i.removeClass(j)}else{i.addClass(j)}},_setUpBehaviors:function(){this.on("pair:new",function(){this._renderUnpaired();this._renderPaired();this.$(".paired-columns").scrollTop(8000000)});this.on("pair:unpair",function(h){this._renderUnpaired();this._renderPaired();this.splitView()});this.on("filter-change",function(){this.filters=[this.$(".forward-unpaired-filter input").val(),this.$(".reverse-unpaired-filter input").val()];this._renderFilters();this._renderUnpaired()});this.on("autopair",function(){this._renderUnpaired();this._renderPaired();var h,i=null;if(this.paired.length){i="alert-success";h=this.paired.length+" "+d("pairs created");if(!this.unpaired.length){h+=": "+d("all datasets have been successfully paired");this.hideUnpaired()}}else{h=d("Could not automatically create any pairs from the given dataset names")}this._showAlert(h,i)});return this},events:{"click .more-help":"_clickMoreHelp","click .less-help":"_clickLessHelp","click .header .alert button":"_hideAlert","click .forward-column .column-title":"_clickShowOnlyUnpaired","click .reverse-column .column-title":"_clickShowOnlyUnpaired","click .unpair-all-link":"_clickUnpairAll","change .forward-unpaired-filter input":function(h){this.trigger("filter-change")},"focus .forward-unpaired-filter input":function(h){$(h.currentTarget).select()},"click .autopair-link":"_clickAutopair","click .choose-filters .filter-choice":"_clickFilterChoice","click .clear-filters-link":"_clearFilters","change .reverse-unpaired-filter input":function(h){this.trigger("filter-change")},"focus .reverse-unpaired-filter input":function(h){$(h.currentTarget).select()},"click .forward-column .dataset.unpaired":"_clickUnpairedDataset","click .reverse-column .dataset.unpaired":"_clickUnpairedDataset","click .paired-column .dataset.unpaired":"_clickPairRow","click .unpaired-columns":"clearSelectedUnpaired","mousedown .unpaired-columns .dataset":"_mousedownUnpaired","click .paired-column-title":"_clickShowOnlyPaired","mousedown .flexible-partition-drag":"_startPartitionDrag","click .paired-columns .dataset.paired":"selectPair","click .paired-columns .pair-name":"_clickPairName","click .unpair-btn":"_clickUnpair","change .remove-extensions":function(h){this.toggleExtensions()},"change .collection-name":"_changeName","click .cancel-create":function(h){if(typeof this.oncancel==="function"){this.oncancel.call(this)}},"click .create-collection":"_clickCreate"},_clickMoreHelp:function(h){this.$(".main-help").addClass("expanded");this.$(".more-help").hide()},_clickLessHelp:function(h){this.$(".main-help").removeClass("expanded");this.$(".more-help").show()},_showAlert:function(i,h){h=h||"alert-danger";this.$(".main-help").hide();this.$(".header .alert").attr("class","alert alert-dismissable").addClass(h).show().find(".alert-message").html(i)},_hideAlert:function(h){this.$(".main-help").show();this.$(".header .alert").hide()},_clickShowOnlyUnpaired:function(h){if(this.$(".paired-columns").is(":visible")){this.hidePaired()}else{this.splitView()}},_clickShowOnlyPaired:function(h){if(this.$(".unpaired-columns").is(":visible")){this.hideUnpaired()}else{this.splitView()}},hideUnpaired:function(h,i){this.unpairedPanelHidden=true;this.pairedPanelHidden=false;this._renderMiddle(h,i)},hidePaired:function(h,i){this.unpairedPanelHidden=false;this.pairedPanelHidden=true;this._renderMiddle(h,i)},splitView:function(h,i){this.unpairedPanelHidden=this.pairedPanelHidden=false;this._renderMiddle(h,i);return this},_clickUnpairAll:function(h){this.unpairAll()},_clickAutopair:function(i){var h=this.autoPair();this.trigger("autopair",h)},_clickFilterChoice:function(i){var h=$(i.currentTarget);this.$(".forward-unpaired-filter input").val(h.data("forward"));this.$(".reverse-unpaired-filter input").val(h.data("reverse"));this._hideChooseFilters();this.trigger("filter-change")},_hideChooseFilters:function(){this.$(".choose-filters-link").popover("hide");this.$(".popover").css("display","none")},_clearFilters:function(h){this.$(".forward-unpaired-filter input").val("");this.$(".reverse-unpaired-filter input").val("");this.trigger("filter-change")},_clickUnpairedDataset:function(h){h.stopPropagation();return this.toggleSelectUnpaired($(h.currentTarget))},toggleSelectUnpaired:function(j,i){i=i||{};var k=j.data("dataset"),h=i.force!==undefined?i.force:!j.hasClass("selected");if(!j.size()||k===undefined){return j}if(h){j.addClass("selected");if(!i.waitToPair){this.pairAllSelected()}}else{j.removeClass("selected")}return j},pairAllSelected:function(i){i=i||{};var j=this,k=[],h=[],l=[];j.$(".unpaired-columns .forward-column .dataset.selected").each(function(){k.push($(this).data("dataset"))});j.$(".unpaired-columns .reverse-column .dataset.selected").each(function(){h.push($(this).data("dataset"))});k.length=h.length=Math.min(k.length,h.length);k.forEach(function(n,m){try{l.push(j._pair(n,h[m],{silent:true}))}catch(o){j.error(o)}});if(l.length&&!i.silent){this.trigger("pair:new",l)}return l},clearSelectedUnpaired:function(){this.$(".unpaired-columns .dataset.selected").removeClass("selected")},_mousedownUnpaired:function(j){if(j.shiftKey){var i=this,h=$(j.target).addClass("selected"),k=function(l){i.$(l.target).filter(".dataset").addClass("selected")};h.parent().on("mousemove",k);$(document).one("mouseup",function(l){h.parent().off("mousemove",k);i.pairAllSelected()})}},_clickPairRow:function(j){var k=$(j.currentTarget).index(),i=$(".unpaired-columns .forward-column .dataset").eq(k).data("dataset"),h=$(".unpaired-columns .reverse-column .dataset").eq(k).data("dataset");this._pair(i,h)},_startPartitionDrag:function(i){var h=this,l=i.pageY;$("body").css("cursor","ns-resize");h.$(".flexible-partition-drag").css("color","black");function k(m){h.$(".flexible-partition-drag").css("color","");$("body").css("cursor","").unbind("mousemove",j)}function j(m){var n=m.pageY-l;if(!h.adjPartition(n)){$("body").trigger("mouseup")}h._adjUnpairedOnScrollbar();l+=n}$("body").mousemove(j);$("body").one("mouseup",k)},adjPartition:function(i){var h=this.$(".unpaired-columns"),j=this.$(".paired-columns"),k=parseInt(h.css("height"),10),l=parseInt(j.css("height"),10);k=Math.max(10,k+i);l=l-i;var m=i<0;if(m){if(this.unpairedPanelHidden){return false}else{if(k<=10){this.hideUnpaired();return false}}}else{if(this.unpairedPanelHidden){h.show();this.unpairedPanelHidden=false}}if(!m){if(this.pairedPanelHidden){return false}else{if(l<=15){this.hidePaired();return false}}}else{if(this.pairedPanelHidden){j.show();this.pairedPanelHidden=false}}h.css({height:k+"px",flex:"0 0 auto"});return true},selectPair:function(h){$(h.currentTarget).toggleClass("selected")},_clickPairName:function(j){j.stopPropagation();var i=$(j.currentTarget),k=this.paired[i.parent().index()],h=prompt("Enter a new name for the pair:",k.name);if(h){k.name=h;k.customizedName=true;i.text(k.name)}},_clickUnpair:function(i){var h=Math.floor($(i.currentTarget).index()/2);this._unpair(this.paired[h])},toggleExtensions:function(i){var h=this;h.removeExtensions=(i!==undefined)?(i):(!h.removeExtensions);_.each(h.paired,function(j){if(j.customizedName){return}j.name=h._guessNameForPair(j.forward,j.reverse)});h._renderPaired();h._renderFooter()},_changeName:function(h){this._validationWarning("name",!!this._getName())},_getName:function(){return _.escape(this.$(".collection-name").val())},_clickCreate:function(i){var h=this._getName();if(!h){this._validationWarning("name")}else{this.createList()}},_printList:function(i){var h=this;_.each(i,function(j){if(i===h.paired){h._printPair(j)}else{}})},_printPair:function(h){this.debug(h.forward.name,h.reverse.name,": ->",h.name)},toString:function(){return"PairedCollectionCreator"}});e.templates=e.templates||{main:_.template(['<div class="header flex-row no-flex"></div>','<div class="middle flex-row flex-row-container"></div>','<div class="footer flex-row no-flex">'].join("")),header:_.template(['<div class="main-help well clear">','<a class="more-help" href="javascript:void(0);">',d("More help"),"</a>",'<div class="help-content">','<a class="less-help" href="javascript:void(0);">',d("Less"),"</a>","</div>","</div>",'<div class="alert alert-dismissable">','<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>','<span class="alert-message"></span>',"</div>",'<div class="column-headers vertically-spaced flex-column-container">','<div class="forward-column flex-column column">','<div class="column-header">','<div class="column-title">','<span class="title">',d("Unpaired forward"),"</span>",'<span class="title-info unpaired-info"></span>',"</div>",'<div class="unpaired-filter forward-unpaired-filter pull-left">','<input class="search-query" placeholder="',d("Filter this list"),'" />',"</div>","</div>","</div>",'<div class="paired-column flex-column no-flex column">','<div class="column-header">','<a class="choose-filters-link" href="javascript:void(0)">',d("Choose filters"),"</a>",'<a class="clear-filters-link" href="javascript:void(0);">',d("Clear filters"),"</a><br />",'<a class="autopair-link" href="javascript:void(0);">',d("Auto-pair"),"</a>","</div>","</div>",'<div class="reverse-column flex-column column">','<div class="column-header">','<div class="column-title">','<span class="title">',d("Unpaired reverse"),"</span>",'<span class="title-info unpaired-info"></span>',"</div>",'<div class="unpaired-filter reverse-unpaired-filter pull-left">','<input class="search-query" placeholder="',d("Filter this list"),'" />',"</div>","</div>","</div>","</div>"].join("")),middle:_.template(['<div class="unpaired-columns flex-column-container scroll-container flex-row">','<div class="forward-column flex-column column">','<ol class="column-datasets"></ol>',"</div>",'<div class="paired-column flex-column no-flex column">','<ol class="column-datasets"></ol>',"</div>",'<div class="reverse-column flex-column column">','<ol class="column-datasets"></ol>',"</div>","</div>",'<div class="flexible-partition">','<div class="flexible-partition-drag" title="',d("Drag to change"),'"></div>','<div class="column-header">','<div class="column-title paired-column-title">','<span class="title"></span>',"</div>",'<a class="unpair-all-link" href="javascript:void(0);">',d("Unpair all"),"</a>","</div>","</div>",'<div class="paired-columns flex-column-container scroll-container flex-row">','<ol class="column-datasets"></ol>',"</div>"].join("")),footer:_.template(['<div class="attributes clear">','<div class="clear">','<label class="remove-extensions-prompt pull-right">',d("Remove file extensions from pair names"),"?",'<input class="remove-extensions pull-right" type="checkbox" />',"</label>","</div>",'<div class="clear">','<input class="collection-name form-control pull-right" ','placeholder="',d("Enter a name for your new list"),'" />','<div class="collection-name-prompt pull-right">',d("Name"),":</div>","</div>","</div>",'<div class="actions clear vertically-spaced">','<div class="other-options pull-left">','<button class="cancel-create btn" tabindex="-1">',d("Cancel"),"</button>",'<div class="create-other btn-group dropup">','<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">',d("Create a different kind of collection"),' <span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">','<li><a href="#">',d("Create a <i>single</i> pair"),"</a></li>",'<li><a href="#">',d("Create a list of <i>unpaired</i> datasets"),"</a></li>","</ul>","</div>","</div>",'<div class="main-options pull-right">','<button class="create-collection btn btn-primary">',d("Create list"),"</button>","</div>","</div>"].join("")),helpContent:_.template(["<p>",d(["Collections of paired datasets are ordered lists of dataset pairs (often forward and reverse reads). ","These collections can be passed to tools and workflows in order to have analyses done on each member of ","the entire group. This interface allows you to create a collection, choose which datasets are paired, ","and re-order the final collection."].join("")),"</p>","<p>",d(['Unpaired datasets are shown in the <i data-target=".unpaired-columns">unpaired section</i> ',"(hover over the underlined words to highlight below). ",'Paired datasets are shown in the <i data-target=".paired-columns">paired section</i>.',"<ul>To pair datasets, you can:","<li>Click a dataset in the ",'<i data-target=".unpaired-columns .forward-column .column-datasets,','.unpaired-columns .forward-column">forward column</i> ',"to select it then click a dataset in the ",'<i data-target=".unpaired-columns .reverse-column .column-datasets,','.unpaired-columns .reverse-column">reverse column</i>.',"</li>",'<li>Click one of the "Pair these datasets" buttons in the ','<i data-target=".unpaired-columns .paired-column .column-datasets,','.unpaired-columns .paired-column">middle column</i> ',"to pair the datasets in a particular row.","</li>",'<li>Click <i data-target=".autopair-link">"Auto-pair"</i> ',"to have your datasets automatically paired based on name.","</li>","</ul>"].join("")),"</p>","<p>",d(["<ul>You can filter what is shown in the unpaired sections by:","<li>Entering partial dataset names in either the ",'<i data-target=".forward-unpaired-filter input">forward filter</i> or ','<i data-target=".reverse-unpaired-filter input">reverse filter</i>.',"</li>","<li>Choosing from a list of preset filters by clicking the ",'<i data-target=".choose-filters-link">"Choose filters" link</i>.',"</li>","<li>Entering regular expressions to match dataset names. See: ",'<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expres..."',' target="_blank">MDN\'s JavaScript Regular Expression Tutorial</a>. ',"Note: forward slashes (\\) are not needed.","</li>","<li>Clearing the filters by clicking the ",'<i data-target=".clear-filters-link">"Clear filters" link</i>.',"</li>","</ul>"].join("")),"</p>","<p>",d(["To unpair individual dataset pairs, click the ",'<i data-target=".unpair-btn">unpair buttons ( <span class="fa fa-unlink"></span> )</i>. ','Click the <i data-target=".unpair-all-link">"Unpair all" link</i> to unpair all pairs.'].join("")),"</p>","<p>",d(['You can include or remove the file extensions (e.g. ".fastq") from your pair names by toggling the ','<i data-target=".remove-extensions-prompt">"Remove file extensions from pair names?"</i> control.'].join("")),"</p>","<p>",d(['Once your collection is complete, enter a <i data-target=".collection-name">name</i> and ','click <i data-target=".create-collection">"Create list"</i>. ',"(Note: you do not have to pair all unpaired datasets to finish.)"].join("")),"</p>"].join(""))};(function(){jQuery.fn.extend({hoverhighlight:function h(j,i){j=j||"body";if(!this.size()){return this}$(this).each(function(){var l=$(this),k=l.data("target");if(k){l.mouseover(function(m){$(k,j).css({background:i})}).mouseout(function(m){$(k).css({background:""})})}});return this}})}());var b=function c(j,h){h=_.defaults(h||{},{datasets:j,oncancel:function(){Galaxy.modal.hide()},oncreate:function(){Galaxy.modal.hide();Galaxy.currHistoryPanel.refreshContents()}});if(!window.Galaxy||!Galaxy.modal){throw new Error("Galaxy or Galaxy.modal not found")}var i=new e(h).render();Galaxy.modal.show({title:"Create a collection of paired datasets",body:i.$el,width:"80%",height:"800px",closing_events:true});window.PCC=i;return i};return{PairedCollectionCreator:e,pairedCollectionCreatorModal:b}}); \ No newline at end of file +define(["utils/levenshtein","mvc/base-mvc","utils/localization"],function(g,a,d){var f=Backbone.View.extend(a.LoggableMixin).extend({tagName:"li",className:"dataset paired",initialize:function(h){this.pair=h.pair||{}},render:function(){this.$el.attr("draggable",true).data("pair",this.pair).html(_.template(['<span class="forward-dataset-name flex-column"><%= pair.forward.name %></span>','<span class="pair-name-column flex-column">','<span class="pair-name"><%= pair.name %></span>',"</span>",'<span class="reverse-dataset-name flex-column"><%= pair.reverse.name %></span>'].join(""),{pair:this.pair})).addClass("flex-column-container");return this},events:{dragstart:"_dragstart",dragend:"_dragend",dragover:"_sendToParent",drop:"_sendToParent"},_dragstart:function(h){h.currentTarget.style.opacity="0.4";if(h.originalEvent){h=h.originalEvent}h.dataTransfer.effectAllowed="move";h.dataTransfer.setData("text/plain",JSON.stringify(this.pair));this.$el.parent().trigger("pair.dragstart",[this])},_dragend:function(h){h.currentTarget.style.opacity="1.0";this.$el.parent().trigger("pair.dragend",[this])},_sendToParent:function(h){this.$el.parent().trigger(h)},toString:function(){return"PairView("+this.pair.name+")"}});var e=Backbone.View.extend(a.LoggableMixin).extend({className:"collection-creator flex-row-container",initialize:function(h){h=_.defaults(h,{datasets:[],filters:this.DEFAULT_FILTERS,automaticallyPair:true,matchPercentage:1,strategy:"lcs"});this.initialList=h.datasets;this.historyId=h.historyId;this.filters=this.commonFilters[h.filters]||this.commonFilters[this.DEFAULT_FILTERS];if(_.isArray(h.filters)){this.filters=h.filters}this.automaticallyPair=h.automaticallyPair;this.matchPercentage=h.matchPercentage;this.strategy=this.strategies[h.strategy]||this.strategies[this.DEFAULT_STRATEGY];if(_.isFunction(h.strategy)){this.strategy=h.strategy}this.removeExtensions=true;this.oncancel=h.oncancel;this.oncreate=h.oncreate;this.unpairedPanelHidden=false;this.pairedPanelHidden=false;this.$dragging=null;this._dataSetUp();this._setUpBehaviors()},commonFilters:{none:["",""],illumina:["_1","_2"]},DEFAULT_FILTERS:"illumina",strategies:{lcs:"autoPairLCSs",levenshtein:"autoPairLevenshtein"},DEFAULT_STRATEGY:"lcs",_dataSetUp:function(){this.paired=[];this.unpaired=[];this.selectedIds=[];this._sortInitialList();this._ensureIds();this.unpaired=this.initialList.slice(0);if(this.automaticallyPair){this.autoPair()}},_sortInitialList:function(){this._sortDatasetList(this.initialList)},_sortDatasetList:function(h){h.sort(function(j,i){return naturalSort(j.name,i.name)});return h},_ensureIds:function(){this.initialList.forEach(function(h){if(!h.hasOwnProperty("id")){h.id=_.uniqueId()}});return this.initialList},_splitByFilters:function(j){var i=[],h=[];this.unpaired.forEach(function(k){if(this._filterFwdFn(k)){i.push(k)}if(this._filterRevFn(k)){h.push(k)}}.bind(this));return[i,h]},_filterFwdFn:function(i){var h=new RegExp(this.filters[0]);return h.test(i.name)},_filterRevFn:function(i){var h=new RegExp(this.filters[1]);return h.test(i.name)},_addToUnpaired:function(i){var h=function(j,l){if(j===l){return j}var k=Math.floor((l-j)/2)+j,m=naturalSort(i.name,this.unpaired[k].name);if(m<0){return h(j,k)}else{if(m>0){return h(k+1,l)}}while(this.unpaired[k]&&this.unpaired[k].name===i.name){k++}return k}.bind(this);this.unpaired.splice(h(0,this.unpaired.length),0,i)},autoPair:function(h){h=h||this.strategy;this.simpleAutoPair();return this[h].call(this)},simpleAutoPair:function(){var n=0,l,r=this._splitByFilters(),h=r[0],q=r[1],p,s,k=false;while(n<h.length){var m=h[n];p=m.name.replace(this.filters[0],"");k=false;for(l=0;l<q.length;l++){var o=q[l];s=o.name.replace(this.filters[1],"");if(m!==o&&p===s){k=true;this._pair(h.splice(n,1)[0],q.splice(l,1)[0],{silent:true});break}}if(!k){n+=1}}},autoPairLevenshtein:function(){var o=0,m,t=this._splitByFilters(),h=t[0],r=t[1],q,v,k,s,l;while(o<h.length){var n=h[o];q=n.name.replace(this.filters[0],"");l=Number.MAX_VALUE;for(m=0;m<r.length;m++){var p=r[m];v=p.name.replace(this.filters[1],"");if(n!==p){if(q===v){s=m;l=0;break}k=levenshteinDistance(q,v);if(k<l){s=m;l=k}}}var u=1-(l/(Math.max(q.length,v.length)));if(u>=this.matchPercentage){this._pair(h.splice(o,1)[0],r.splice(s,1)[0],{silent:true});if(h.length<=0||r.length<=0){return}}else{o+=1}}},autoPairLCSs:function(){var m=0,k,t=this._splitByFilters(),h=t[0],r=t[1],q,w,v,s,o;if(!h.length||!r.length){return}while(m<h.length){var l=h[m];q=l.name.replace(this.filters[0],"");o=0;for(k=0;k<r.length;k++){var p=r[k];w=p.name.replace(this.filters[1],"");if(l!==p){if(q===w){s=k;o=q.length;break}var n=this._naiveStartingAndEndingLCS(q,w);v=n.length;if(v>o){s=k;o=v}}}var u=o/(Math.min(q.length,w.length));if(u>=this.matchPercentage){this._pair(h.splice(m,1)[0],r.splice(s,1)[0],{silent:true});if(h.length<=0||r.length<=0){return}}else{m+=1}}},_naiveStartingAndEndingLCS:function(m,k){var n="",o="",l=0,h=0;while(l<m.length&&l<k.length){if(m[l]!==k[l]){break}n+=m[l];l+=1}if(l===m.length){return m}if(l===k.length){return k}l=(m.length-1);h=(k.length-1);while(l>=0&&h>=0){if(m[l]!==k[h]){break}o=[m[l],o].join("");l-=1;h-=1}return n+o},_pair:function(j,h,i){i=i||{};var k=this._createPair(j,h,i.name);this.paired.push(k);this.unpaired=_.without(this.unpaired,j,h);if(!i.silent){this.trigger("pair:new",k)}return k},_createPair:function(j,h,i){if(!(j&&h)||(j===h)){throw new Error("Bad pairing: "+[JSON.stringify(j),JSON.stringify(h)])}i=i||this._guessNameForPair(j,h);return{forward:j,name:i,reverse:h}},_guessNameForPair:function(j,h,k){k=(k!==undefined)?(k):(this.removeExtensions);var i=this._naiveStartingAndEndingLCS(j.name.replace(this.filters[0],""),h.name.replace(this.filters[1],""));if(k){var l=i.lastIndexOf(".");if(l>0){i=i.slice(0,l)}}return i||(j.name+" & "+h.name)},_unpair:function(i,h){h=h||{};if(!i){throw new Error("Bad pair: "+JSON.stringify(i))}this.paired=_.without(this.paired,i);this._addToUnpaired(i.forward);this._addToUnpaired(i.reverse);if(!h.silent){this.trigger("pair:unpair",[i])}return i},unpairAll:function(){var h=[];while(this.paired.length){h.push(this._unpair(this.paired[0],{silent:true}))}this.trigger("pair:unpair",h)},_pairToJSON:function(h){return{collection_type:"paired",src:"new_collection",name:h.name,element_identifiers:[{name:"forward",id:h.forward.id,src:"hda"},{name:"reverse",id:h.reverse.id,src:"hda"}]}},createList:function(){var j=this,i;if(j.historyId){i="/api/histories/"+this.historyId+"/contents/dataset_collections"}var h={type:"dataset_collection",collection_type:"list:paired",name:_.escape(j.$(".collection-name").val()),element_identifiers:j.paired.map(function(k){return j._pairToJSON(k)})};return jQuery.ajax(i,{type:"POST",contentType:"application/json",dataType:"json",data:JSON.stringify(h)}).fail(function(m,k,l){j._ajaxErrHandler(m,k,l)}).done(function(k,l,m){j.trigger("collection:created",k,l,m);if(typeof j.oncreate==="function"){j.oncreate.call(this,k,l,m)}})},_ajaxErrHandler:function(k,h,j){this.error(k,h,j);var i=d("An error occurred while creating this collection");if(k){if(k.readyState===0&&k.status===0){i+=": "+d("Galaxy could not be reached and may be updating.")+d(" Try again in a few minutes.")}else{if(k.responseJSON){i+="<br /><pre>"+JSON.stringify(k.responseJSON)+"</pre>"}else{i+=": "+j}}}creator._showAlert(i,"alert-danger")},render:function(h,i){this.$el.empty().html(e.templates.main());this._renderHeader(h);this._renderMiddle(h);this._renderFooter(h);this._addPluginComponents();return this},_renderHeader:function(i,j){var h=this.$(".header").empty().html(e.templates.header()).find(".help-content").prepend($(e.templates.helpContent()));this._renderFilters();return h},_renderFilters:function(){return this.$(".forward-column .column-header input").val(this.filters[0]).add(this.$(".reverse-column .column-header input").val(this.filters[1]))},_renderMiddle:function(i,j){var h=this.$(".middle").empty().html(e.templates.middle());if(this.unpairedPanelHidden){this.$(".unpaired-columns").hide()}else{if(this.pairedPanelHidden){this.$(".paired-columns").hide()}}this._renderUnpaired();this._renderPaired();return h},_renderUnpaired:function(m,n){var k=this,l,i,h=[],j=this._splitByFilters();this.$(".forward-column .title").text([j[0].length,d("unpaired forward")].join(" "));this.$(".forward-column .unpaired-info").text(this._renderUnpairedDisplayStr(this.unpaired.length-j[0].length));this.$(".reverse-column .title").text([j[1].length,d("unpaired reverse")].join(" "));this.$(".reverse-column .unpaired-info").text(this._renderUnpairedDisplayStr(this.unpaired.length-j[1].length));this.$(".unpaired-columns .column-datasets").empty();this.$(".autopair-link").toggle(this.unpaired.length!==0);if(this.unpaired.length===0){this._renderUnpairedEmpty();return}i=j[1].map(function(p,o){if((j[0][o]!==undefined)&&(j[0][o]!==p)){h.push(k._renderPairButton())}return k._renderUnpairedDataset(p)});l=j[0].map(function(o){return k._renderUnpairedDataset(o)});if(!l.length&&!i.length){this._renderUnpairedNotShown();return}this.$(".unpaired-columns .forward-column .column-datasets").append(l).add(this.$(".unpaired-columns .paired-column .column-datasets").append(h)).add(this.$(".unpaired-columns .reverse-column .column-datasets").append(i));this._adjUnpairedOnScrollbar()},_renderUnpairedDisplayStr:function(h){return["(",h," ",d("filtered out"),")"].join("")},_renderUnpairedDataset:function(h){return $("<li/>").attr("id","dataset-"+h.id).addClass("dataset unpaired").attr("draggable",true).addClass(h.selected?"selected":"").append($("<span/>").addClass("dataset-name").text(h.name)).data("dataset",h)},_renderPairButton:function(){return $("<li/>").addClass("dataset unpaired").append($("<span/>").addClass("dataset-name").text(d("Pair these datasets")))},_renderUnpairedEmpty:function(){var h=$('<div class="empty-message"></div>').text("("+d("no remaining unpaired datasets")+")");this.$(".unpaired-columns .paired-column .column-datasets").empty().prepend(h);return h},_renderUnpairedNotShown:function(){var h=$('<div class="empty-message"></div>').text("("+d("no datasets were found matching the current filters")+")");this.$(".unpaired-columns .paired-column .column-datasets").empty().prepend(h);return h},_adjUnpairedOnScrollbar:function(){var k=this.$(".unpaired-columns").last(),l=this.$(".unpaired-columns .reverse-column .dataset").first();if(!l.size()){return}var h=k.offset().left+k.outerWidth(),j=l.offset().left+l.outerWidth(),i=Math.floor(h)-Math.floor(j);this.$(".unpaired-columns .forward-column").css("margin-left",(i>0)?i:0)},_renderPaired:function(i,j){this.$(".paired-column-title .title").text([this.paired.length,d("paired")].join(" "));this.$(".unpair-all-link").toggle(this.paired.length!==0);if(this.paired.length===0){this._renderPairedEmpty();return}else{this.$(".remove-extensions-link").show()}this.$(".paired-columns .column-datasets").empty();var h=this;this.paired.forEach(function(m,k){var l=new f({pair:m});h.$(".paired-columns .column-datasets").append(l.render().$el).append(['<button class="unpair-btn">','<span class="fa fa-unlink" title="',d("Unpair"),'"></span>',"</button>"].join(""))})},_renderPairedEmpty:function(){var h=$('<div class="empty-message"></div>').text("("+d("no paired datasets yet")+")");this.$(".paired-columns .column-datasets").empty().prepend(h);return h},_renderFooter:function(i,j){var h=this.$(".footer").empty().html(e.templates.footer());this.$(".remove-extensions").prop("checked",this.removeExtensions);if(typeof this.oncancel==="function"){this.$(".cancel-create.btn").show()}return h},_addPluginComponents:function(){this._chooseFiltersPopover(".choose-filters-link");this.$(".help-content i").hoverhighlight(".collection-creator","rgba( 64, 255, 255, 1.0 )")},_chooseFiltersPopover:function(h){function i(l,k){return['<button class="filter-choice btn" ','data-forward="',l,'" data-reverse="',k,'">',d("Forward"),": ",l,", ",d("Reverse"),": ",k,"</button>"].join("")}var j=$(_.template(['<div class="choose-filters">','<div class="help">',d("Choose from the following filters to change which unpaired reads are shown in the display"),":</div>",i("_1","_2"),i("_R1","_R2"),"</div>"].join(""),{}));return this.$(h).popover({container:".collection-creator",placement:"bottom",html:true,content:j})},_validationWarning:function(i,h){var j="validation-warning";if(i==="name"){i=this.$(".collection-name").add(this.$(".collection-name-prompt"));this.$(".collection-name").focus().select()}if(h){i=i||this.$("."+j);i.removeClass(j)}else{i.addClass(j)}},_setUpBehaviors:function(){this.on("pair:new",function(){this._renderUnpaired();this._renderPaired();this.$(".paired-columns").scrollTop(8000000)});this.on("pair:unpair",function(h){this._renderUnpaired();this._renderPaired();this.splitView()});this.on("filter-change",function(){this.filters=[this.$(".forward-unpaired-filter input").val(),this.$(".reverse-unpaired-filter input").val()];this._renderFilters();this._renderUnpaired()});this.on("autopair",function(){this._renderUnpaired();this._renderPaired();var h,i=null;if(this.paired.length){i="alert-success";h=this.paired.length+" "+d("pairs created");if(!this.unpaired.length){h+=": "+d("all datasets have been successfully paired");this.hideUnpaired()}}else{h=d("Could not automatically create any pairs from the given dataset names")}this._showAlert(h,i)});return this},events:{"click .more-help":"_clickMoreHelp","click .less-help":"_clickLessHelp","click .header .alert button":"_hideAlert","click .forward-column .column-title":"_clickShowOnlyUnpaired","click .reverse-column .column-title":"_clickShowOnlyUnpaired","click .unpair-all-link":"_clickUnpairAll","change .forward-unpaired-filter input":function(h){this.trigger("filter-change")},"focus .forward-unpaired-filter input":function(h){$(h.currentTarget).select()},"click .autopair-link":"_clickAutopair","click .choose-filters .filter-choice":"_clickFilterChoice","click .clear-filters-link":"_clearFilters","change .reverse-unpaired-filter input":function(h){this.trigger("filter-change")},"focus .reverse-unpaired-filter input":function(h){$(h.currentTarget).select()},"click .forward-column .dataset.unpaired":"_clickUnpairedDataset","click .reverse-column .dataset.unpaired":"_clickUnpairedDataset","click .paired-column .dataset.unpaired":"_clickPairRow","click .unpaired-columns":"clearSelectedUnpaired","mousedown .unpaired-columns .dataset":"_mousedownUnpaired","click .paired-column-title":"_clickShowOnlyPaired","mousedown .flexible-partition-drag":"_startPartitionDrag","click .paired-columns .dataset.paired":"selectPair","click .paired-columns":"clearSelectedPaired","click .paired-columns .pair-name":"_clickPairName","click .unpair-btn":"_clickUnpair","dragover .paired-columns .column-datasets":"_dragoverPairedColumns","drop .paired-columns .column-datasets":"_dropPairedColumns","pair.dragstart .paired-columns .column-datasets":"_pairDragstart","pair.dragend .paired-columns .column-datasets":"_pairDragend","change .remove-extensions":function(h){this.toggleExtensions()},"change .collection-name":"_changeName","click .cancel-create":function(h){if(typeof this.oncancel==="function"){this.oncancel.call(this)}},"click .create-collection":"_clickCreate"},_clickMoreHelp:function(h){this.$(".main-help").addClass("expanded");this.$(".more-help").hide()},_clickLessHelp:function(h){this.$(".main-help").removeClass("expanded");this.$(".more-help").show()},_showAlert:function(i,h){h=h||"alert-danger";this.$(".main-help").hide();this.$(".header .alert").attr("class","alert alert-dismissable").addClass(h).show().find(".alert-message").html(i)},_hideAlert:function(h){this.$(".main-help").show();this.$(".header .alert").hide()},_clickShowOnlyUnpaired:function(h){if(this.$(".paired-columns").is(":visible")){this.hidePaired()}else{this.splitView()}},_clickShowOnlyPaired:function(h){if(this.$(".unpaired-columns").is(":visible")){this.hideUnpaired()}else{this.splitView()}},hideUnpaired:function(h,i){this.unpairedPanelHidden=true;this.pairedPanelHidden=false;this._renderMiddle(h,i)},hidePaired:function(h,i){this.unpairedPanelHidden=false;this.pairedPanelHidden=true;this._renderMiddle(h,i)},splitView:function(h,i){this.unpairedPanelHidden=this.pairedPanelHidden=false;this._renderMiddle(h,i);return this},_clickUnpairAll:function(h){this.unpairAll()},_clickAutopair:function(i){var h=this.autoPair();this.trigger("autopair",h)},_clickFilterChoice:function(i){var h=$(i.currentTarget);this.$(".forward-unpaired-filter input").val(h.data("forward"));this.$(".reverse-unpaired-filter input").val(h.data("reverse"));this._hideChooseFilters();this.trigger("filter-change")},_hideChooseFilters:function(){this.$(".choose-filters-link").popover("hide");this.$(".popover").css("display","none")},_clearFilters:function(h){this.$(".forward-unpaired-filter input").val("");this.$(".reverse-unpaired-filter input").val("");this.trigger("filter-change")},_clickUnpairedDataset:function(h){h.stopPropagation();return this.toggleSelectUnpaired($(h.currentTarget))},toggleSelectUnpaired:function(j,i){i=i||{};var k=j.data("dataset"),h=i.force!==undefined?i.force:!j.hasClass("selected");if(!j.size()||k===undefined){return j}if(h){j.addClass("selected");if(!i.waitToPair){this.pairAllSelected()}}else{j.removeClass("selected")}return j},pairAllSelected:function(i){i=i||{};var j=this,k=[],h=[],l=[];j.$(".unpaired-columns .forward-column .dataset.selected").each(function(){k.push($(this).data("dataset"))});j.$(".unpaired-columns .reverse-column .dataset.selected").each(function(){h.push($(this).data("dataset"))});k.length=h.length=Math.min(k.length,h.length);k.forEach(function(n,m){try{l.push(j._pair(n,h[m],{silent:true}))}catch(o){j.error(o)}});if(l.length&&!i.silent){this.trigger("pair:new",l)}return l},clearSelectedUnpaired:function(){this.$(".unpaired-columns .dataset.selected").removeClass("selected")},_mousedownUnpaired:function(j){if(j.shiftKey){var i=this,h=$(j.target).addClass("selected"),k=function(l){i.$(l.target).filter(".dataset").addClass("selected")};h.parent().on("mousemove",k);$(document).one("mouseup",function(l){h.parent().off("mousemove",k);i.pairAllSelected()})}},_clickPairRow:function(j){var k=$(j.currentTarget).index(),i=$(".unpaired-columns .forward-column .dataset").eq(k).data("dataset"),h=$(".unpaired-columns .reverse-column .dataset").eq(k).data("dataset");this._pair(i,h)},_startPartitionDrag:function(i){var h=this,l=i.pageY;$("body").css("cursor","ns-resize");h.$(".flexible-partition-drag").css("color","black");function k(m){h.$(".flexible-partition-drag").css("color","");$("body").css("cursor","").unbind("mousemove",j)}function j(m){var n=m.pageY-l;if(!h.adjPartition(n)){$("body").trigger("mouseup")}h._adjUnpairedOnScrollbar();l+=n}$("body").mousemove(j);$("body").one("mouseup",k)},adjPartition:function(i){var h=this.$(".unpaired-columns"),j=this.$(".paired-columns"),k=parseInt(h.css("height"),10),l=parseInt(j.css("height"),10);k=Math.max(10,k+i);l=l-i;var m=i<0;if(m){if(this.unpairedPanelHidden){return false}else{if(k<=10){this.hideUnpaired();return false}}}else{if(this.unpairedPanelHidden){h.show();this.unpairedPanelHidden=false}}if(!m){if(this.pairedPanelHidden){return false}else{if(l<=15){this.hidePaired();return false}}}else{if(this.pairedPanelHidden){j.show();this.pairedPanelHidden=false}}h.css({height:k+"px",flex:"0 0 auto"});return true},selectPair:function(h){h.stopPropagation();$(h.currentTarget).toggleClass("selected")},clearSelectedPaired:function(h){this.$(".paired-columns .dataset.selected").removeClass("selected")},_clickPairName:function(j){j.stopPropagation();var i=$(j.currentTarget),k=this.paired[i.parent().index()],h=prompt("Enter a new name for the pair:",k.name);if(h){k.name=h;k.customizedName=true;i.text(k.name)}},_clickUnpair:function(i){var h=Math.floor($(i.currentTarget).index()/2);this._unpair(this.paired[h])},_dragoverPairedColumns:function(k){k.preventDefault();var i=this.$(".paired-columns .column-datasets"),l=i.offset();var j=this._getNearestPairedDatasetLi(k.originalEvent.clientY);$(".paired-drop-placeholder").remove();var h=$('<div class="paired-drop-placeholder"></div>');if(!j.size()){i.append(h)}else{j.before(h)}},_getNearestPairedDatasetLi:function(o){var l=4,j=this.$(".paired-columns .column-datasets li").toArray();for(var k=0;k<j.length;k++){var n=$(j[k]),m=n.offset().top,h=Math.floor(n.outerHeight()/2)+l;if(m+h>o&&m-h<o){return n}}return $()},_dropPairedColumns:function(i){i.preventDefault();i.dataTransfer.dropEffect="move";var h=this._getNearestPairedDatasetLi(i.originalEvent.clientY);if(h.size()){this.$dragging.insertBefore(h)}else{this.$dragging.insertAfter(this.$(".paired-columns .unpair-btn").last())}this._syncPairsToDom();return false},_syncPairsToDom:function(){var h=[];this.$(".paired-columns .dataset.paired").each(function(){h.push($(this).data("pair"))});this.paired=h;this._renderPaired()},_pairDragstart:function(i,j){j.$el.addClass("selected");var h=this.$(".paired-columns .dataset.selected");this.$dragging=h},_pairDragend:function(h,i){$(".paired-drop-placeholder").remove();this.$dragging=null},toggleExtensions:function(i){var h=this;h.removeExtensions=(i!==undefined)?(i):(!h.removeExtensions);_.each(h.paired,function(j){if(j.customizedName){return}j.name=h._guessNameForPair(j.forward,j.reverse)});h._renderPaired();h._renderFooter()},_changeName:function(h){this._validationWarning("name",!!this._getName())},_getName:function(){return _.escape(this.$(".collection-name").val())},_clickCreate:function(i){var h=this._getName();if(!h){this._validationWarning("name")}else{this.createList()}},_printList:function(i){var h=this;_.each(i,function(j){if(i===h.paired){h._printPair(j)}else{}})},_printPair:function(h){this.debug(h.forward.name,h.reverse.name,": ->",h.name)},toString:function(){return"PairedCollectionCreator"}});e.templates=e.templates||{main:_.template(['<div class="header flex-row no-flex"></div>','<div class="middle flex-row flex-row-container"></div>','<div class="footer flex-row no-flex">'].join("")),header:_.template(['<div class="main-help well clear">','<a class="more-help" href="javascript:void(0);">',d("More help"),"</a>",'<div class="help-content">','<a class="less-help" href="javascript:void(0);">',d("Less"),"</a>","</div>","</div>",'<div class="alert alert-dismissable">','<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>','<span class="alert-message"></span>',"</div>",'<div class="column-headers vertically-spaced flex-column-container">','<div class="forward-column flex-column column">','<div class="column-header">','<div class="column-title">','<span class="title">',d("Unpaired forward"),"</span>",'<span class="title-info unpaired-info"></span>',"</div>",'<div class="unpaired-filter forward-unpaired-filter pull-left">','<input class="search-query" placeholder="',d("Filter this list"),'" />',"</div>","</div>","</div>",'<div class="paired-column flex-column no-flex column">','<div class="column-header">','<a class="choose-filters-link" href="javascript:void(0)">',d("Choose filters"),"</a>",'<a class="clear-filters-link" href="javascript:void(0);">',d("Clear filters"),"</a><br />",'<a class="autopair-link" href="javascript:void(0);">',d("Auto-pair"),"</a>","</div>","</div>",'<div class="reverse-column flex-column column">','<div class="column-header">','<div class="column-title">','<span class="title">',d("Unpaired reverse"),"</span>",'<span class="title-info unpaired-info"></span>',"</div>",'<div class="unpaired-filter reverse-unpaired-filter pull-left">','<input class="search-query" placeholder="',d("Filter this list"),'" />',"</div>","</div>","</div>","</div>"].join("")),middle:_.template(['<div class="unpaired-columns flex-column-container scroll-container flex-row">','<div class="forward-column flex-column column">','<ol class="column-datasets"></ol>',"</div>",'<div class="paired-column flex-column no-flex column">','<ol class="column-datasets"></ol>',"</div>",'<div class="reverse-column flex-column column">','<ol class="column-datasets"></ol>',"</div>","</div>",'<div class="flexible-partition">','<div class="flexible-partition-drag" title="',d("Drag to change"),'"></div>','<div class="column-header">','<div class="column-title paired-column-title">','<span class="title"></span>',"</div>",'<a class="unpair-all-link" href="javascript:void(0);">',d("Unpair all"),"</a>","</div>","</div>",'<div class="paired-columns flex-column-container scroll-container flex-row">','<ol class="column-datasets"></ol>',"</div>"].join("")),footer:_.template(['<div class="attributes clear">','<div class="clear">','<label class="remove-extensions-prompt pull-right">',d("Remove file extensions from pair names"),"?",'<input class="remove-extensions pull-right" type="checkbox" />',"</label>","</div>",'<div class="clear">','<input class="collection-name form-control pull-right" ','placeholder="',d("Enter a name for your new list"),'" />','<div class="collection-name-prompt pull-right">',d("Name"),":</div>","</div>","</div>",'<div class="actions clear vertically-spaced">','<div class="other-options pull-left">','<button class="cancel-create btn" tabindex="-1">',d("Cancel"),"</button>",'<div class="create-other btn-group dropup">','<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">',d("Create a different kind of collection"),' <span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">','<li><a href="#">',d("Create a <i>single</i> pair"),"</a></li>",'<li><a href="#">',d("Create a list of <i>unpaired</i> datasets"),"</a></li>","</ul>","</div>","</div>",'<div class="main-options pull-right">','<button class="create-collection btn btn-primary">',d("Create list"),"</button>","</div>","</div>"].join("")),helpContent:_.template(["<p>",d(["Collections of paired datasets are ordered lists of dataset pairs (often forward and reverse reads). ","These collections can be passed to tools and workflows in order to have analyses done on each member of ","the entire group. This interface allows you to create a collection, choose which datasets are paired, ","and re-order the final collection."].join("")),"</p>","<p>",d(['Unpaired datasets are shown in the <i data-target=".unpaired-columns">unpaired section</i> ',"(hover over the underlined words to highlight below). ",'Paired datasets are shown in the <i data-target=".paired-columns">paired section</i>.',"<ul>To pair datasets, you can:","<li>Click a dataset in the ",'<i data-target=".unpaired-columns .forward-column .column-datasets,','.unpaired-columns .forward-column">forward column</i> ',"to select it then click a dataset in the ",'<i data-target=".unpaired-columns .reverse-column .column-datasets,','.unpaired-columns .reverse-column">reverse column</i>.',"</li>",'<li>Click one of the "Pair these datasets" buttons in the ','<i data-target=".unpaired-columns .paired-column .column-datasets,','.unpaired-columns .paired-column">middle column</i> ',"to pair the datasets in a particular row.","</li>",'<li>Click <i data-target=".autopair-link">"Auto-pair"</i> ',"to have your datasets automatically paired based on name.","</li>","</ul>"].join("")),"</p>","<p>",d(["<ul>You can filter what is shown in the unpaired sections by:","<li>Entering partial dataset names in either the ",'<i data-target=".forward-unpaired-filter input">forward filter</i> or ','<i data-target=".reverse-unpaired-filter input">reverse filter</i>.',"</li>","<li>Choosing from a list of preset filters by clicking the ",'<i data-target=".choose-filters-link">"Choose filters" link</i>.',"</li>","<li>Entering regular expressions to match dataset names. See: ",'<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expres..."',' target="_blank">MDN\'s JavaScript Regular Expression Tutorial</a>. ',"Note: forward slashes (\\) are not needed.","</li>","<li>Clearing the filters by clicking the ",'<i data-target=".clear-filters-link">"Clear filters" link</i>.',"</li>","</ul>"].join("")),"</p>","<p>",d(["To unpair individual dataset pairs, click the ",'<i data-target=".unpair-btn">unpair buttons ( <span class="fa fa-unlink"></span> )</i>. ','Click the <i data-target=".unpair-all-link">"Unpair all" link</i> to unpair all pairs.'].join("")),"</p>","<p>",d(['You can include or remove the file extensions (e.g. ".fastq") from your pair names by toggling the ','<i data-target=".remove-extensions-prompt">"Remove file extensions from pair names?"</i> control.'].join("")),"</p>","<p>",d(['Once your collection is complete, enter a <i data-target=".collection-name">name</i> and ','click <i data-target=".create-collection">"Create list"</i>. ',"(Note: you do not have to pair all unpaired datasets to finish.)"].join("")),"</p>"].join(""))};(function(){jQuery.fn.extend({hoverhighlight:function h(j,i){j=j||"body";if(!this.size()){return this}$(this).each(function(){var l=$(this),k=l.data("target");if(k){l.mouseover(function(m){$(k,j).css({background:i})}).mouseout(function(m){$(k).css({background:""})})}});return this}})}());var b=function c(j,h){h=_.defaults(h||{},{datasets:j,oncancel:function(){Galaxy.modal.hide()},oncreate:function(){Galaxy.modal.hide();Galaxy.currHistoryPanel.refreshContents()}});if(!window.Galaxy||!Galaxy.modal){throw new Error("Galaxy or Galaxy.modal not found")}var i=new e(h).render();Galaxy.modal.show({title:"Create a collection of paired datasets",body:i.$el,width:"80%",height:"800px",closing_events:true});window.PCC=i;return i};return{PairedCollectionCreator:e,pairedCollectionCreatorModal:b}}); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/packed/mvc/tools/tools-form.js --- a/static/scripts/packed/mvc/tools/tools-form.js +++ b/static/scripts/packed/mvc/tools/tools-form.js @@ -1,1 +1,1 @@ -define(["mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/citation/citation-model","mvc/citation/citation-view","mvc/tools","mvc/tools/tools-template","mvc/tools/tools-datasets","mvc/tools/tools-section"],function(f,j,h,a,e,c,g,i){var d=Backbone.Model.extend({initialize:function(k){this.url=galaxy_config.root+"api/tools/"+k.id+"?io_details=true"}});var b=Backbone.View.extend({main_el:"body",initialize:function(l){var k=this;this.options=l;this.model=new d({id:l.id});this.datasets=new g({success:function(){k._initializeToolForm()}})},_initializeToolForm:function(){this.field_list={};this.inputs_sequential={};var k=this;this.model.fetch({error:function(l){console.debug("tools-form::_initializeToolForm() : Attempt to fetch tool model failed.")},success:function(){k.inputs=k.model.get("inputs");k.portlet=new f.View({icon:"fa-wrench",title:"<b>"+k.model.get("name")+"</b> "+k.model.get("description"),buttons:{execute:new j.ButtonIcon({icon:"fa-check",tooltip:"Execute the tool",title:"Execute",floating:"clear",onclick:function(){}})}});k.message=new j.Message();k.portlet.append(k.message.$el);$(k.main_el).append(k.portlet.$el);if(k.options.help!=""){$(k.main_el).append(c.help(k.options.help))}if(k.options.citations){$(k.main_el).append(c.citations());var l=new h.ToolCitationCollection();l.tool_id=k.options.id;var m=new a.CitationListView({collection:l});m.render();l.fetch()}k.setElement(k.portlet.content());k.section=new i.View(k,{inputs:k.model.get("inputs")});k.portlet.append(k.section.$el)}})}});return{View:b}}); \ No newline at end of file +define(["mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/citation/citation-model","mvc/citation/citation-view","mvc/tools","mvc/tools/tools-template","mvc/tools/tools-datasets","mvc/tools/tools-section","mvc/tools/tools-tree"],function(g,k,i,a,f,d,h,j,c){var e=Backbone.Model.extend({initialize:function(l){this.url=galaxy_config.root+"api/tools/"+l.id+"?io_details=true"}});var b=Backbone.View.extend({main_el:"body",initialize:function(m){var l=this;this.options=m;this.model=new e({id:m.id});this.tree=new c(this);this.field_list={};this.input_list={};this.data=new Backbone.Model();this.datasets=new h({success:function(){l._initializeToolForm()}})},_initializeToolForm:function(){var l=this;this.model.fetch({error:function(m){console.debug("tools-form::_initializeToolForm() : Attempt to fetch tool model failed.")},success:function(){l.inputs=l.model.get("inputs");l.portlet=new g.View({icon:"fa-wrench",title:"<b>"+l.model.get("name")+"</b> "+l.model.get("description"),buttons:{execute:new k.ButtonIcon({icon:"fa-check",tooltip:"Execute the tool",title:"Execute",floating:"clear",onclick:function(){console.log(l.tree.create(l))}})}});l.message=new k.Message();l.portlet.append(l.message.$el);$(l.main_el).append(l.portlet.$el);if(l.options.help!=""){$(l.main_el).append(d.help(l.options.help))}if(l.options.citations){$(l.main_el).append(d.citations());var m=new i.ToolCitationCollection();m.tool_id=l.options.id;var n=new a.CitationListView({collection:m});n.render();m.fetch()}l.setElement(l.portlet.content());l.section=new j.View(l,{inputs:l.model.get("inputs")});l.portlet.append(l.section.$el);l.refresh()}})},refresh:function(){this.tree.refresh();for(var l in this.field_list){this.field_list[l].trigger("change")}console.debug("tools-form::refresh() - Recreated tree structure. Refresh.")}});return{View:b}}); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/packed/mvc/tools/tools-section.js --- a/static/scripts/packed/mvc/tools/tools-section.js +++ b/static/scripts/packed/mvc/tools/tools-section.js @@ -1,1 +1,1 @@ -define(["mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(b,d,a){var c=Backbone.View.extend({initialize:function(f,e){this.app=f;this.inputs=e.inputs;this.datasets=f.datasets;this.table=new b.View(e);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();var e=new Backbone.Model();for(var f in this.inputs){this._add(this.inputs[f],e)}for(var f in this.app.field_list){this.app.field_list[f].trigger("change")}},_add:function(f,k){var e=this;var j=f.type;switch(j){case"conditional":f.label=f.test_param.label;f.name=f.test_param.name;this._addRow("conditional",f,k);for(var h in f.cases){var l=new c(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(l.$el);this.table.append(f.name+"_formsection_"+h)}break;case"repeat":var g=new a.View({title_new:"Add Group",onnew:function(){var m=new c(e.app,{inputs:f.inputs,cls:"ui-table-plain"});var i=f.name+"_formsection_"+g.size();g.add({id:i,title:"Repeat",$el:m.$el,ondel:function(){g.del(i)}});g.show(i)}});this.table.add(f.title);this.table.add(g.$el);this.table.append(f.name);break;default:this._addRow(j,f,k)}},_addRow:function(h,e,f){var j=e.name;var g=null;switch(h){case"text":g=this._field_text(e,f);break;case"select":g=this._field_select(e,f);break;case"radiobutton":g=this._field_radio(e,f);break;case"data":g=this._field_data(e,f);break;case"data_column":g=this._field_column(e,f);break;case"textarea":g=this._field_textarea(e,f);break;case"conditional":g=this._field_conditional(e,f);break}if(!g){console.debug("tools-form::_addRow() : Unmatched field type ("+h+").");return}if(!f.get(j)){f.set(j,e.value)}g.value(f.get(j));this.app.field_list[j]=g;this.app.inputs_sequential[j]=e;var i=$("<div/>");i.append(g.$el);if(e.help){i.append('<div class="ui-table-form-info">'+e.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+e.label+"</span>","25%");this.table.add(i);this.table.append(j);if(e.hide){this.table.get(j).hide()}},_field_text:function(e,f){var g=e.name;return new d.Input({id:"field-"+g,value:f.get(g),onchange:function(h){f.set(g,h)}})},_field_textarea:function(e,f){var g=e.name;return new d.Textarea({id:"field-"+g,onchange:function(){f.set(g,field.value())}})},_field_conditional:function(g,k){var e=this;var f=[];for(var h in g.test_param.options){var j=g.test_param.options[h];f.push({label:j[0],value:j[1]})}var l=g.name;return new d.Select.View({id:"field-"+l,data:f,value:k.get(l),onchange:function(q){k.set(l,q);for(var p in g.cases){var n=g.cases[p];var o=g.name+"_formsection_"+p;var m=e.table.get(o);if(n.value==q){m.show()}else{m.hide()}}}})},_field_data:function(g,k){var e=this;var l=g.name;var j=this.datasets.filterType();var f=[];for(var h in j){f.push({label:j[h].get("name"),value:j[h].get("id")})}return new d.Select.View({id:"field-"+l,data:f,value:f[0].value,onchange:function(r){k.set(l,r);var n=_.where(e.app.inputs_sequential,{data_ref:l,type:"data_column"});var t=e.datasets.filter(r);if(t&&n.length>0){console.debug("tool-form::field_data() - Selected dataset "+r+".");var s=t.get("metadata_column_types");if(!s){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+r+".")}var q=[];for(var p in s){q.push({label:"Column: "+(parseInt(p)+1)+" ["+s[p]+"]",value:p})}for(var o in n){var m=e.app.field_list[n[o].name];if(m){m.update(q);m.value(m.first())}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+r+".")}}})},_field_column:function(e,f){var g=e.name;return new d.Select.View({id:"field-"+g,value:f.get(g),onchange:function(h){f.set(g,h)}})},_field_select:function(f,k){var e=[];for(var g in f.options){var h=f.options[g];e.push({label:h[0],value:h[1]})}var j=d.Select;if(f.display=="checkboxes"){j=d.Checkbox}var l=f.name;return new j.View({id:"field-"+l,data:e,value:k.get(l),onchange:function(i){k.set(l,i)}})},_field_radio:function(e,f){var g=e.name;return new d.RadioButton({id:"field-"+g,data:e.data,value:f.get(g),onchange:function(h){f.set(g,h)}})}});return{View:c}}); \ No newline at end of file +define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(c,b,e,a){var d=Backbone.View.extend({initialize:function(g,f){this.app=g;this.inputs=f.inputs;this.datasets=g.datasets;this.data=g.data;f.cls_tr="form-row";this.table=new b.View(f);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var f in this.inputs){this._add(this.inputs[f],this.data)}},_add:function(h,j){var g=this;var f=jQuery.extend(true,{},h);f.id=c.uuid();this.app.input_list[f.id]=f;var i=f.type;switch(i){case"conditional":this._addConditional(f,j);break;case"repeat":this._addRepeat(f);break;default:this._addRow(i,f,j)}},_addConditional:function(f,j){f.label=f.test_param.label;f.value=f.test_param.value;this._addRow("conditional",f,j);for(var h in f.cases){var g=f.id+"-section-"+h;var k=new d(this.app,{inputs:f.cases[h].inputs,cls:"ui-table-plain"});this.table.add("");this.table.add(k.$el);this.table.append(g)}},_addRepeat:function(f){var g=this;var k=new a.View({title_new:"Add "+f.title,max:f.max,onnew:function(){var i=f.id+"-section-"+c.uuid();var m=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:i,title:f.title,$el:m.$el,ondel:function(){k.del(i);k.retitle(f.title);g.app.refresh()}});k.retitle(f.title);k.show(i);g.app.refresh()}});for(var j=0;j<f.min;j++){var h=f.id+"-section-"+c.uuid();var l=new d(g.app,{inputs:f.inputs,cls:"ui-table-plain"});k.add({id:h,title:f.title,$el:l.$el})}k.retitle(f.title);this.table.add("");this.table.add(k.$el);this.table.append(f.id)},_addRow:function(i,f,g){var k=f.id;var h=null;switch(i){case"text":h=this._field_text(f,g);break;case"select":h=this._field_select(f,g);break;case"radiobutton":h=this._field_radio(f,g);break;case"data":h=this._field_data(f,g);break;case"data_column":h=this._field_column(f,g);break;case"textarea":h=this._field_textarea(f,g);break;case"conditional":h=this._field_conditional(f,g);break;case"hidden":h=this._field_hidden(f,g);break}if(!h){console.debug("tools-form::_addRow() : Unmatched field type ("+i+").");return}if(!g.get(k)){g.set(k,f.value)}h.value(g.get(k));this.app.field_list[k]=h;var j=$("<div/>");j.append(h.$el);if(f.help){j.append('<div class="ui-table-form-info">'+f.help+"</div>")}this.table.add('<span class="ui-table-form-title">'+f.label+"</span>","20%");this.table.add(j);this.table.append(k)},_field_conditional:function(f,l){var g=this;var h=[];for(var j in f.test_param.options){var k=f.test_param.options[j];h.push({label:k[0],value:k[1]})}var m=f.id;return new e.Select.View({id:"field-"+m,data:h,value:l.get(m),onchange:function(u){l.set(m,u);for(var s in f.cases){var o=f.cases[s];var r=f.id+"-section-"+s;var n=g.table.get(r);var q=false;for(var p in o.inputs){var t=o.inputs[p].type;if(t&&t!=="hidden"){q=true;break}}if(o.value==u&&q){n.fadeIn("fast")}else{n.hide()}}}})},_field_data:function(f,l){var g=this;var m=f.id;var k=this.datasets.filterType();var h=[];for(var j in k){h.push({label:k[j].get("name"),value:k[j].get("id")})}return new e.Select.View({id:"field-"+m,data:h,value:h[0].value,onchange:function(s){l.set(m,s);var o=g.app.tree.findReferences(m);var u=g.datasets.filter(s);if(u&&o.length>0){console.debug("tool-form::field_data() - Selected dataset "+s+".");var t=u.get("metadata_column_types");if(!t){console.debug("tool-form::field_data() - FAILED: Could not find metadata for dataset "+s+".")}var r=[];for(var q in t){r.push({label:"Column: "+(parseInt(q)+1)+" ["+t[q]+"]",value:q})}for(var p in o){var n=g.app.field_list[o[p]];if(n){n.update(r);if(!n.exists(n.value())){n.value(n.first())}}}}else{console.debug("tool-form::field_data() - FAILED: Could not find dataset "+s+".")}}})},_field_column:function(f,g){var h=f.id;return new e.Select.View({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_select:function(f,l){var g=[];for(var h in f.options){var j=f.options[h];g.push({label:j[0],value:j[1]})}var k=e.Select;if(f.display=="checkboxes"){k=e.Checkbox}var m=f.id;return new k.View({id:"field-"+m,data:g,value:l.get(m),onchange:function(i){l.set(m,i)}})},_field_text:function(f,g){var h=f.id;return new e.Input({id:"field-"+h,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_textarea:function(f,g){var h=f.id;return new e.Textarea({id:"field-"+h,onchange:function(){g.set(h,field.value())}})},_field_radio:function(f,g){var h=f.id;return new e.RadioButton({id:"field-"+h,data:f.data,value:g.get(h),onchange:function(i){g.set(h,i)}})},_field_hidden:function(f,g){var h=f.id;return new e.Hidden({id:"field-"+h,value:g.get(h)})}});return{View:d}}); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/packed/mvc/tools/tools-tree.js --- /dev/null +++ b/static/scripts/packed/mvc/tools/tools-tree.js @@ -0,0 +1,1 @@ +define([],function(){return Backbone.Model.extend({initialize:function(a){this.app=a},refresh:function(){if(!this.app.section){return{}}this.dict={};this.xml=$("<div/>");this._iterate(this.app.section.$el,this.dict,this.xml)},_iterate:function(d,e,b){var a=this;var c=$(d).children();c.each(function(){var i=this;var h=$(i).attr("id");if($(i).hasClass("form-row")||$(i).hasClass("tab-pane")){e[h]={};var f=a.app.input_list[h];if(f){e[h]={input:f}}var g=$('<div id="'+h+'"/>');b.append(g);a._iterate(i,e[h],g)}else{a._iterate(i,e,b)}})},findReferences:function(c){var f=[];var b=this;function d(g,i){var h=$(i).children();var k=[];var j=false;h.each(function(){var n=this;var m=$(n).attr("id");if(m!==c){var l=b.app.input_list[m];if(l){if(l.name==g){j=true;return false}if(l.data_ref==g){k.push(m)}}}});if(!j){f=f.concat(k);h.each(function(){d(g,this)})}}var e=this.xml.find("#"+c);if(e.length>0){var a=this.app.input_list[c];if(a){d(a.name,e.parent())}}return f}})}); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 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.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;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},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="'+d.target+'"'):(""),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 c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},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.create=function _create(b,a){return new PopupMenu(b,a)};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.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&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};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}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}(function(){var b=window._l||function(d){return d};function a(k,q){var e=27,n=13,d=$(k),f=true,h={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(r){},minSearchLen:0,escWillClear:true,oninit:function(){}};function j(r){var s=$(this).parent().children("input");s.val("");s.trigger("clear:searchInput");q.onclear()}function p(s,r){$(this).trigger("search:searchInput",r);if(typeof q.onfirstsearch==="function"&&f){f=false;q.onfirstsearch(r)}else{q.onsearch(r)}}function g(){return['<input type="text" name="',q.name,'" placeholder="',q.placeholder,'" ','class="search-query ',q.classes,'" ',"/>"].join("")}function m(){return $(g()).focus(function(r){$(this).select()}).keyup(function(s){s.preventDefault();s.stopPropagation();if(!$(this).val()){$(this).blur()}if(s.which===e&&q.escWillClear){j.call(this,s)}else{var r=$(this).val();if((s.which===n)||(q.minSearchLen&&r.length>=q.minSearchLen)){p.call(this,s,r)}else{if(!r.length){j.call(this,s)}}}}).val(q.initialVal)}function l(){return $(['<span class="search-clear fa fa-times-circle" ','title="',b("clear search (esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(r){j.call(this,r)})}function o(){return $(['<span class="search-loading fa fa-spinner fa-spin" ','title="',b("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function i(){d.find(".search-loading").toggle();d.find(".search-clear").toggle()}if(jQuery.type(q)==="string"){if(q==="toggle-loading"){i()}return d}if(jQuery.type(q)==="object"){q=jQuery.extend(true,{},h,q)}return d.addClass("search-input").prepend([m(),l(),o()])}jQuery.fn.extend({searchInput:function c(d){return this.each(function(){return a(this,d)})}})}());(function(){function c(o,n){this.currModeIndex=0;return this._init(o,n)}c.prototype.DATA_KEY="mode-button";c.prototype.defaults={switchModesOnClick:true};c.prototype._init=function j(o,n){n=n||{};this.$element=$(o);this.options=jQuery.extend(true,{},this.defaults,n);if(!n.modes){throw new Error('ModeButton requires a "modes" array')}var q=this;this.$element.click(function p(r){q.callModeFn();if(q.options.switchModesOnClick){q._incModeIndex()}$(this).html(q.options.modes[q.currModeIndex].html)});return this.reset()};c.prototype._incModeIndex=function l(){this.currModeIndex+=1;if(this.currModeIndex>=this.options.modes.length){this.currModeIndex=0}return this};c.prototype._getModeIndex=function f(n){for(var o=0;o<this.options.modes.length;o+=1){if(this.options.modes[o].mode===n){return o}}throw new Error("mode not found: "+n)};c.prototype._setModeByIndex=function m(n){var o=this.options.modes[n];if(!o){throw new Error("mode index not found: "+n)}this.currModeIndex=n;if(o.html){this.$element.html(o.html)}return this};c.prototype.currentMode=function d(){return this.options.modes[this.currModeIndex]};c.prototype.current=function i(){return this.currentMode().mode};c.prototype.getMode=function g(n){if(!n){return this.currentMode()}return this.options.modes[(this._getModeIndex(n))]};c.prototype.hasMode=function b(n){try{return !!this.getMode(n)}catch(o){}return false};c.prototype.setMode=function a(n){return this._setModeByIndex(this._getModeIndex(n))};c.prototype.reset=function h(){this.currModeIndex=0;if(this.options.initialMode){this.currModeIndex=this._getModeIndex(this.options.initialMode)}return this._setModeByIndex(this.currModeIndex)};c.prototype.callModeFn=function e(n){var o=this.getMode(n).onclick;if(o&&jQuery.type(o==="function")){return o.call(this.$element.get(0))}return undefined};jQuery.fn.extend({modeButton:function k(n){if(!this.size()){return this}if(jQuery.type(n)==="object"){return this.map(function(){var r=$(this);r.data("mode-button",new c(r,n));return this})}var p=$(this[0]),o=p.data("mode-button");if(!o){throw new Error("modeButton needs an options object or string name of a function")}if(o&&jQuery.type(n)==="string"){var q=n;if(o&&jQuery.type(o[q])==="function"){return o[q].apply(o,jQuery.makeArray(arguments).slice(1))}}return o}})}());function dropDownSelect(b,c){c=c||((!_.isEmpty(b))?(b[0]):(""));var a=$(['<div class="dropdown-select btn-group">','<button type="button" class="btn btn-default">','<span class="dropdown-select-selected">'+c+"</span>","</button>","</div>"].join("\n"));if(b&&b.length>1){a.find("button").addClass("dropdown-toggle").attr("data-toggle","dropdown").append(' <span class="caret"></span>');a.append(['<ul class="dropdown-menu" role="menu">',_.map(b,function(e){return['<li><a href="javascript:void(0)">',e,"</a></li>"].join("")}).join("\n"),"</ul>"].join("\n"))}function d(g){var h=$(this),f=h.parents(".dropdown-select"),e=h.text();f.find(".dropdown-select-selected").text(e);f.trigger("change.dropdown-select",e)}a.find("a").click(d);return a}(function(){function e(k,j){return this.init(k,j)}e.prototype.DATA_KEY="filter-control";e.prototype.init=function g(k,j){j=j||{filters:[]};this.$element=$(k).addClass("filter-control btn-group");this.options=jQuery.extend(true,{},this.defaults,j);this.currFilter=this.options.filters[0];return this.render()};e.prototype.render=function d(){this.$element.empty().append([this._renderKeySelect(),this._renderOpSelect(),this._renderValueInput()]);return this};e.prototype._renderKeySelect=function a(){var j=this;var k=this.options.filters.map(function(l){return l.key});this.$keySelect=dropDownSelect(k,this.currFilter.key).addClass("filter-control-key").on("change.dropdown-select",function(m,l){j.currFilter=_.findWhere(j.options.filters,{key:l});j.render()._triggerChange()});return this.$keySelect};e.prototype._renderOpSelect=function i(){var j=this,k=this.currFilter.ops;this.$opSelect=dropDownSelect(k,k[0]).addClass("filter-control-op").on("change.dropdown-select",function(m,l){j._triggerChange()});return this.$opSelect};e.prototype._renderValueInput=function c(){var j=this;if(this.currFilter.values){this.$valueSelect=dropDownSelect(this.currFilter.values,this.currFilter.values[0]).on("change.dropdown-select",function(l,k){j._triggerChange()})}else{this.$valueSelect=$("<input/>").addClass("form-control").on("change",function(k,l){j._triggerChange()})}this.$valueSelect.addClass("filter-control-value");return this.$valueSelect};e.prototype.val=function b(){var k=this.$element.find(".filter-control-key .dropdown-select-selected").text(),m=this.$element.find(".filter-control-op .dropdown-select-selected").text(),j=this.$element.find(".filter-control-value"),l=(j.hasClass("dropdown-select"))?(j.find(".dropdown-select-selected").text()):(j.val());return{key:k,op:m,value:l}};e.prototype._triggerChange=function h(){this.$element.trigger("change.filter-control",this.val())};jQuery.fn.extend({filterControl:function f(k){var j=jQuery.makeArray(arguments).slice(1);return this.map(function(){var n=$(this),m=n.data(e.prototype.DATA_KEY);if(jQuery.type(k)==="object"){m=new e(n,k);n.data(e.prototype.DATA_KEY,m)}if(m&&jQuery.type(k)==="string"){var l=m[k];if(jQuery.type(l)==="function"){return l.apply(m,j)}}return this})}})}());(function(){function i(o,n){this.numPages=null;this.currPage=0;return this.init(o,n)}i.prototype.DATA_KEY="pagination";i.prototype.defaults={startingPage:0,perPage:20,totalDataSize:null,currDataSize:null};i.prototype.init=function g(n,o){o=o||{};this.$element=n;this.options=jQuery.extend(true,{},this.defaults,o);this.currPage=this.options.startingPage;if(this.options.totalDataSize!==null){this.numPages=Math.ceil(this.options.totalDataSize/this.options.perPage);if(this.currPage>=this.numPages){this.currPage=this.numPages-1}}this.$element.data(i.prototype.DATA_KEY,this);this._render();return this};function m(n){return $(['<li><a href="javascript:void(0);">',n,"</a></li>"].join(""))}i.prototype._render=function e(){if(this.options.totalDataSize===0){return this}if(this.numPages===1){return this}if(this.numPages>0){this._renderPages();this._scrollToActivePage()}else{this._renderPrevNext()}return this};i.prototype._renderPrevNext=function b(){var o=this,p=m("Prev"),n=m("Next"),q=$("<ul/>").addClass("pagination pagination-prev-next");if(this.currPage===0){p.addClass("disabled")}else{p.click(function(){o.prevPage()})}if((this.numPages&&this.currPage===(this.numPages-1))||(this.options.currDataSize&&this.options.currDataSize<this.options.perPage)){n.addClass("disabled")}else{n.click(function(){o.nextPage()})}this.$element.html(q.append([p,n]));return this.$element};i.prototype._renderPages=function a(){var n=this,q=$("<div>").addClass("pagination-scroll-container"),s=$("<ul/>").addClass("pagination pagination-page-list"),r=function(t){n.goToPage($(this).data("page"))};for(var o=0;o<this.numPages;o+=1){var p=m(o+1).attr("data-page",o).click(r);if(o===this.currPage){p.addClass("active")}s.append(p)}return this.$element.html(q.html(s))};i.prototype._scrollToActivePage=function l(){var p=this.$element.find(".pagination-scroll-container");if(!p.size()){return this}var o=this.$element.find("li.active"),n=p.width()/2;p.scrollLeft(p.scrollLeft()+o.position().left-n);return this};i.prototype.goToPage=function j(n){if(n<=0){n=0}if(this.numPages&&n>=this.numPages){n=this.numPages-1}if(n===this.currPage){return this}this.currPage=n;this.$element.trigger("pagination.page-change",this.currPage);this._render();return this};i.prototype.prevPage=function c(){return this.goToPage(this.currPage-1)};i.prototype.nextPage=function h(){return this.goToPage(this.currPage+1)};i.prototype.page=function f(){return this.currPage};i.create=function k(n,o){return new i(n,o)};jQuery.fn.extend({pagination:function d(o){var n=jQuery.makeArray(arguments).slice(1);if(jQuery.type(o)==="object"){return this.map(function(){i.create($(this),o);return this})}var q=$(this[0]),r=q.data(i.prototype.DATA_KEY);if(r){if(jQuery.type(o)==="string"){var p=r[o];if(jQuery.type(p)==="function"){return p.apply(r,n)}}else{return r}}return undefined}})}());(function(){var g={renameColumns:false,columnNames:[],commentChar:"#",hideCommentRows:false,includePrompts:true,topLeftContent:"Columns:"},s="peek-control.change",t="peek-control.rename",l="peek-control",v="control",f="control-prompt",c="selected",n="disabled",u="button",q="renamable-header",p="column-index",a="column-name";function i(w){if(w.disabled&&jQuery.type(w.disabled)!=="array"){throw new Error('"disabled" must be defined as an array of indeces: '+JSON.stringify(w))}if(w.multiselect&&w.selected&&jQuery.type(w.selected)!=="array"){throw new Error('Mulitselect rows need an array for "selected": '+JSON.stringify(w))}if(!w.label||!w.id){throw new Error("Peek controls need a label and id for each control row: "+JSON.stringify(w))}if(w.disabled&&w.disabled.indexOf(w.selected)!==-1){throw new Error("Selected column is in the list of disabled columns: "+JSON.stringify(w))}return w}function o(x,w){return $("<div/>").addClass(u).text(x.label)}function k(x,w){var y=$("<td/>").html(o(x,w)).attr("data-"+p,w);if(x.disabled&&x.disabled.indexOf(w)!==-1){y.addClass(n)}return y}function e(y,z,w){var x=y.children("."+u);if(y.hasClass(c)){x.html((z.selectedText!==undefined)?(z.selectedText):(z.label))}else{x.html((z.unselectedText!==undefined)?(z.unselectedText):(z.label))}}function h(z,x){var y=k(z,x);if(z.selected===x){y.addClass(c)}e(y,z,x);if(!y.hasClass(n)){y.click(function w(D){var E=$(this);if(!E.hasClass(c)){var A=E.parent().children("."+c).removeClass(c);A.each(function(){e($(this),z,x)});E.addClass(c);e(E,z,x);var C={},B=E.parent().attr("id"),F=E.data(p);C[B]=F;E.parents(".peek").trigger(s,C)}})}return y}function m(z,x){var y=k(z,x);if(z.selected&&z.selected.indexOf(x)!==-1){y.addClass(c)}e(y,z,x);if(!y.hasClass(n)){y.click(function w(D){var E=$(this);E.toggleClass(c);e(E,z,x);var C=E.parent().find("."+c).map(function(G,H){return $(H).data(p)});var B={},A=E.parent().attr("id"),F=jQuery.makeArray(C);B[A]=F;E.parents(".peek").trigger(s,B)})}return y}function j(y,z){var w=[];for(var x=0;x<y;x+=1){w.push(z.multiselect?m(z,x):h(z,x))}return w}function r(y,z,x){var A=$("<tr/>").attr("id",z.id).addClass(v);if(x){var w=$("<td/>").addClass(f).text(z.label+":");A.append(w)}A.append(j(y,z));return A}function b(E){E=jQuery.extend(true,{},g,E);var D=$(this).addClass(l),A=D.find("table"),z=A.find("th").size(),C=A.find("tr").size(),w=A.find("td[colspan]").map(function(H,F){var G=$(this);if(G.text()&&G.text().match(new RegExp("^"+E.commentChar))){return $(this).css("color","grey").parent().get(0)}return null});if(E.hideCommentRows){w.hide();C-=w.size()}if(E.includePrompts){var y=$("<th/>").addClass("top-left").text(E.topLeftContent).attr("rowspan",C);A.find("tr").first().prepend(y)}var B=A.find("th:not(.top-left)").each(function(G,I){var H=$(this),J=H.text().replace(/^\d+\.*/,""),F=E.columnNames[G]||J;H.attr("data-"+a,F).text((G+1)+((F)?("."+F):("")))});if(E.renameColumns){B.addClass(q).click(function x(){var G=$(this),F=G.index()+(E.includePrompts?0:1),I=G.data(a),H=prompt("New column name:",I);if(H!==null&&H!==I){G.text(F+(H?("."+H):"")).data(a,H).attr("data-",a,H);var J=jQuery.makeArray(G.parent().children("th:not(.top-left)").map(function(){return $(this).data(a)}));G.parents(".peek").trigger(t,J)}})}E.controls.forEach(function(G,F){i(G);var H=r(z,G,E.includePrompts);A.find("tbody").append(H)});return this}jQuery.fn.extend({peekControl:function d(w){return this.map(function(){return b.call(this,w)})}})}()); \ 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;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},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="'+d.target+'"'):(""),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 c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},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.create=function _create(b,a){return new PopupMenu(b,a)};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.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&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};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";a.parent().find(".loading-indicator").remove();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}(function(){var b=window._l||function(d){return d};function a(k,q){var e=27,n=13,d=$(k),f=true,h={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(r){},minSearchLen:0,escWillClear:true,oninit:function(){}};function j(r){var s=$(this).parent().children("input");s.val("");s.trigger("clear:searchInput");q.onclear()}function p(s,r){$(this).trigger("search:searchInput",r);if(typeof q.onfirstsearch==="function"&&f){f=false;q.onfirstsearch(r)}else{q.onsearch(r)}}function g(){return['<input type="text" name="',q.name,'" placeholder="',q.placeholder,'" ','class="search-query ',q.classes,'" ',"/>"].join("")}function m(){return $(g()).focus(function(r){$(this).select()}).keyup(function(s){s.preventDefault();s.stopPropagation();if(!$(this).val()){$(this).blur()}if(s.which===e&&q.escWillClear){j.call(this,s)}else{var r=$(this).val();if((s.which===n)||(q.minSearchLen&&r.length>=q.minSearchLen)){p.call(this,s,r)}else{if(!r.length){j.call(this,s)}}}}).val(q.initialVal)}function l(){return $(['<span class="search-clear fa fa-times-circle" ','title="',b("clear search (esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(r){j.call(this,r)})}function o(){return $(['<span class="search-loading fa fa-spinner fa-spin" ','title="',b("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function i(){d.find(".search-loading").toggle();d.find(".search-clear").toggle()}if(jQuery.type(q)==="string"){if(q==="toggle-loading"){i()}return d}if(jQuery.type(q)==="object"){q=jQuery.extend(true,{},h,q)}return d.addClass("search-input").prepend([m(),l(),o()])}jQuery.fn.extend({searchInput:function c(d){return this.each(function(){return a(this,d)})}})}());(function(){function c(o,n){this.currModeIndex=0;return this._init(o,n)}c.prototype.DATA_KEY="mode-button";c.prototype.defaults={switchModesOnClick:true};c.prototype._init=function j(o,n){n=n||{};this.$element=$(o);this.options=jQuery.extend(true,{},this.defaults,n);if(!n.modes){throw new Error('ModeButton requires a "modes" array')}var q=this;this.$element.click(function p(r){q.callModeFn();if(q.options.switchModesOnClick){q._incModeIndex()}$(this).html(q.options.modes[q.currModeIndex].html)});return this.reset()};c.prototype._incModeIndex=function l(){this.currModeIndex+=1;if(this.currModeIndex>=this.options.modes.length){this.currModeIndex=0}return this};c.prototype._getModeIndex=function f(n){for(var o=0;o<this.options.modes.length;o+=1){if(this.options.modes[o].mode===n){return o}}throw new Error("mode not found: "+n)};c.prototype._setModeByIndex=function m(n){var o=this.options.modes[n];if(!o){throw new Error("mode index not found: "+n)}this.currModeIndex=n;if(o.html){this.$element.html(o.html)}return this};c.prototype.currentMode=function d(){return this.options.modes[this.currModeIndex]};c.prototype.current=function i(){return this.currentMode().mode};c.prototype.getMode=function g(n){if(!n){return this.currentMode()}return this.options.modes[(this._getModeIndex(n))]};c.prototype.hasMode=function b(n){try{return !!this.getMode(n)}catch(o){}return false};c.prototype.setMode=function a(n){return this._setModeByIndex(this._getModeIndex(n))};c.prototype.reset=function h(){this.currModeIndex=0;if(this.options.initialMode){this.currModeIndex=this._getModeIndex(this.options.initialMode)}return this._setModeByIndex(this.currModeIndex)};c.prototype.callModeFn=function e(n){var o=this.getMode(n).onclick;if(o&&jQuery.type(o==="function")){return o.call(this.$element.get(0))}return undefined};jQuery.fn.extend({modeButton:function k(n){if(!this.size()){return this}if(jQuery.type(n)==="object"){return this.map(function(){var r=$(this);r.data("mode-button",new c(r,n));return this})}var p=$(this[0]),o=p.data("mode-button");if(!o){throw new Error("modeButton needs an options object or string name of a function")}if(o&&jQuery.type(n)==="string"){var q=n;if(o&&jQuery.type(o[q])==="function"){return o[q].apply(o,jQuery.makeArray(arguments).slice(1))}}return o}})}());function dropDownSelect(b,c){c=c||((!_.isEmpty(b))?(b[0]):(""));var a=$(['<div class="dropdown-select btn-group">','<button type="button" class="btn btn-default">','<span class="dropdown-select-selected">'+c+"</span>","</button>","</div>"].join("\n"));if(b&&b.length>1){a.find("button").addClass("dropdown-toggle").attr("data-toggle","dropdown").append(' <span class="caret"></span>');a.append(['<ul class="dropdown-menu" role="menu">',_.map(b,function(e){return['<li><a href="javascript:void(0)">',e,"</a></li>"].join("")}).join("\n"),"</ul>"].join("\n"))}function d(g){var h=$(this),f=h.parents(".dropdown-select"),e=h.text();f.find(".dropdown-select-selected").text(e);f.trigger("change.dropdown-select",e)}a.find("a").click(d);return a}(function(){function e(k,j){return this.init(k,j)}e.prototype.DATA_KEY="filter-control";e.prototype.init=function g(k,j){j=j||{filters:[]};this.$element=$(k).addClass("filter-control btn-group");this.options=jQuery.extend(true,{},this.defaults,j);this.currFilter=this.options.filters[0];return this.render()};e.prototype.render=function d(){this.$element.empty().append([this._renderKeySelect(),this._renderOpSelect(),this._renderValueInput()]);return this};e.prototype._renderKeySelect=function a(){var j=this;var k=this.options.filters.map(function(l){return l.key});this.$keySelect=dropDownSelect(k,this.currFilter.key).addClass("filter-control-key").on("change.dropdown-select",function(m,l){j.currFilter=_.findWhere(j.options.filters,{key:l});j.render()._triggerChange()});return this.$keySelect};e.prototype._renderOpSelect=function i(){var j=this,k=this.currFilter.ops;this.$opSelect=dropDownSelect(k,k[0]).addClass("filter-control-op").on("change.dropdown-select",function(m,l){j._triggerChange()});return this.$opSelect};e.prototype._renderValueInput=function c(){var j=this;if(this.currFilter.values){this.$valueSelect=dropDownSelect(this.currFilter.values,this.currFilter.values[0]).on("change.dropdown-select",function(l,k){j._triggerChange()})}else{this.$valueSelect=$("<input/>").addClass("form-control").on("change",function(k,l){j._triggerChange()})}this.$valueSelect.addClass("filter-control-value");return this.$valueSelect};e.prototype.val=function b(){var k=this.$element.find(".filter-control-key .dropdown-select-selected").text(),m=this.$element.find(".filter-control-op .dropdown-select-selected").text(),j=this.$element.find(".filter-control-value"),l=(j.hasClass("dropdown-select"))?(j.find(".dropdown-select-selected").text()):(j.val());return{key:k,op:m,value:l}};e.prototype._triggerChange=function h(){this.$element.trigger("change.filter-control",this.val())};jQuery.fn.extend({filterControl:function f(k){var j=jQuery.makeArray(arguments).slice(1);return this.map(function(){var n=$(this),m=n.data(e.prototype.DATA_KEY);if(jQuery.type(k)==="object"){m=new e(n,k);n.data(e.prototype.DATA_KEY,m)}if(m&&jQuery.type(k)==="string"){var l=m[k];if(jQuery.type(l)==="function"){return l.apply(m,j)}}return this})}})}());(function(){function i(o,n){this.numPages=null;this.currPage=0;return this.init(o,n)}i.prototype.DATA_KEY="pagination";i.prototype.defaults={startingPage:0,perPage:20,totalDataSize:null,currDataSize:null};i.prototype.init=function g(n,o){o=o||{};this.$element=n;this.options=jQuery.extend(true,{},this.defaults,o);this.currPage=this.options.startingPage;if(this.options.totalDataSize!==null){this.numPages=Math.ceil(this.options.totalDataSize/this.options.perPage);if(this.currPage>=this.numPages){this.currPage=this.numPages-1}}this.$element.data(i.prototype.DATA_KEY,this);this._render();return this};function m(n){return $(['<li><a href="javascript:void(0);">',n,"</a></li>"].join(""))}i.prototype._render=function e(){if(this.options.totalDataSize===0){return this}if(this.numPages===1){return this}if(this.numPages>0){this._renderPages();this._scrollToActivePage()}else{this._renderPrevNext()}return this};i.prototype._renderPrevNext=function b(){var o=this,p=m("Prev"),n=m("Next"),q=$("<ul/>").addClass("pagination pagination-prev-next");if(this.currPage===0){p.addClass("disabled")}else{p.click(function(){o.prevPage()})}if((this.numPages&&this.currPage===(this.numPages-1))||(this.options.currDataSize&&this.options.currDataSize<this.options.perPage)){n.addClass("disabled")}else{n.click(function(){o.nextPage()})}this.$element.html(q.append([p,n]));return this.$element};i.prototype._renderPages=function a(){var n=this,q=$("<div>").addClass("pagination-scroll-container"),s=$("<ul/>").addClass("pagination pagination-page-list"),r=function(t){n.goToPage($(this).data("page"))};for(var o=0;o<this.numPages;o+=1){var p=m(o+1).attr("data-page",o).click(r);if(o===this.currPage){p.addClass("active")}s.append(p)}return this.$element.html(q.html(s))};i.prototype._scrollToActivePage=function l(){var p=this.$element.find(".pagination-scroll-container");if(!p.size()){return this}var o=this.$element.find("li.active"),n=p.width()/2;p.scrollLeft(p.scrollLeft()+o.position().left-n);return this};i.prototype.goToPage=function j(n){if(n<=0){n=0}if(this.numPages&&n>=this.numPages){n=this.numPages-1}if(n===this.currPage){return this}this.currPage=n;this.$element.trigger("pagination.page-change",this.currPage);this._render();return this};i.prototype.prevPage=function c(){return this.goToPage(this.currPage-1)};i.prototype.nextPage=function h(){return this.goToPage(this.currPage+1)};i.prototype.page=function f(){return this.currPage};i.create=function k(n,o){return new i(n,o)};jQuery.fn.extend({pagination:function d(o){var n=jQuery.makeArray(arguments).slice(1);if(jQuery.type(o)==="object"){return this.map(function(){i.create($(this),o);return this})}var q=$(this[0]),r=q.data(i.prototype.DATA_KEY);if(r){if(jQuery.type(o)==="string"){var p=r[o];if(jQuery.type(p)==="function"){return p.apply(r,n)}}else{return r}}return undefined}})}());(function(){var g={renameColumns:false,columnNames:[],commentChar:"#",hideCommentRows:false,includePrompts:true,topLeftContent:"Columns:"},s="peek-control.change",t="peek-control.rename",l="peek-control",v="control",f="control-prompt",c="selected",n="disabled",u="button",q="renamable-header",p="column-index",a="column-name";function i(w){if(w.disabled&&jQuery.type(w.disabled)!=="array"){throw new Error('"disabled" must be defined as an array of indeces: '+JSON.stringify(w))}if(w.multiselect&&w.selected&&jQuery.type(w.selected)!=="array"){throw new Error('Mulitselect rows need an array for "selected": '+JSON.stringify(w))}if(!w.label||!w.id){throw new Error("Peek controls need a label and id for each control row: "+JSON.stringify(w))}if(w.disabled&&w.disabled.indexOf(w.selected)!==-1){throw new Error("Selected column is in the list of disabled columns: "+JSON.stringify(w))}return w}function o(x,w){return $("<div/>").addClass(u).text(x.label)}function k(x,w){var y=$("<td/>").html(o(x,w)).attr("data-"+p,w);if(x.disabled&&x.disabled.indexOf(w)!==-1){y.addClass(n)}return y}function e(y,z,w){var x=y.children("."+u);if(y.hasClass(c)){x.html((z.selectedText!==undefined)?(z.selectedText):(z.label))}else{x.html((z.unselectedText!==undefined)?(z.unselectedText):(z.label))}}function h(z,x){var y=k(z,x);if(z.selected===x){y.addClass(c)}e(y,z,x);if(!y.hasClass(n)){y.click(function w(D){var E=$(this);if(!E.hasClass(c)){var A=E.parent().children("."+c).removeClass(c);A.each(function(){e($(this),z,x)});E.addClass(c);e(E,z,x);var C={},B=E.parent().attr("id"),F=E.data(p);C[B]=F;E.parents(".peek").trigger(s,C)}})}return y}function m(z,x){var y=k(z,x);if(z.selected&&z.selected.indexOf(x)!==-1){y.addClass(c)}e(y,z,x);if(!y.hasClass(n)){y.click(function w(D){var E=$(this);E.toggleClass(c);e(E,z,x);var C=E.parent().find("."+c).map(function(G,H){return $(H).data(p)});var B={},A=E.parent().attr("id"),F=jQuery.makeArray(C);B[A]=F;E.parents(".peek").trigger(s,B)})}return y}function j(y,z){var w=[];for(var x=0;x<y;x+=1){w.push(z.multiselect?m(z,x):h(z,x))}return w}function r(y,z,x){var A=$("<tr/>").attr("id",z.id).addClass(v);if(x){var w=$("<td/>").addClass(f).text(z.label+":");A.append(w)}A.append(j(y,z));return A}function b(E){E=jQuery.extend(true,{},g,E);var D=$(this).addClass(l),A=D.find("table"),z=A.find("th").size(),C=A.find("tr").size(),w=A.find("td[colspan]").map(function(H,F){var G=$(this);if(G.text()&&G.text().match(new RegExp("^"+E.commentChar))){return $(this).css("color","grey").parent().get(0)}return null});if(E.hideCommentRows){w.hide();C-=w.size()}if(E.includePrompts){var y=$("<th/>").addClass("top-left").text(E.topLeftContent).attr("rowspan",C);A.find("tr").first().prepend(y)}var B=A.find("th:not(.top-left)").each(function(G,I){var H=$(this),J=H.text().replace(/^\d+\.*/,""),F=E.columnNames[G]||J;H.attr("data-"+a,F).text((G+1)+((F)?("."+F):("")))});if(E.renameColumns){B.addClass(q).click(function x(){var G=$(this),F=G.index()+(E.includePrompts?0:1),I=G.data(a),H=prompt("New column name:",I);if(H!==null&&H!==I){G.text(F+(H?("."+H):"")).data(a,H).attr("data-",a,H);var J=jQuery.makeArray(G.parent().children("th:not(.top-left)").map(function(){return $(this).data(a)}));G.parents(".peek").trigger(t,J)}})}E.controls.forEach(function(G,F){i(G);var H=r(z,G,E.includePrompts);A.find("tbody").append(H)});return this}jQuery.fn.extend({peekControl:function d(w){return this.map(function(){return b.call(this,w)})}})}()); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/packed/mvc/ui/ui-misc.js --- a/static/scripts/packed/mvc/ui/ui-misc.js +++ b/static/scripts/packed/mvc/ui/ui-misc.js @@ -1,1 +1,1 @@ -define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-checkbox","mvc/ui/ui-radiobutton","mvc/ui/ui-button-menu","mvc/ui/ui-modal"],function(l,b,e,m,p,n){var d=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(q){this.options=l.merge(q,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(q){return'<img class="ui-image '+q.cls+'" src="'+q.url+'"/>'}});var k=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(q){this.options=l.merge(q,this.optionsDefault);this.setElement(this._template(this.options))},title:function(q){this.$el.html(q)},_template:function(q){return'<label class="ui-label '+q.cls+'">'+q.title+"</label>"},value:function(){return options.title}});var c=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(q){this.options=l.merge(q,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:q.tooltip,placement:"bottom"})},_template:function(q){return'<div><span class="fa '+q.icon+'" class="ui-icon"/> '+q.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"btn btn-default",icon:""},initialize:function(q){this.options=l.merge(q,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",q.onclick);$(this.el).tooltip({title:q.tooltip,placement:"bottom"})},_template:function(q){var r='<button id="'+q.id+'" type="submit" style="float: '+q.floating+';" type="button" class="ui-button '+q.cls+'">';if(q.icon){r+='<i class="icon fa '+q.icon+'"></i> '}r+=q.title+"</button>";return r}});var h=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"icon-btn",icon:"",tooltip:"",onclick:null},initialize:function(q){this.options=l.merge(q,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",q.onclick);$(this.el).tooltip({title:q.tooltip,placement:"bottom"})},_template:function(q){var r="";if(q.title){r="width: auto;"}var s='<div id="'+q.id+'" style="float: '+q.floating+"; "+r+'" class="ui-button-icon '+q.cls+'">';if(q.title){s+='<div class="button"><i class="icon fa '+q.icon+'"/> <span class="title">'+q.title+"</span></div>"}else{s+='<i class="icon fa '+q.icon+'"/>'}s+="</div>";return s}});var f=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(q){this.options=l.merge(q,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",q.onclick)},_template:function(q){return'<div><a href="javascript:void(0)" class="ui-anchor '+q.cls+'">'+q.title+"</a></div>"}});var o=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:false},initialize:function(q){this.options=l.merge(q,this.optionsDefault);this.setElement("<div></div>")},update:function(r){this.options=l.merge(r,this.optionsDefault);if(r.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(r.message);this.$el.fadeIn();if(!r.persistent){var q=this;window.setTimeout(function(){if(q.$el.is(":visible")){q.$el.fadeOut()}else{q.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(q){return'<div class="ui-message alert alert-'+q.status+'"/>'}});var a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));var q=this;if(this.options.onclick){this.$el.on("submit",function(t){var s=q.$el.find("#search");q.options.onclick(s.val())})}},_template:function(q){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+q.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var j=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var q=this;this.$el.on("input",function(){if(q.options.onchange){q.options.onchange(q.$el.val())}})},value:function(q){if(q!==undefined){this.$el.val(q)}return this.$el.val()},_template:function(q){return'<input id="'+q.id+'" type="'+q.type+'" value="'+q.value+'" placeholder="'+q.placeholder+'" class="ui-input '+q.cls+'">'}});var i=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var q=this;this.$el.on("input",function(){if(q.options.onchange){q.options.onchange(q.$el.val())}})},value:function(q){if(q!==undefined){this.$el.val(q)}return this.$el.val()},_template:function(q){return'<textarea id="'+q.id+'" class="ui-textarea '+q.cls+'" rows="5"></textarea>'}});return{Anchor:f,Button:g,ButtonIcon:h,ButtonMenu:p,Icon:c,Image:d,Input:j,Label:k,Message:o,Modal:n,RadioButton:m,Checkbox:e,Searchbox:a,Select:b,Textarea:i}}); \ No newline at end of file +define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-checkbox","mvc/ui/ui-radiobutton","mvc/ui/ui-button-menu","mvc/ui/ui-modal"],function(l,b,e,m,q,n){var d=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},_template:function(r){return'<img class="ui-image '+r.cls+'" src="'+r.url+'"/>'}});var k=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},title:function(r){this.$el.html(r)},_template:function(r){return'<label class="ui-label '+r.cls+'">'+r.title+"</label>"},value:function(){return options.title}});var c=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){return'<div><span class="fa '+r.icon+'" class="ui-icon"/> '+r.title+"</div>"}});var g=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"btn btn-default",icon:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick);$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){var s='<button id="'+r.id+'" type="submit" style="float: '+r.floating+';" type="button" class="ui-button '+r.cls+'">';if(r.icon){s+='<i class="icon fa '+r.icon+'"></i> '}s+=r.title+"</button>";return s}});var h=Backbone.View.extend({optionsDefault:{id:null,title:"",floating:"right",cls:"icon-btn",icon:"",tooltip:"",onclick:null},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick);$(this.el).tooltip({title:r.tooltip,placement:"bottom"})},_template:function(r){var s="";if(r.title){s="width: auto;"}var t='<div id="'+r.id+'" style="float: '+r.floating+"; "+s+'" class="ui-button-icon '+r.cls+'">';if(r.title){t+='<div class="button"><i class="icon fa '+r.icon+'"/> <span class="title">'+r.title+"</span></div>"}else{t+='<i class="icon fa '+r.icon+'"/>'}t+="</div>";return t}});var f=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options));$(this.el).on("click",r.onclick)},_template:function(r){return'<div><a href="javascript:void(0)" class="ui-anchor '+r.cls+'">'+r.title+"</a></div>"}});var o=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:false},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement("<div></div>")},update:function(s){this.options=l.merge(s,this.optionsDefault);if(s.message!=""){this.$el.html(this._template(this.options));this.$el.find(".alert").append(s.message);this.$el.fadeIn();if(!s.persistent){var r=this;window.setTimeout(function(){if(r.$el.is(":visible")){r.$el.fadeOut()}else{r.$el.hide()}},3000)}}else{this.$el.fadeOut()}},_template:function(r){return'<div class="ui-message alert alert-'+r.status+'"/>'}});var a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(s){this.options=l.merge(s,this.optionsDefault);this.setElement(this._template(this.options));var r=this;if(this.options.onclick){this.$el.on("submit",function(u){var t=r.$el.find("#search");r.options.onclick(t.val())})}},_template:function(r){return'<div class="ui-search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+r.searchword+'"><button type="submit" class="btn search-btn"><i class="fa fa-search"></i></button></form></div>'}});var j=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(s){this.options=l.merge(s,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var r=this;this.$el.on("input",function(){if(r.options.onchange){r.options.onchange(r.$el.val())}})},value:function(r){if(r!==undefined){this.$el.val(r)}return this.$el.val()},_template:function(r){return'<input id="'+r.id+'" type="'+r.type+'" value="'+r.value+'" placeholder="'+r.placeholder+'" class="ui-input '+r.cls+'">'}});var i=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:false,visible:true,cls:""},initialize:function(s){this.options=l.merge(s,this.optionsDefault);this.setElement(this._template(this.options));if(this.options.disabled){this.$el.prop("disabled",true)}if(!this.options.visible){this.$el.hide()}var r=this;this.$el.on("input",function(){if(r.options.onchange){r.options.onchange(r.$el.val())}})},value:function(r){if(r!==undefined){this.$el.val(r)}return this.$el.val()},_template:function(r){return'<textarea id="'+r.id+'" class="ui-textarea '+r.cls+'" rows="5"></textarea>'}});var p=Backbone.View.extend({optionsDefault:{value:""},initialize:function(r){this.options=l.merge(r,this.optionsDefault);this.setElement(this._template(this.options))},value:function(r){if(r!==undefined){this.$el.val(r)}return this.$el.val()},_template:function(r){return'<hidden id="'+r.id+'" value="'+r.value+'"/>'}});return{Anchor:f,Button:g,ButtonIcon:h,ButtonMenu:q,Icon:c,Image:d,Input:j,Label:k,Message:o,Modal:n,RadioButton:m,Checkbox:e,Searchbox:a,Select:b,Textarea:i,Hidden:p}}); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/packed/mvc/ui/ui-table.js --- a/static/scripts/packed/mvc/ui/ui-table.js +++ b/static/scripts/packed/mvc/ui/ui-table.js @@ -1,1 +1,1 @@ -define(["utils/utils"],function(a){var b=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null,cls:"ui-table"},events:{click:"_onclick",dblclick:"_ondblclick"},initialize:function(c){this.options=a.merge(c,this.optionsDefault);var d=$(this._template(this.options));this.$thead=d.find("thead");this.$tbody=d.find("tbody");this.$tmessage=d.find("tmessage");this.setElement(d);this.row=$("<tr></tr>")},addHeader:function(c){var d=$("<th></th>");d.append(c);this.row.append(d)},appendHeader:function(){this.$thead.append(this.row);this.row=$("<tr></tr>")},add:function(c,d,f){var e=$("<td></td>");if(d){e.css("width",d)}if(f){e.css("text-align",f)}e.append(c);this.row.append(e)},append:function(c){this._commit(c)},prepend:function(c){this._commit(c,true)},get:function(c){return this.$el.find("#"+c)},del:function(d){var c=this.$tbody.find("#"+d);if(c.length>0){c.remove();this.row_count--;this._refresh()}},delAll:function(){this.$tbody.empty();this.row_count=0;this._refresh()},value:function(c){this.before=this.$tbody.find(".current").attr("id");if(c!==undefined){this.$tbody.find("tr").removeClass("current");if(c){this.$tbody.find("#"+c).addClass("current")}}var d=this.$tbody.find(".current").attr("id");if(d===undefined){return null}else{if(d!=this.before&&this.options.onchange){this.options.onchange(c)}return d}},size:function(){return this.$tbody.find("tr").length},_commit:function(d,c){this.del(d);this.row.attr("id",d);if(c){this.$tbody.prepend(this.row)}else{this.$tbody.append(this.row)}this.row=$("<tr></tr>");this.row_count++;this._refresh()},_onclick:function(f){var c=this.value();var d=$(f.target).closest("tr").attr("id");if(d!=""){if(d&&c!=d){if(this.options.onconfirm){this.options.onconfirm(d)}else{this.value(d)}}}},_ondblclick:function(d){var c=this.value();if(c&&this.options.ondblclick){this.options.ondblclick(c)}},_refresh:function(){if(this.row_count==0){this.$tmessage.show()}else{this.$tmessage.hide()}},_template:function(c){return'<div><table class="'+c.cls+'"><thead></thead><tbody></tbody></table><tmessage>'+c.content+"</tmessage><div>"}});return{View:b}}); \ No newline at end of file +define(["utils/utils"],function(a){var b=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null,cls:"ui-table",cls_tr:""},events:{click:"_onclick",dblclick:"_ondblclick"},initialize:function(c){this.options=a.merge(c,this.optionsDefault);var d=$(this._template(this.options));this.$thead=d.find("thead");this.$tbody=d.find("tbody");this.$tmessage=d.find("tmessage");this.setElement(d);this.row=this._row()},addHeader:function(c){var d=$("<th></th>");d.append(c);this.row.append(d)},appendHeader:function(){this.$thead.append(this.row);this.row=$("<tr></tr>")},add:function(c,d,f){var e=$("<td></td>");if(d){e.css("width",d)}if(f){e.css("text-align",f)}e.append(c);this.row.append(e)},append:function(c){this._commit(c)},prepend:function(c){this._commit(c,true)},get:function(c){return this.$el.find("#"+c)},del:function(d){var c=this.$tbody.find("#"+d);if(c.length>0){c.remove();this.row_count--;this._refresh()}},delAll:function(){this.$tbody.empty();this.row_count=0;this._refresh()},value:function(c){this.before=this.$tbody.find(".current").attr("id");if(c!==undefined){this.$tbody.find("tr").removeClass("current");if(c){this.$tbody.find("#"+c).addClass("current")}}var d=this.$tbody.find(".current").attr("id");if(d===undefined){return null}else{if(d!=this.before&&this.options.onchange){this.options.onchange(c)}return d}},size:function(){return this.$tbody.find("tr").length},_commit:function(d,c){this.del(d);this.row.attr("id",d);if(c){this.$tbody.prepend(this.row)}else{this.$tbody.append(this.row)}this.row=this._row();this.row_count++;this._refresh()},_row:function(){return $('<tr class="'+this.options.cls_tr+'"></tr>')},_onclick:function(f){var c=this.value();var d=$(f.target).closest("tr").attr("id");if(d!=""){if(d&&c!=d){if(this.options.onconfirm){this.options.onconfirm(d)}else{this.value(d)}}}},_ondblclick:function(d){var c=this.value();if(c&&this.options.ondblclick){this.options.ondblclick(c)}},_refresh:function(){if(this.row_count==0){this.$tmessage.show()}else{this.$tmessage.hide()}},_template:function(c){return'<div><table class="'+c.cls+'"><thead></thead><tbody></tbody></table><tmessage>'+c.content+"</tmessage><div>"}});return{View:b}}); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/scripts/packed/mvc/ui/ui-tabs.js --- a/static/scripts/packed/mvc/ui/ui-tabs.js +++ b/static/scripts/packed/mvc/ui/ui-tabs.js @@ -1,1 +1,1 @@ -define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(e){this.visible=false;this.$nav=null;this.$content=null;this.first_tab=null;this.options=a.merge(e,this.optionsDefault);var c=$(this._template(this.options));this.$nav=c.find(".tab-navigation");this.$content=c.find(".tab-content");this.setElement(c);this.list={};var d=this;if(this.options.operations){$.each(this.options.operations,function(g,h){h.$el.prop("id",g);d.$nav.find(".operations").append(h.$el)})}if(this.options.onnew){var f=$(this._template_tab_new(this.options));this.$nav.append(f);f.tooltip({title:"Add a new tab",placement:"bottom",container:d.$el});f.on("click",function(g){f.tooltip("hide");d.options.onnew()})}},size:function(){return _.size(this.list)},add:function(f){var e=this;var h=f.id;var g=$(this._template_tab(f));var d=$(this._template_tab_content(f));this.list[h]=f.ondel?true:false;if(this.options.onnew){this.$nav.find("#new-tab").before(g)}else{this.$nav.append(g)}d.append(f.$el);this.$content.append(d);if(_.size(this.list)==1){g.addClass("active");d.addClass("active");this.first_tab=h}if(f.ondel){var c=g.find("#delete");c.tooltip({title:"Delete this tab",placement:"bottom",container:e.$el});c.on("click",function(){c.tooltip("destroy");e.$el.find(".tooltip").remove();f.ondel();return false})}g.on("click",function(i){i.preventDefault();if(f.onclick){f.onclick()}else{e.show(h)}})},del:function(c){this.$el.find("#tab-"+c).remove();this.$el.find("#tab-content-"+c).remove();if(this.first_tab==c){this.first_tab=null}if(this.first_tab!=null){this.show(this.first_tab)}},delRemovable:function(){for(var c in this.list){if(this.list[c]){this.del(c)}}},show:function(c){this.$el.fadeIn("fast");this.visible=true;if(c){this.$el.find(".tab-element").removeClass("active");this.$el.find(".tab-pane").removeClass("active");this.$el.find("#tab-"+c).addClass("active");this.$el.find("#tab-content-"+c).addClass("active")}},hide:function(){this.$el.fadeOut("fast");this.visible=false},hideOperation:function(c){this.$nav.find("#"+c).hide()},showOperation:function(c){this.$nav.find("#"+c).show()},setOperation:function(e,d){var c=this.$nav.find("#"+e);c.off("click");c.on("click",d)},title:function(e,d){var c=this.$el.find("#tab-title-text-"+e);if(d){c.html(d)}return c.html()},_template:function(c){return'<div class="ui-tabs tabbable tabs-left"><ul id="tab-navigation" class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div id="tab-content" class="tab-content"/></div>'},_template_tab_new:function(c){return'<li id="new-tab"><a href="javascript:void(0);"><i class="ui-tabs-add fa fa-plus-circle"/>'+c.title_new+"</a></li>"},_template_tab:function(d){var c='<li id="tab-'+d.id+'" class="tab-element"><a id="tab-title-link-'+d.id+'" title="" href="#tab-content-'+d.id+'" data-original-title=""><span id="tab-title-text-'+d.id+'">'+d.title+"</span>";if(d.ondel){c+='<i id="delete" class="ui-tabs-delete fa fa-minus-circle"/>'}c+="</a></li>";return c},_template_tab_content:function(c){return'<div id="tab-content-'+c.id+'" class="tab-pane"/>'}});return{View:b}}); \ No newline at end of file +define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{title_new:"",operations:null,onnew:null,min:null,max:null},initialize:function(e){this.visible=false;this.$nav=null;this.$content=null;this.first_tab=null;this.options=a.merge(e,this.optionsDefault);var c=$(this._template(this.options));this.$nav=c.find(".tab-navigation");this.$content=c.find(".tab-content");this.setElement(c);this.list={};var d=this;if(this.options.operations){$.each(this.options.operations,function(g,h){h.$el.prop("id",g);d.$nav.find(".operations").append(h.$el)})}if(this.options.onnew){var f=$(this._template_tab_new(this.options));this.$nav.append(f);f.tooltip({title:"Add a new tab",placement:"bottom",container:d.$el});f.on("click",function(g){f.tooltip("hide");d.options.onnew()})}},size:function(){return _.size(this.list)},add:function(f){var e=this;var h=f.id;var g=$(this._template_tab(f));var d=$(this._template_tab_content(f));this.list[h]=f.ondel?true:false;if(this.options.onnew){this.$nav.find("#new-tab").before(g)}else{this.$nav.append(g)}d.append(f.$el);this.$content.append(d);if(this.size()==1){g.addClass("active");d.addClass("active");this.first_tab=h}if(this.options.max&&this.size()>=this.options.max){this.$el.find("#new-tab").hide()}if(f.ondel){var c=g.find("#delete");c.tooltip({title:"Delete this tab",placement:"bottom",container:e.$el});c.on("click",function(){c.tooltip("destroy");e.$el.find(".tooltip").remove();f.ondel();return false})}g.on("click",function(i){i.preventDefault();if(f.onclick){f.onclick()}else{e.show(h)}})},del:function(c){this.$el.find("#tab-"+c).remove();this.$el.find("#"+c).remove();if(this.first_tab==c){this.first_tab=null}if(this.first_tab!=null){this.show(this.first_tab)}if(this.list[c]){delete this.list[c]}if(this.size()<this.options.max){this.$el.find("#new-tab").show()}},delRemovable:function(){for(var c in this.list){this.del(c)}},show:function(c){this.$el.fadeIn("fast");this.visible=true;if(c){this.$el.find(".tab-element").removeClass("active");this.$el.find(".tab-pane").removeClass("active");this.$el.find("#tab-"+c).addClass("active");this.$el.find("#"+c).addClass("active")}},hide:function(){this.$el.fadeOut("fast");this.visible=false},hideOperation:function(c){this.$nav.find("#"+c).hide()},showOperation:function(c){this.$nav.find("#"+c).show()},setOperation:function(e,d){var c=this.$nav.find("#"+e);c.off("click");c.on("click",d)},title:function(e,d){var c=this.$el.find("#tab-title-text-"+e);if(d){c.html(d)}return c.html()},retitle:function(d){var c=0;for(var e in this.list){this.title(e,++c+": "+d)}},_template:function(c){return'<div class="ui-tabs tabbable tabs-left"><ul id="tab-navigation" class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div id="tab-content" class="tab-content"/></div>'},_template_tab_new:function(c){return'<li id="new-tab"><a href="javascript:void(0);"><i class="ui-tabs-add fa fa-plus-circle"/>'+c.title_new+"</a></li>"},_template_tab:function(d){var c='<li id="tab-'+d.id+'" class="tab-element"><a id="tab-title-link-'+d.id+'" title="" href="#'+d.id+'" data-original-title=""><span id="tab-title-text-'+d.id+'" class="tab-title-text">'+d.title+"</span>";if(d.ondel){c+='<i id="delete" class="ui-tabs-delete fa fa-minus-circle"/>'}c+="</a></li>";return c},_template_tab_content:function(c){return'<div id="'+c.id+'" class="tab-pane"/>'}});return{View:b}}); \ No newline at end of file diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/style/blue/base.css --- a/static/style/blue/base.css +++ b/static/style/blue/base.css @@ -1870,6 +1870,8 @@ .collection-creator .flexible-partition .column-header .remove-extensions-link{display:none} .collection-creator .paired-columns{height:0;border:1px solid lightgrey;border-width:1px 0 1px 0;margin-bottom:8px}.collection-creator .paired-columns .column-datasets{width:100%;overflow:auto} .collection-creator .paired-columns .unpair-btn{float:right;margin-top:-32px;width:31px;height:32px;border-color:transparent;background:transparent;font-size:120%}.collection-creator .paired-columns .unpair-btn:hover{border-color:#BFBFBF;background:#DEDEDE} +.collection-creator .paired-columns .paired-drop-placeholder{width:60px;height:3px;margin:2px 0px 0px 14px;background:black}.collection-creator .paired-columns .paired-drop-placeholder:before{float:left;font-size:120%;margin:-9px 0 0 -8px;font-family:FontAwesome;content:'\f0da'} +.collection-creator .paired-columns .paired-drop-placeholder:last-child{margin-bottom:8px} .collection-creator .paired-columns .empty-message{text-align:center} .collection-creator .footer{padding-bottom:8px}.collection-creator .footer .attributes .remove-extensions-prompt{line-height:32px}.collection-creator .footer .attributes .remove-extensions-prompt .remove-extensions{display:inline-block;width:24px;height:24px} .collection-creator .footer .attributes .collection-name-prompt{margin:5px 4px 0 0} diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 static/style/src/less/ui/paired-collection-creator.less --- a/static/style/src/less/ui/paired-collection-creator.less +++ b/static/style/src/less/ui/paired-collection-creator.less @@ -374,6 +374,22 @@ background: #DEDEDE; } } + .paired-drop-placeholder { + width : 60px; + height : 3px; + margin : 2px 0px 0px 14px; + background : black; + &:before { + float: left; + font-size: 120%; + margin: -9px 0px 0px -8px; + font-family: FontAwesome; + content: '\f0da'; + } + &:last-child { + margin-bottom: 8px; + } + } .empty-message { text-align: center; } diff -r c4e19939b6a300c555a9fdab10b7372d8a8a73a1 -r 11e6f06278126edb16c6333e2eddf6dd1a9772b2 templates/base/base_panels.mako --- a/templates/base/base_panels.mako +++ b/templates/base/base_panels.mako @@ -106,7 +106,6 @@ ## Scripts can be loaded later since they progressively add features to ## the panels, but do not change layout ${h.js( - 'libs/jquery/jquery.event.drag', 'libs/jquery/jquery.event.hover', 'libs/jquery/jquery.form', 'libs/jquery/jquery.rating', 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.