function getCardsBetween ( idA , idB ) {
function pluckId ( doc ) {
return doc . _id ;
}
function getListsStrictlyBetween ( id1 , id2 ) {
return Lists . find ( {
$and : [
{ sort : { $gt : Lists . findOne ( id1 ) . sort } } ,
{ sort : { $lt : Lists . findOne ( id2 ) . sort } } ,
] ,
archived : false ,
} ) . map ( pluckId ) ;
}
const cards = _ . sortBy ( [ Cards . findOne ( idA ) , Cards . findOne ( idB ) ] , c => {
return c . sort ;
} ) ;
let selector ;
if ( cards [ 0 ] . listId === cards [ 1 ] . listId ) {
selector = {
listId : cards [ 0 ] . listId ,
sort : {
$gte : cards [ 0 ] . sort ,
$lte : cards [ 1 ] . sort ,
} ,
archived : false ,
} ;
} else {
selector = {
$or : [
{
listId : cards [ 0 ] . listId ,
sort : { $lte : cards [ 0 ] . sort } ,
} ,
{
listId : {
$in : getListsStrictlyBetween ( cards [ 0 ] . listId , cards [ 1 ] . listId ) ,
} ,
} ,
{
listId : cards [ 1 ] . listId ,
sort : { $gte : cards [ 1 ] . sort } ,
} ,
] ,
archived : false ,
} ;
}
return Cards . find ( Filter . mongoSelector ( selector ) ) . map ( pluckId ) ;
}
MultiSelection = {
sidebarView : 'multiselection' ,
_selectedCards : new ReactiveVar ( [ ] ) ,
_isActive : new ReactiveVar ( false ) ,
startRangeCardId : null ,
reset ( ) {
this . _selectedCards . set ( [ ] ) ;
} ,
getMongoSelector ( ) {
return Filter . mongoSelector ( {
_id : { $in : this . _selectedCards . get ( ) } ,
} ) ;
} ,
isActive ( ) {
return this . _isActive . get ( ) ;
} ,
count ( ) {
return Cards . find ( this . getMongoSelector ( ) ) . count ( ) ;
} ,
isEmpty ( ) {
return this . count ( ) === 0 ;
} ,
activate ( ) {
if ( ! this . isActive ( ) ) {
EscapeActions . executeUpTo ( 'detailsPane' ) ;
this . _isActive . set ( true ) ;
Tracker . flush ( ) ;
}
Sidebar . setView ( this . sidebarView ) ;
} ,
disable ( ) {
if ( this . isActive ( ) ) {
this . _isActive . set ( false ) ;
if ( Sidebar && Sidebar . getView ( ) === this . sidebarView ) {
Sidebar . setView ( ) ;
}
this . reset ( ) ;
}
} ,
add ( cardIds ) {
return this . toggle ( cardIds , { add : true , remove : false } ) ;
} ,
remove ( cardIds ) {
return this . toggle ( cardIds , { add : false , remove : true } ) ;
} ,
toggleRange ( cardId ) {
const selectedCards = this . _selectedCards . get ( ) ;
this . reset ( ) ;
if ( ! this . isActive ( ) || selectedCards . length === 0 ) {
this . toggle ( cardId ) ;
} else {
const startRange = selectedCards [ selectedCards . length - 1 ] ;
this . toggle ( getCardsBetween ( startRange , cardId ) ) ;
}
} ,
toggle ( cardIds , options = { } ) {
cardIds = _ . isString ( cardIds ) ? [ cardIds ] : cardIds ;
options = {
add : true ,
remove : true ,
... options ,
} ;
if ( ! this . isActive ( ) ) {
this . reset ( ) ;
this . activate ( ) ;
}
const selectedCards = this . _selectedCards . get ( ) ;
cardIds . forEach ( cardId => {
const indexOfCard = selectedCards . indexOf ( cardId ) ;
if ( options . remove && indexOfCard > - 1 )
selectedCards . splice ( indexOfCard , 1 ) ;
else if ( options . add ) selectedCards . push ( cardId ) ;
} ) ;
this . _selectedCards . set ( selectedCards ) ;
} ,
isSelected ( cardId ) {
return this . _selectedCards . get ( ) . indexOf ( cardId ) > - 1 ;
} ,
} ;
Blaze . registerHelper ( 'MultiSelection' , MultiSelection ) ;
EscapeActions . register (
'multiselection' ,
( ) => {
MultiSelection . disable ( ) ;
} ,
( ) => {
return MultiSelection . isActive ( ) ;
} ,
{
noClickEscapeOn : '.js-minicard,.js-board-sidebar-content' ,
} ,
) ;