Merge pull request #134 from carlfeberhard/collections

Collections
This commit is contained in:
Dannon Baker
2015-04-20 17:41:58 -04:00
17 changed files with 1552 additions and 136 deletions
File diff suppressed because it is too large Load Diff
@@ -3,7 +3,8 @@ define([
"utils/natural-sort",
"mvc/collection/list-collection-creator",
"mvc/base-mvc",
"utils/localization"
"utils/localization",
"ui/hoverhighlight"
], function( levenshteinDistance, naturalSort, LIST_COLLECTION_CREATOR, baseMVC, _l ){
/* ============================================================================
TODO:
@@ -185,7 +186,7 @@ function autoPairFnBuilder( options ){
*/
var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
className: 'collection-creator flex-row-container',
className: 'list-of-pairs-collection-creator collection-creator flex-row-container',
/** set up initial options, instance vars, behaviors, and autopair (if set to do so) */
initialize : function( attributes ){
@@ -1307,8 +1308,8 @@ var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).exte
//this.debug( ev.originalEvent.clientX, ev.originalEvent.clientY );
var $nearest = this._getNearestPairedDatasetLi( ev.originalEvent.clientY );
$( '.paired-drop-placeholder' ).remove();
var $placeholder = $( '<div class="paired-drop-placeholder"></div>' );
$( '.element-drop-placeholder' ).remove();
var $placeholder = $( '<div class="element-drop-placeholder"></div>' );
if( !$nearest.size() ){
$list.append( $placeholder );
} else {
@@ -1388,7 +1389,7 @@ var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).exte
/** drag communication with pair sub-views: dragend - remove the placeholder */
_pairDragend : function( ev, pair ){
//this.debug( '_pairDragend', ev, pair )
$( '.paired-drop-placeholder' ).remove();
$( '.element-drop-placeholder' ).remove();
this.$dragging = null;
},
@@ -1656,37 +1657,6 @@ PairedCollectionCreator.templates = PairedCollectionCreator.templates || {
};
//=============================================================================
(function(){
/** plugin that will highlight an element when this element is hovered over */
jQuery.fn.extend({
hoverhighlight : function $hoverhighlight( scope, color ){
scope = scope || 'body';
if( !this.size() ){ return this; }
$( this ).each( function(){
var $this = $( this ),
targetSelector = $this.data( 'target' );
if( targetSelector ){
$this.mouseover( function( ev ){
$( targetSelector, scope ).css({
background: color
});
})
.mouseout( function( ev ){
$( targetSelector ).css({
background: ''
});
});
}
});
return this;
}
});
}());
//=============================================================================
/** a modal version of the paired collection creator */
var pairedCollectionCreatorModal = function _pairedCollectionCreatorModal( datasets, options ){
@@ -1728,12 +1698,8 @@ var pairedCollectionCreatorModal = function _pairedCollectionCreatorModal( datas
//=============================================================================
function createListOfPairsCollection( collection ){
var elements = LIST_COLLECTION_CREATOR.validElements( collection );
if( !elements.length ){
LIST_COLLECTION_CREATOR.noValidElementsErrorModal();
return jQuery.Deferred().reject( LIST_COLLECTION_CREATOR.noValidElementsMessage );
}
var elements = collection.toJSON();
//TODO: validate elements
return pairedCollectionCreatorModal( elements, {
historyId : collection.historyId
});
@@ -1,33 +1,247 @@
define([
"mvc/collection/list-collection-creator",
"mvc/ui/error-modal",
"mvc/history/hdca-model",
"mvc/base-mvc",
"utils/localization"
], function( LIST_COLLECTION_CREATOR, errorModal, _l ){
], function( LIST_CREATOR, HDCA, BASE_MVC, _l ){
/*==============================================================================
TODO:
the paired creator doesn't really mesh with the list creator as parent
it may be better to make an abstract super class for both
composites may inherit from this (or vis-versa)
PairedDatasetCollectionElementView doesn't make a lot of sense
function createPairHDCA( collection ){
// currently: datasets in the ok state
var elementsJSON = LIST_COLLECTION_CREATOR.validElements( collection );
if( !elementsJSON.length ){
LIST_COLLECTION_CREATOR.noValidElementsErrorModal();
return jQuery.Deferred().reject( LIST_COLLECTION_CREATOR.noValidElementsMessage );
}
if( elementsJSON.length !== 2 ){
errorModal(
'When pairing datasets, select only two datasets: one forward and one reverse.',
'Not a valid pair'
);
return jQuery.Deferred().reject( LIST_COLLECTION_CREATOR.noValidElementsMessage );
}
==============================================================================*/
/** */
var PairedDatasetCollectionElementView = Backbone.View.extend( BASE_MVC.LoggableMixin ).extend({
//TODO: use proper class (DatasetDCE or NestedDCDCE (or the union of both))
tagName : 'li',
className : 'collection-element',
var name = 'New Dataset Pair',
elementIdentifiers = [
{ name: "forward", src: "hda", id: elementsJSON[0].id },
{ name: "reverse", src: "hda", id: elementsJSON[1].id }
];
return collection.createHDCA( elementIdentifiers, 'paired', name );
initialize : function( attributes ){
this.element = attributes.element || {};
this.identifier = attributes.identifier;
},
render : function(){
this.$el
.attr( 'data-element-id', this.element.id )
.html( this.template({ identifier: this.identifier, element: this.element }) );
return this;
},
//TODO: lots of unused space in the element - possibly load details and display them horiz.
template : _.template([
'<span class="identifier"><%= identifier %></span>',
'<span class="name"><%= element.name %></span>',
].join('')),
/** remove the DOM and any listeners */
destroy : function(){
this.off();
this.$el.remove();
},
/** string rep */
toString : function(){
return 'DatasetCollectionElementView()';
}
});
// ============================================================================
var _super = LIST_CREATOR.ListCollectionCreator;
/** An interface for building collections.
*/
var PairCollectionCreator = _super.extend({
/** the class used to display individual elements */
elementViewClass : PairedDatasetCollectionElementView,
/** the class this creator will create and save */
collectionClass : HDCA.HistoryPairDatasetCollection,
className : 'pair-collection-creator collection-creator flex-row-container',
/** override to no-op */
_mangleDuplicateNames : function(){},
// TODO: this whole pattern sucks. There needs to be two classes of problem area:
// bad inital choices and
// when the user has painted his/her self into a corner during creation/use-of-the-creator
/** render the entire interface */
render : function( speed, callback ){
if( this.workingElements.length === 2 ){
return _super.prototype.render.call( this, speed, callback );
}
return this._renderInvalid( speed, callback );
},
// ------------------------------------------------------------------------ rendering elements
/** render forward/reverse */
_renderList : function( speed, callback ){
//this.debug( '-- _renderList' );
//precondition: there are two valid elements in workingElements
var creator = this,
$tmp = jQuery( '<div/>' ),
$list = creator.$list();
// lose the original views, create the new, append all at once, then call their renders
_.each( this.elementViews, function( view ){
view.destroy();
creator.removeElementView( view );
});
$tmp.append( creator._createForwardElementView().$el );
$tmp.append( creator._createReverseElementView().$el );
$list.empty().append( $tmp.children() );
_.invoke( creator.elementViews, 'render' );
},
/** create the forward element view */
_createForwardElementView : function(){
return this._createElementView( this.workingElements[0], { identifier: 'forward' } );
},
/** create the forward element view */
_createReverseElementView : function(){
return this._createElementView( this.workingElements[1], { identifier: 'reverse' } );
},
/** create an element view, cache in elementViews, and return */
_createElementView : function( element, options ){
var elementView = new this.elementViewClass( _.extend( options, {
element : element,
}));
this.elementViews.push( elementView );
return elementView;
},
/** swap the forward, reverse elements and re-render */
swap : function(){
this.workingElements = [
this.workingElements[1],
this.workingElements[0],
];
this._renderList();
},
events : _.extend( _.clone( _super.prototype.events ), {
'click .swap' : 'swap',
}),
// ------------------------------------------------------------------------ templates
//TODO: move to require text plugin and load these as text
//TODO: underscore currently unnecc. bc no vars are used
//TODO: better way of localizing text-nodes in long strings
/** underscore template fns attached to class */
templates : _.extend( _.clone( _super.prototype.templates ), {
/** the middle: element list */
middle : _.template([
'<div class="collection-elements-controls">',
'<a class="swap" href="javascript:void(0);" title="', _l( 'Swap forward and reverse datasets' ), '">',
_l( 'Swap' ),
'</a>',
'</div>',
'<div class="collection-elements scroll-container flex-row">',
'</div>'
].join('')),
/** help content */
helpContent : _.template([
'<p>', _l([
'Pair collections are permanent collections containing two datasets: one forward and one reverse. ',
'Often these are forward and reverse reads. The pair collections can be passed to tools and ',
'workflows in order to have analyses done on both datasets. This interface allows ',
'you to create a pair, name it, and swap which is forward and which reverse.'
].join( '' )), '</p>',
'<ul>',
'<li>', _l([
'Click the <i data-target=".swap">"Swap"</i> link to make your forward dataset the reverse ',
'and the reverse dataset forward.'
].join( '' )), '</li>',
'<li>', _l([
'Click the <i data-target=".cancel-create">"Cancel"</i> button to exit the interface.'
].join( '' )), '</li>',
'</ul><br />',
'<p>', _l([
'Once your collection is complete, enter a <i data-target=".collection-name">name</i> and ',
'click <i data-target=".create-collection">"Create list"</i>.'
].join( '' )), '</p>'
].join('')),
/** a simplified page communicating what went wrong and why the user needs to reselect something else */
invalidInitial : _.template([
'<div class="header flex-row no-flex">',
'<div class="alert alert-warning" style="display: block">',
'<span class="alert-message">',
'<% if( _.size( problems ) ){ %>',
_l( 'The following selections could not be included due to problems' ),
'<ul><% _.each( problems, function( problem ){ %>',
'<li><b><%= problem.element.name %></b>: <%= problem.text %></li>',
'<% }); %></ul>',
'<% } else if( _.size( elements ) === 0 ){ %>',
_l( 'No datasets were selected' ), '.',
'<% } else if( _.size( elements ) === 1 ){ %>',
_l( 'Only one dataset was selected' ), ': <%= elements[0].name %>',
'<% } else if( _.size( elements ) > 2 ){ %>',
_l( 'Too many datasets were selected' ),
': <%= _.pluck( elements, "name" ).join( ", ") %>',
'<% } %>',
'<br />',
_l( 'Two (and only two) elements are needed for the pair' ), '. ',
_l( 'You may need to ' ),
'<a class="cancel-create" href="javascript:void(0)">', _l( 'cancel' ), '</a> ',
_l( 'and reselect new elements' ), '.',
'</span>',
'</div>',
'</div>',
'<div class="footer flex-row no-flex">',
'<div class="actions clear vertically-spaced">',
'<div class="other-options pull-left">',
'<button class="cancel-create btn" tabindex="-1">', _l( 'Cancel' ), '</button>',
// _l( 'Create a different kind of collection' ),
'</div>',
'</div>',
'</div>'
].join('')),
}),
// ------------------------------------------------------------------------ misc
/** string rep */
toString : function(){ return 'PairCollectionCreator'; }
});
//==============================================================================
/** List collection flavor of collectionCreatorModal. */
var pairCollectionCreatorModal = function _pairCollectionCreatorModal( elements, options ){
options = options || {};
options.title = _l( 'Create a collection from a pair of datasets' );
return LIST_CREATOR.collectionCreatorModal( elements, options, PairCollectionCreator );
};
//==============================================================================
/** Use a modal to create a pair collection, then add it to the given history contents.
* @returns {Deferred} resolved when the collection is added to the history.
*/
function createPairCollection( contents ){
var elements = contents.toJSON(),
promise = pairCollectionCreatorModal( elements, {
creationFn : function( elements, name ){
elements = [
{ name: "forward", src: "hda", id: elements[0].id },
{ name: "reverse", src: "hda", id: elements[1].id }
];
return contents.createHDCA( elements, 'paired', name );
}
});
return promise;
}
//==============================================================================
return {
createPairHDCA : createPairHDCA
PairCollectionCreator : PairCollectionCreator,
pairCollectionCreatorModal : pairCollectionCreatorModal,
createPairCollection : createPairCollection,
};
});
@@ -287,13 +287,13 @@ var HistoryPanelEdit = _super.extend(
var panel = this;
return [
{ html: _l( 'Build Dataset List' ), func: function() {
LIST_COLLECTION_CREATOR.createListHDCA( panel.getSelectedModels() )
LIST_COLLECTION_CREATOR.createListCollection( panel.getSelectedModels() )
.done( function(){ panel.model.refresh() });
}
},
// TODO: Only show quick pair if two things selected.
{ html: _l( 'Build Dataset Pair' ), func: function() {
PAIR_COLLECTION_CREATOR.createPairHDCA( panel.getSelectedModels() )
PAIR_COLLECTION_CREATOR.createPairCollection( panel.getSelectedModels() )
.done( function(){ panel.model.refresh() });
}
},
@@ -458,7 +458,6 @@ var HistoryPanelEdit = _super.extend(
var dropTarget = this.$( '.history-drop-target' ).get(0);
for( var evName in this._dropHandlers ){
if( this._dropHandlers.hasOwnProperty( evName ) ){
console.debug( evName, this._dropHandlers[ evName ] );
dropTarget.off( evName, this._dropHandlers[ evName ] );
}
}
@@ -0,0 +1,37 @@
(function (factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else {
// Browser globals
factory(jQuery);
}
}(function () {
//=============================================================================
jQuery.fn.extend({
hoverhighlight : function $hoverhighlight( scope, color ){
scope = scope || 'body';
if( !this.size() ){ return this; }
$( this ).each( function(){
var $this = $( this ),
targetSelector = $this.data( 'target' );
if( targetSelector ){
$this.mouseover( function( ev ){
$( targetSelector, scope ).css({
background: color
});
})
.mouseout( function( ev ){
$( targetSelector ).css({
background: ''
});
});
}
});
return this;
}
});
}));
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
{"version":3,"file":"pair-collection-creator.js","sources":["../../../src/mvc/collection/pair-collection-creator.js"],"names":["define","LIST_COLLECTION_CREATOR","errorModal","createPairHDCA","collection","elementsJSON","validElements","length","noValidElementsErrorModal","jQuery","Deferred","reject","noValidElementsMessage","name","elementIdentifiers","src","id","createHDCA"],"mappings":"AAAAA,QACI,yCACA,qBACA,sBACD,SAAUC,EAAyBC,GAElC,QAASC,GAAgBC,GAErB,GAAIC,GAAeJ,EAAwBK,cAAeF,EAC1D,KAAKC,EAAaE,OAEd,MADAN,GAAwBO,4BACjBC,OAAOC,WAAWC,OAAQV,EAAwBW,uBAE7D,IAA4B,IAAxBP,EAAaE,OAKb,MAJAL,GACI,gFACA,oBAEGO,OAAOC,WAAWC,OAAQV,EAAwBW,uBAG7D,IAAIC,GAAO,mBACPC,IACMD,KAAM,UAAWE,IAAK,MAAOC,GAAIX,EAAa,GAAGW,KACjDH,KAAM,UAAWE,IAAK,MAAOC,GAAIX,EAAa,GAAGW,IAE3D,OAAOZ,GAAWa,WAAYH,EAAoB,SAAUD,GAGhE,OACIV,eAAiBA"}
{"version":3,"file":"pair-collection-creator.js","sources":["../../../src/mvc/collection/pair-collection-creator.js"],"names":["define","LIST_CREATOR","HDCA","BASE_MVC","_l","createPairCollection","contents","elements","toJSON","promise","pairCollectionCreatorModal","creationFn","name","src","id","createHDCA","PairedDatasetCollectionElementView","Backbone","View","extend","LoggableMixin","tagName","className","initialize","attributes","this","element","identifier","render","$el","attr","html","template","_","join","destroy","off","remove","toString","_super","ListCollectionCreator","PairCollectionCreator","elementViewClass","collectionClass","HistoryPairDatasetCollection","_mangleDuplicateNames","speed","callback","workingElements","length","prototype","call","_renderInvalid","_renderList","creator","$tmp","jQuery","$list","each","elementViews","view","removeElementView","append","_createForwardElementView","_createReverseElementView","empty","children","invoke","_createElementView","options","elementView","push","swap","events","clone","click .swap","templates","middle","helpContent","invalidInitial","title","collectionCreatorModal"],"mappings":"AAAAA,QACI,yCACA,yBACA,eACA,sBACD,SAAUC,EAAcC,EAAMC,EAAUC,GA6N3C,QAASC,GAAsBC,GAC3B,GAAIC,GAAWD,EAASE,SACpBC,EAAUC,EAA4BH,GAClCI,WAAa,SAAUJ,EAAUK,GAK7B,MAJAL,KACMK,KAAM,UAAWC,IAAK,MAAOC,GAAIP,EAAS,GAAGO,KAC7CF,KAAM,UAAWC,IAAK,MAAOC,GAAIP,EAAS,GAAGO,KAE5CR,EAASS,WAAYR,EAAU,SAAUK,KAG5D,OAAOH,GA9NX,GAAIO,GAAqCC,SAASC,KAAKC,OAAQhB,EAASiB,eAAgBD,QAEpFE,QAAc,KACdC,UAAc,qBAEdC,WAAa,SAAUC,GACnBC,KAAKC,QAAUF,EAAWE,YAC1BD,KAAKE,WAAaH,EAAWG,YAGjCC,OAAS,WAIL,MAHAH,MAAKI,IACAC,KAAM,kBAAmBL,KAAKC,QAAQZ,IACtCiB,KAAMN,KAAKO,UAAWL,WAAYF,KAAKE,WAAYD,QAASD,KAAKC,WAC/DD,MAIXO,SAAWC,EAAED,UACT,oDACA,iDACFE,KAAK,KAGPC,QAAU,WACNV,KAAKW,MACLX,KAAKI,IAAIQ,UAIbC,SAAW,WACP,MAAO,oCAMXC,EAAStC,EAAauC,sBAItBC,EAAwBF,EAAOpB,QAG/BuB,iBAAmB1B,EAEnB2B,gBAAkBzC,EAAK0C,6BACvBtB,UAAY,gEAGZuB,sBAAwB,aAMxBjB,OAAS,SAAUkB,EAAOC,GACtB,MAAoC,KAAhCtB,KAAKuB,gBAAgBC,OACdV,EAAOW,UAAUtB,OAAOuB,KAAM1B,KAAMqB,EAAOC,GAE/CtB,KAAK2B,eAAgBN,EAAOC,IAKvCM,YAAc,WAGV,GAAIC,GAAU7B,KACV8B,EAAOC,OAAQ,UACfC,EAAQH,EAAQG,OAGpBxB,GAAEyB,KAAMjC,KAAKkC,aAAc,SAAUC,GACjCA,EAAKzB,UACLmB,EAAQO,kBAAmBD,KAE/BL,EAAKO,OAAQR,EAAQS,4BAA4BlC,KACjD0B,EAAKO,OAAQR,EAAQU,4BAA4BnC,KACjD4B,EAAMQ,QAAQH,OAAQP,EAAKW,YAC3BjC,EAAEkC,OAAQb,EAAQK,aAAc,WAIpCI,0BAA4B,WACxB,MAAOtC,MAAK2C,mBAAoB3C,KAAKuB,gBAAgB,IAAMrB,WAAY,aAI3EqC,0BAA4B,WACxB,MAAOvC,MAAK2C,mBAAoB3C,KAAKuB,gBAAgB,IAAMrB,WAAY,aAI3EyC,mBAAqB,SAAU1C,EAAS2C,GACpC,GAAIC,GAAc,GAAI7C,MAAKiB,iBAAkBT,EAAEd,OAAQkD,GACnD3C,QAAUA,IAGd,OADAD,MAAKkC,aAAaY,KAAMD,GACjBA,GAIXE,KAAO,WACH/C,KAAKuB,iBACDvB,KAAKuB,gBAAgB,GACrBvB,KAAKuB,gBAAgB,IAEzBvB,KAAK4B,eAGToB,OAASxC,EAAEd,OAAQc,EAAEyC,MAAOnC,EAAOW,UAAUuB,SACzCE,cAAgB,SAQpBC,UAAY3C,EAAEd,OAAQc,EAAEyC,MAAOnC,EAAOW,UAAU0B,YAE5CC,OAAS5C,EAAED,UACP,6CACI,qDAAsD5B,EAAI,qCAAuC,KAC7FA,EAAI,QACR,OACJ,SACA,8DACA,UACF8B,KAAK,KAGP4C,YAAc7C,EAAED,UACZ,MAAO5B,GACH,oGACA,8FACA,oFACA,+EACF8B,KAAM,KAAO,OACf,OACI,OAAQ9B,GACJ,6FACA,oCACF8B,KAAM,KAAO,QACf,OAAQ9B,GACJ,wFACF8B,KAAM,KAAO,QACnB,cACA,MAAO9B,GACH,4FACA,gEACF8B,KAAM,KAAO,QACjBA,KAAK,KAGP6C,eAAiB9C,EAAED,UACf,wCACI,2DACI,+BACI,kCACI5B,EAAI,kEACJ,mDACI,mEACJ,iBACJ,+CACIA,EAAI,6BAA+B,IACvC,+CACIA,EAAI,iCAAmC,4BAC3C,6CACIA,EAAI,mCACJ,mDACJ,UACA,SACAA,EAAI,uDAAyD,KAC7DA,EAAI,oBACJ,sDAAuDA,EAAI,UAAY,QACvEA,EAAI,6BAA+B,IACvC,UACJ,SACJ,SACA,wCACI,gDACI,wCACI,mDAAoDA,EAAI,UAAY,YAExE,SACJ,SACJ,UACF8B,KAAK,OAKXI,SAAW,WAAY,MAAO,2BAM9B5B,EAA6B,SAAsCH,EAAU8D,GAG7E,MAFAA,GAAUA,MACVA,EAAQW,MAAQ5E,EAAI,+CACbH,EAAagF,uBAAwB1E,EAAU8D,EAAS5B,GAuB/D,QACIA,sBAA8BA,EAC9B/B,2BAA8BA,EAC9BL,qBAA8BA"}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"hoverhighlight.js","sources":["../../src/ui/hoverhighlight.js"],"names":["factory","define","amd","jQuery","fn","extend","hoverhighlight","scope","color","this","size","$","each","$this","targetSelector","data","mouseover","css","background","mouseout"],"mappings":"CAAC,SAAUA,GACe,kBAAXC,SAAyBA,OAAOC,IACvCD,UAAWD,GAGXA,EAAQG,SAGd,WAGEA,OAAOC,GAAGC,QACNC,eAAiB,SAA0BC,EAAOC,GAE9C,MADAD,GAAQA,GAAS,OACZE,KAAKC,QAEVC,EAAGF,MAAOG,KAAM,WACZ,GAAIC,GAAQF,EAAGF,MACXK,EAAiBD,EAAME,KAAM,SAE7BD,IACAD,EAAMG,UAAW,WACbL,EAAGG,EAAgBP,GAAQU,KACvBC,WAAYV,MAGnBW,SAAU,WACPR,EAAGG,GAAiBG,KAChBC,WAAY,SAKrBT,MAnBoBA"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
define(["mvc/collection/list-collection-creator","mvc/ui/error-modal","utils/localization"],function(a,b){function c(c){var d=a.validElements(c);if(!d.length)return a.noValidElementsErrorModal(),jQuery.Deferred().reject(a.noValidElementsMessage);if(2!==d.length)return b("When pairing datasets, select only two datasets: one forward and one reverse.","Not a valid pair"),jQuery.Deferred().reject(a.noValidElementsMessage);var e="New Dataset Pair",f=[{name:"forward",src:"hda",id:d[0].id},{name:"reverse",src:"hda",id:d[1].id}];return c.createHDCA(f,"paired",e)}return{createPairHDCA:c}});
define(["mvc/collection/list-collection-creator","mvc/history/hdca-model","mvc/base-mvc","utils/localization"],function(a,b,c,d){function e(a){var b=a.toJSON(),c=i(b,{creationFn:function(b,c){return b=[{name:"forward",src:"hda",id:b[0].id},{name:"reverse",src:"hda",id:b[1].id}],a.createHDCA(b,"paired",c)}});return c}var f=Backbone.View.extend(c.LoggableMixin).extend({tagName:"li",className:"collection-element",initialize:function(a){this.element=a.element||{},this.identifier=a.identifier},render:function(){return this.$el.attr("data-element-id",this.element.id).html(this.template({identifier:this.identifier,element:this.element})),this},template:_.template(['<span class="identifier"><%= identifier %></span>','<span class="name"><%= element.name %></span>'].join("")),destroy:function(){this.off(),this.$el.remove()},toString:function(){return"DatasetCollectionElementView()"}}),g=a.ListCollectionCreator,h=g.extend({elementViewClass:f,collectionClass:b.HistoryPairDatasetCollection,className:"pair-collection-creator collection-creator flex-row-container",_mangleDuplicateNames:function(){},render:function(a,b){return 2===this.workingElements.length?g.prototype.render.call(this,a,b):this._renderInvalid(a,b)},_renderList:function(){var a=this,b=jQuery("<div/>"),c=a.$list();_.each(this.elementViews,function(b){b.destroy(),a.removeElementView(b)}),b.append(a._createForwardElementView().$el),b.append(a._createReverseElementView().$el),c.empty().append(b.children()),_.invoke(a.elementViews,"render")},_createForwardElementView:function(){return this._createElementView(this.workingElements[0],{identifier:"forward"})},_createReverseElementView:function(){return this._createElementView(this.workingElements[1],{identifier:"reverse"})},_createElementView:function(a,b){var c=new this.elementViewClass(_.extend(b,{element:a}));return this.elementViews.push(c),c},swap:function(){this.workingElements=[this.workingElements[1],this.workingElements[0]],this._renderList()},events:_.extend(_.clone(g.prototype.events),{"click .swap":"swap"}),templates:_.extend(_.clone(g.prototype.templates),{middle:_.template(['<div class="collection-elements-controls">','<a class="swap" href="javascript:void(0);" title="',d("Swap forward and reverse datasets"),'">',d("Swap"),"</a>","</div>",'<div class="collection-elements scroll-container flex-row">',"</div>"].join("")),helpContent:_.template(["<p>",d(["Pair collections are permanent collections containing two datasets: one forward and one reverse. ","Often these are forward and reverse reads. The pair collections can be passed to tools and ","workflows in order to have analyses done on both datasets. This interface allows ","you to create a pair, name it, and swap which is forward and which reverse."].join("")),"</p>","<ul>","<li>",d(['Click the <i data-target=".swap">"Swap"</i> link to make your forward dataset the reverse ',"and the reverse dataset forward."].join("")),"</li>","<li>",d(['Click the <i data-target=".cancel-create">"Cancel"</i> button to exit the interface.'].join("")),"</li>","</ul><br />","<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>.'].join("")),"</p>"].join("")),invalidInitial:_.template(['<div class="header flex-row no-flex">','<div class="alert alert-warning" style="display: block">','<span class="alert-message">',"<% if( _.size( problems ) ){ %>",d("The following selections could not be included due to problems"),"<ul><% _.each( problems, function( problem ){ %>","<li><b><%= problem.element.name %></b>: <%= problem.text %></li>","<% }); %></ul>","<% } else if( _.size( elements ) === 0 ){ %>",d("No datasets were selected"),".","<% } else if( _.size( elements ) === 1 ){ %>",d("Only one dataset was selected"),": <%= elements[0].name %>","<% } else if( _.size( elements ) > 2 ){ %>",d("Too many datasets were selected"),': <%= _.pluck( elements, "name" ).join( ", ") %>',"<% } %>","<br />",d("Two (and only two) elements are needed for the pair"),". ",d("You may need to "),'<a class="cancel-create" href="javascript:void(0)">',d("cancel"),"</a> ",d("and reselect new elements"),".","</span>","</div>","</div>",'<div class="footer flex-row no-flex">','<div class="actions clear vertically-spaced">','<div class="other-options pull-left">','<button class="cancel-create btn" tabindex="-1">',d("Cancel"),"</button>","</div>","</div>","</div>"].join(""))}),toString:function(){return"PairCollectionCreator"}}),i=function(b,c){return c=c||{},c.title=d("Create a collection from a pair of datasets"),a.collectionCreatorModal(b,c,h)};return{PairCollectionCreator:h,pairCollectionCreatorModal:i,createPairCollection:e}});
//# sourceMappingURL=../../../maps/mvc/collection/pair-collection-creator.js.map
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
!function(a){"function"==typeof define&&define.amd?define([],a):a(jQuery)}(function(){jQuery.fn.extend({hoverhighlight:function(a,b){return a=a||"body",this.size()?($(this).each(function(){var c=$(this),d=c.data("target");d&&c.mouseover(function(){$(d,a).css({background:b})}).mouseout(function(){$(d).css({background:""})})}),this):this}})});
//# sourceMappingURL=../../maps/ui/hoverhighlight.js.map
+30 -5
View File
@@ -2220,13 +2220,13 @@ pre.peek table,pre.peek th,pre.peek tr,pre.peek td{font-family:Monaco,Menlo,Cons
.collection-creator .flex-column.no-flex{-webkit-flex:0 auto;-ms-flex:0 auto;flex:0 0 auto}
.collection-creator .choose-filters .help{margin-bottom:2px;font-size:90%;color:grey}
.collection-creator .choose-filters button{width:100%;margin-top:2px}
.collection-creator .header .alert{display:none}
.collection-creator .header .alert{display:none}.collection-creator .header .alert li{list-style:circle;margin-left:32px}
.collection-creator .column{width:30%}
.collection-creator .column-title{height:22px;line-height:22px;overflow:hidden}.collection-creator .column-title:hover{text-decoration:underline;cursor:pointer}
.collection-creator .column-title .title{font-weight:bold}
.collection-creator .column-title .title-info{color:grey}.collection-creator .column-title .title-info:before{content:' - '}
.collection-creator .paired-column{text-align:center;width:22%}
.collection-creator .header{padding-bottom:8px}.collection-creator .header .main-help{margin-bottom:17px;overflow:hidden;padding:15px;background:#f8f8f8}.collection-creator .header .main-help:not(.expanded){max-height:49px}.collection-creator .header .main-help:not(.expanded) .help-content p:first-child{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.collection-creator .header .main-help{margin-bottom:17px;overflow:hidden;padding:15px;background:#f8f8f8}.collection-creator .header .main-help:not(.expanded){max-height:49px}.collection-creator .header .main-help:not(.expanded) .help-content p:first-child{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.collection-creator .header .main-help:not(.expanded) .help-content>*:not(:first-child){display:none}
.collection-creator .header .main-help.expanded{max-height:none}
.collection-creator .header .main-help .help-content i{cursor:help;border-bottom:1px dotted grey;font-style:normal}
@@ -2244,7 +2244,7 @@ pre.peek table,pre.peek th,pre.peek tr,pre.peek td{font-family:Monaco,Menlo,Cons
.collection-creator .column-datasets .dataset.paired .pair-name-column{text-align:center}.collection-creator .column-datasets .dataset.paired .pair-name-column .pair-name:hover{text-decoration:underline}
.collection-creator .column-datasets .dataset.paired .reverse-dataset-name{border-left:1px solid grey;padding-left:8px}.collection-creator .column-datasets .dataset.paired .reverse-dataset-name:before{margin-right:8px;font-family:FontAwesome;content:'\f060'}
.collection-creator .column-datasets .dataset:hover{border-color:black}
.collection-creator .column-datasets .dataset.selected{border-color:black;background:black;color:white}
.collection-creator .column-datasets .dataset.selected{border-color:black;background:black;color:white}.collection-creator .column-datasets .dataset.selected a{color:white}
.collection-creator .unpaired-columns{height:0;border:1px solid lightgrey;border-width:1px 0 1px 0}.collection-creator .unpaired-columns .forward-column .dataset.unpaired{margin-right:32px}
.collection-creator .unpaired-columns .paired-column .dataset.unpaired{border-color:lightgrey;color:lightgrey}.collection-creator .unpaired-columns .paired-column .dataset.unpaired:hover{border-color:black;color:black}
.collection-creator .unpaired-columns .reverse-column .dataset.unpaired{text-align:right;margin-left:32px}
@@ -2255,14 +2255,39 @@ pre.peek table,pre.peek th,pre.peek tr,pre.peek td{font-family:Monaco,Menlo,Cons
.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 .element-drop-placeholder{width:60px;height:3px;margin:2px 0px 0px 14px;background:black}.collection-creator .element-drop-placeholder:before{float:left;font-size:120%;margin:-9px 0 0 -8px;font-family:FontAwesome;content:'\f0da'}
.collection-creator .element-drop-placeholder:last-child{margin-bottom:8px}
.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}
.collection-creator .footer .attributes .collection-name-prompt.validation-warning:before{content:'(required)';margin-right:4px;color:red}
.collection-creator .footer .attributes .collection-name{width:50%}.collection-creator .footer .attributes .collection-name.validation-warning{border-color:red}
.collection-creator .footer .actions .other-options>*{display:none;margin-left:4px}
.collection-creator.list-collection-creator .footer{margin-top:8px}
.collection-creator.list-collection-creator .main-help{cursor:pointer}
.collection-creator.list-collection-creator .collection-elements-controls{margin-bottom:8px}.collection-creator.list-collection-creator .collection-elements-controls .clear-selected{float:right !important;float:right;display:none}
.collection-creator.list-collection-creator .collection-elements{max-height:400px;border:0px solid lightgrey;overflow-y:auto;overflow-x:hidden}
.collection-creator.list-collection-creator .collection-element{height:32px;margin:2px 4px 0px 4px;opacity:1.0;border:1px solid lightgrey;border-radius:3px;padding:0 8px 0 8px;line-height:28px;cursor:pointer;overflow:hidden}.collection-creator.list-collection-creator .collection-element:last-of-type{margin-bottom:2px}
.collection-creator.list-collection-creator .collection-element:hover{border-color:black}
.collection-creator.list-collection-creator .collection-element.selected{border-color:black;background:black;color:white}.collection-creator.list-collection-creator .collection-element.selected a{color:white}
.collection-creator.list-collection-creator .collection-element.dragging{opacity:0.4}.collection-creator.list-collection-creator .collection-element.dragging button{display:none}
.collection-creator.list-collection-creator .collection-element .name:hover{text-decoration:underline}
.collection-creator.list-collection-creator .collection-element button{margin-top:3px}
.collection-creator.list-collection-creator .collection-element .discard{float:right !important;float:right}
.collection-creator.list-collection-creator .element-drop-placeholder{margin-left:8px}.collection-creator.list-collection-creator .element-drop-placeholder:before{margin:-8.5px 0 0 -8px}
.collection-creator.list-collection-creator .empty-message{margin:8px;color:grey;font-style:italic;text-align:center}
.collection-creator.list-collection-creator .no-elements-left-message{text-align:left}
.collection-creator.pair-collection-creator .footer{margin-top:8px}
.collection-creator.pair-collection-creator .main-help{cursor:pointer}
.collection-creator.pair-collection-creator .collection-elements-controls{margin-bottom:8px}.collection-creator.pair-collection-creator .collection-elements-controls .clear-selected{float:right !important;float:right;display:none}
.collection-creator.pair-collection-creator .collection-elements{max-height:400px;border:0px solid lightgrey;overflow-y:auto;overflow-x:hidden}
.collection-creator.pair-collection-creator .collection-element{height:32px;margin:2px 4px 0px 4px;opacity:1.0;border:1px solid lightgrey;border-radius:3px;padding:0 8px 0 8px;line-height:28px;cursor:pointer;overflow:hidden}.collection-creator.pair-collection-creator .collection-element:last-of-type{margin-bottom:2px}
.collection-creator.pair-collection-creator .collection-element:hover{border-color:black}
.collection-creator.pair-collection-creator .collection-element button{margin-top:3px}
.collection-creator.pair-collection-creator .collection-element .identifier:after{content:':';margin-right:6px}
.collection-creator.pair-collection-creator .collection-element .name:hover{text-decoration:none}
.collection-creator.pair-collection-creator .empty-message{margin:8px;color:grey;font-style:italic;text-align:center}
.collection-creator.list-of-pairs-collection-creator .column-headers{margin-bottom:8px}
.search-input .search-query{width:100%;padding-right:24px}
.search-input .search-clear,.search-input .search-loading{position:relative;display:inline-block;float:right;margin-top:-24px;margin-right:4px;font-size:1.4em;line-height:23px;color:grey}
.search-input .search-clear:hover{color:#303030}
@@ -1,4 +1,4 @@
// --- main layout elements
// ======================================================================== all types
.collection-creator {
height: 100%;
@@ -106,6 +106,11 @@
.header .alert {
display: none;
li {
list-style: circle;
margin-left: 32px;
}
}
// ------------------------------------------------------------------------ columns
@@ -139,8 +144,6 @@
// ------------------------------------------------------------------------ header
.header {
padding-bottom: 8px;
.main-help {
margin-bottom: 17px;
overflow: hidden;
@@ -287,6 +290,9 @@
border-color: black;
background: black;
color: white;
a {
color: white;
}
}
}
}
@@ -374,26 +380,26 @@
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;
}
}
.element-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;
}
}
// ------------------------------------------------------------------------ footer
.footer {
@@ -434,3 +440,166 @@
padding-bottom: 8px;
}
}
// ======================================================================== list
.collection-creator.list-collection-creator {
.footer {
margin-top: 8px;
}
.main-help {
cursor: pointer;
}
.collection-elements-controls {
margin-bottom: 8px;
.clear-selected {
.pull-right;
display: none;
}
}
.collection-elements {
max-height: 400px;
border: 0px solid lightgrey;
overflow-y: auto;
overflow-x: hidden;
}
// TODO: taken from .dataset above - swap these out
.collection-element {
height: 32px;
margin: 2px 4px 0px 4px;
opacity: 1.0;
border: 1px solid lightgrey;
border-radius: 3px;
padding: 0 8px 0 8px;
line-height: 28px;
cursor: pointer;
overflow: hidden;
&:last-of-type {
margin-bottom: 2px;
}
&:hover {
border-color: black;
}
&.selected {
border-color: black;
background: black;
color: white;
a {
color: white;
}
}
&.dragging {
opacity: 0.4;
button {
display: none;
}
}
.name {
&:hover {
text-decoration: underline;
}
}
button {
margin-top: 3px;
}
.discard {
.pull-right;
}
}
.element-drop-placeholder {
margin-left : 8px;
&:before {
margin: -8.5px 0px 0px -8px;
}
}
.empty-message {
margin: 8px;
color: grey;
font-style: italic;
text-align: center;
}
.no-elements-left-message {
text-align: left;
}
}
// ======================================================================== pair
.collection-creator.pair-collection-creator {
.footer {
margin-top: 8px;
}
.main-help {
cursor: pointer;
}
.collection-elements-controls {
margin-bottom: 8px;
.clear-selected {
.pull-right;
display: none;
}
}
.collection-elements {
max-height: 400px;
border: 0px solid lightgrey;
overflow-y: auto;
overflow-x: hidden;
}
// TODO: taken from .dataset above - swap these out
.collection-element {
height: 32px;
margin: 2px 4px 0px 4px;
opacity: 1.0;
border: 1px solid lightgrey;
border-radius: 3px;
padding: 0 8px 0 8px;
line-height: 28px;
cursor: pointer;
overflow: hidden;
&:last-of-type {
margin-bottom: 2px;
}
&:hover {
border-color: black;
}
button {
margin-top: 3px;
}
.identifier {
&:after {
content: ':';
margin-right: 6px;
}
}
.name {
&:hover {
text-decoration: none;
}
}
}
.empty-message {
margin: 8px;
color: grey;
font-style: italic;
text-align: center;
}
}
// ======================================================================== list of pairs
.collection-creator.list-of-pairs-collection-creator {
.column-headers {
margin-bottom: 8px;
}
}