2015-05-29 23:35:30 +02:00
|
|
|
|
|
|
|
var getCardsBetween = function(idA, idB) {
|
|
|
|
|
|
|
|
var pluckId = function(doc) {
|
|
|
|
return doc._id;
|
|
|
|
};
|
|
|
|
|
|
|
|
var getListsStrictlyBetween = function(id1, id2) {
|
|
|
|
return Lists.find({
|
|
|
|
$and: [
|
|
|
|
{ sort: { $gt: Lists.findOne(id1).sort } },
|
|
|
|
{ sort: { $lt: Lists.findOne(id2).sort } }
|
|
|
|
],
|
|
|
|
archived: false
|
|
|
|
}).map(pluckId);
|
|
|
|
};
|
|
|
|
|
|
|
|
var cards = _.sortBy([Cards.findOne(idA), Cards.findOne(idB)], function(c) {
|
|
|
|
return c.sort;
|
|
|
|
});
|
|
|
|
|
|
|
|
var 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: function() {
|
|
|
|
this._selectedCards.set([]);
|
|
|
|
},
|
|
|
|
|
|
|
|
getMongoSelector: function() {
|
|
|
|
return Filter.mongoSelector({
|
|
|
|
_id: { $in: this._selectedCards.get() }
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
isActive: function() {
|
|
|
|
return this._isActive.get();
|
|
|
|
},
|
|
|
|
|
2015-06-15 17:16:56 +02:00
|
|
|
count: function() {
|
|
|
|
return Cards.find(this.getMongoSelector()).count();
|
|
|
|
},
|
|
|
|
|
2015-05-29 23:35:30 +02:00
|
|
|
isEmpty: function() {
|
2015-06-15 17:16:56 +02:00
|
|
|
return this.count() === 0;
|
2015-05-29 23:35:30 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
activate: function() {
|
|
|
|
if (! this.isActive()) {
|
2015-06-07 10:30:27 +02:00
|
|
|
EscapeActions.executeUpTo('detailsPane');
|
2015-05-29 23:35:30 +02:00
|
|
|
this._isActive.set(true);
|
|
|
|
Tracker.flush();
|
|
|
|
}
|
2015-06-15 17:16:56 +02:00
|
|
|
Sidebar.setView(this.sidebarView);
|
2015-05-29 23:35:30 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
disable: function() {
|
|
|
|
if (this.isActive()) {
|
|
|
|
this._isActive.set(false);
|
|
|
|
if (Sidebar && Sidebar.getView() === this.sidebarView) {
|
|
|
|
Sidebar.setView();
|
|
|
|
}
|
2015-06-07 10:30:27 +02:00
|
|
|
this.reset();
|
2015-05-29 23:35:30 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
add: function(cardIds) {
|
|
|
|
return this.toogle(cardIds, { add: true, remove: false });
|
|
|
|
},
|
|
|
|
|
|
|
|
remove: function(cardIds) {
|
|
|
|
return this.toogle(cardIds, { add: false, remove: true });
|
|
|
|
},
|
|
|
|
|
|
|
|
toogleRange: function(cardId) {
|
|
|
|
var selectedCards = this._selectedCards.get();
|
|
|
|
var startRange;
|
|
|
|
this.reset();
|
|
|
|
if (! this.isActive() || selectedCards.length === 0) {
|
|
|
|
this.toogle(cardId);
|
|
|
|
} else {
|
|
|
|
startRange = selectedCards[selectedCards.length - 1];
|
|
|
|
this.toogle(getCardsBetween(startRange, cardId));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
toogle: function(cardIds, options) {
|
|
|
|
var self = this;
|
|
|
|
cardIds = _.isString(cardIds) ? [cardIds] : cardIds;
|
|
|
|
options = _.extend({
|
|
|
|
add: true,
|
|
|
|
remove: true
|
|
|
|
}, options || {});
|
|
|
|
|
|
|
|
if (! self.isActive()) {
|
|
|
|
self.reset();
|
|
|
|
self.activate();
|
|
|
|
}
|
|
|
|
|
|
|
|
var selectedCards = self._selectedCards.get();
|
|
|
|
|
|
|
|
_.each(cardIds, function(cardId) {
|
|
|
|
var indexOfCard = selectedCards.indexOf(cardId);
|
|
|
|
|
|
|
|
if (options.remove && indexOfCard > -1)
|
|
|
|
selectedCards.splice(indexOfCard, 1);
|
|
|
|
|
|
|
|
else if (options.add)
|
|
|
|
selectedCards.push(cardId);
|
|
|
|
});
|
|
|
|
|
|
|
|
self._selectedCards.set(selectedCards);
|
|
|
|
},
|
|
|
|
|
|
|
|
isSelected: function(cardId) {
|
|
|
|
return this._selectedCards.get().indexOf(cardId) > -1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Blaze.registerHelper('MultiSelection', MultiSelection);
|
|
|
|
|
2015-06-07 10:30:27 +02:00
|
|
|
EscapeActions.register('multiselection',
|
2015-05-29 23:35:30 +02:00
|
|
|
function() { MultiSelection.disable(); },
|
2015-06-15 17:16:56 +02:00
|
|
|
function() { return MultiSelection.isActive(); }, {
|
|
|
|
noClickEscapeOn: '.js-minicard,.js-board-sidebar-content'
|
|
|
|
}
|
2015-05-29 23:35:30 +02:00
|
|
|
);
|