wekan/client/lib/multiSelection.js

163 lines
3.5 KiB
JavaScript
Raw Normal View History

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();
},
count: function() {
return Cards.find(this.getMongoSelector()).count();
},
isEmpty: function() {
return this.count() === 0;
},
activate: function() {
if (! this.isActive()) {
EscapeActions.executeUpTo('detailsPane');
this._isActive.set(true);
Tracker.flush();
}
Sidebar.setView(this.sidebarView);
},
disable: function() {
if (this.isActive()) {
this._isActive.set(false);
if (Sidebar && Sidebar.getView() === this.sidebarView) {
Sidebar.setView();
}
this.reset();
}
},
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);
EscapeActions.register('multiselection',
function() { MultiSelection.disable(); },
function() { return MultiSelection.isActive(); }, {
noClickEscapeOn: '.js-minicard,.js-board-sidebar-content'
}
);