|
|
|
@ -552,6 +552,11 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) { |
|
|
|
|
|
|
|
|
|
const attachments = Attachments.find({ 'original.name': regex }); |
|
|
|
|
|
|
|
|
|
// const comments = CardComments.find(
|
|
|
|
|
// { text: regex },
|
|
|
|
|
// { fields: { cardId: 1 } },
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
selector.$and.push({ |
|
|
|
|
$or: [ |
|
|
|
|
{ title: regex }, |
|
|
|
@ -566,6 +571,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) { |
|
|
|
|
}, |
|
|
|
|
{ _id: { $in: checklists.map(list => list.cardId) } }, |
|
|
|
|
{ _id: { $in: attachments.map(attach => attach.cardId) } }, |
|
|
|
|
// { _id: { $in: comments.map(com => com.cardId) } },
|
|
|
|
|
], |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
@ -580,89 +586,206 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) { |
|
|
|
|
// eslint-disable-next-line no-console
|
|
|
|
|
// console.log('selector.$and:', selector.$and);
|
|
|
|
|
|
|
|
|
|
let cards = null; |
|
|
|
|
|
|
|
|
|
if (!errors.hasErrors()) { |
|
|
|
|
const projection = { |
|
|
|
|
fields: { |
|
|
|
|
_id: 1, |
|
|
|
|
archived: 1, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
title: 1, |
|
|
|
|
type: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
members: 1, |
|
|
|
|
assignees: 1, |
|
|
|
|
colors: 1, |
|
|
|
|
dueAt: 1, |
|
|
|
|
createdAt: 1, |
|
|
|
|
modifiedAt: 1, |
|
|
|
|
labelIds: 1, |
|
|
|
|
customFields: 1, |
|
|
|
|
}, |
|
|
|
|
skip, |
|
|
|
|
limit, |
|
|
|
|
}; |
|
|
|
|
const projection = { |
|
|
|
|
fields: { |
|
|
|
|
_id: 1, |
|
|
|
|
archived: 1, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
title: 1, |
|
|
|
|
type: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
members: 1, |
|
|
|
|
assignees: 1, |
|
|
|
|
colors: 1, |
|
|
|
|
dueAt: 1, |
|
|
|
|
createdAt: 1, |
|
|
|
|
modifiedAt: 1, |
|
|
|
|
labelIds: 1, |
|
|
|
|
customFields: 1, |
|
|
|
|
}, |
|
|
|
|
sort: { |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
}, |
|
|
|
|
skip, |
|
|
|
|
limit, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
if (queryParams.sort === 'due') { |
|
|
|
|
projection.sort = { |
|
|
|
|
dueAt: 1, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
}; |
|
|
|
|
} else if (queryParams.sort === 'modified') { |
|
|
|
|
projection.sort = { |
|
|
|
|
modifiedAt: -1, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
}; |
|
|
|
|
} else if (queryParams.sort === 'created') { |
|
|
|
|
projection.sort = { |
|
|
|
|
createdAt: -1, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
}; |
|
|
|
|
} else if (queryParams.sort === 'system') { |
|
|
|
|
projection.sort = { |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
modifiedAt: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
}; |
|
|
|
|
if (queryParams.sort) { |
|
|
|
|
const order = queryParams.sort.order === 'asc' ? 1 : -1; |
|
|
|
|
switch (queryParams.sort.name) { |
|
|
|
|
case 'dueAt': |
|
|
|
|
projection.sort = { |
|
|
|
|
dueAt: order, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
}; |
|
|
|
|
break; |
|
|
|
|
case 'modifiedAt': |
|
|
|
|
projection.sort = { |
|
|
|
|
modifiedAt: order, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
}; |
|
|
|
|
break; |
|
|
|
|
case 'createdAt': |
|
|
|
|
projection.sort = { |
|
|
|
|
createdAt: order, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
}; |
|
|
|
|
break; |
|
|
|
|
case 'system': |
|
|
|
|
projection.sort = { |
|
|
|
|
boardId: order, |
|
|
|
|
swimlaneId: order, |
|
|
|
|
listId: order, |
|
|
|
|
modifiedAt: order, |
|
|
|
|
sort: order, |
|
|
|
|
}; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-console
|
|
|
|
|
// console.log('projection:', projection);
|
|
|
|
|
cards = Cards.find(selector, projection); |
|
|
|
|
// eslint-disable-next-line no-console
|
|
|
|
|
// console.log('projection:', projection);
|
|
|
|
|
|
|
|
|
|
return findCards(sessionId, selector, projection, errors); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Meteor.publish('brokenCards', function() { |
|
|
|
|
const user = Users.findOne({ _id: this.userId }); |
|
|
|
|
|
|
|
|
|
const permiitedBoards = [null]; |
|
|
|
|
let selector = {}; |
|
|
|
|
selector.$or = [ |
|
|
|
|
{ permission: 'public' }, |
|
|
|
|
{ members: { $elemMatch: { userId: user._id, isActive: true } } }, |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
Boards.find(selector).forEach(board => { |
|
|
|
|
permiitedBoards.push(board._id); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
selector = { |
|
|
|
|
boardId: { $in: permiitedBoards }, |
|
|
|
|
$or: [ |
|
|
|
|
{ boardId: { $in: [null, ''] } }, |
|
|
|
|
{ swimlaneId: { $in: [null, ''] } }, |
|
|
|
|
{ listId: { $in: [null, ''] } }, |
|
|
|
|
], |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const cards = Cards.find(selector, { |
|
|
|
|
fields: { |
|
|
|
|
_id: 1, |
|
|
|
|
archived: 1, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
title: 1, |
|
|
|
|
type: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
members: 1, |
|
|
|
|
assignees: 1, |
|
|
|
|
colors: 1, |
|
|
|
|
dueAt: 1, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const boards = []; |
|
|
|
|
const swimlanes = []; |
|
|
|
|
const lists = []; |
|
|
|
|
const users = []; |
|
|
|
|
|
|
|
|
|
cards.forEach(card => { |
|
|
|
|
if (card.boardId) boards.push(card.boardId); |
|
|
|
|
if (card.swimlaneId) swimlanes.push(card.swimlaneId); |
|
|
|
|
if (card.listId) lists.push(card.listId); |
|
|
|
|
if (card.members) { |
|
|
|
|
card.members.forEach(userId => { |
|
|
|
|
users.push(userId); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
if (card.assignees) { |
|
|
|
|
card.assignees.forEach(userId => { |
|
|
|
|
users.push(userId); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return [ |
|
|
|
|
cards, |
|
|
|
|
Boards.find({ _id: { $in: boards } }), |
|
|
|
|
Swimlanes.find({ _id: { $in: swimlanes } }), |
|
|
|
|
Lists.find({ _id: { $in: lists } }), |
|
|
|
|
Users.find({ _id: { $in: users } }, { fields: Users.safeFields }), |
|
|
|
|
]; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Meteor.publish('nextPage', function(sessionId) { |
|
|
|
|
check(sessionId, String); |
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-console
|
|
|
|
|
// console.log('count:', cards.count());
|
|
|
|
|
const session = SessionData.findOne({ sessionId }); |
|
|
|
|
const projection = session.getProjection(); |
|
|
|
|
projection.skip = session.lastHit; |
|
|
|
|
|
|
|
|
|
return findCards(sessionId, session.getSelector(), projection); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Meteor.publish('previousPage', function(sessionId) { |
|
|
|
|
check(sessionId, String); |
|
|
|
|
|
|
|
|
|
const session = SessionData.findOne({ sessionId }); |
|
|
|
|
const projection = session.getProjection(); |
|
|
|
|
projection.skip = session.lastHit - session.resultsCount - projection.limit; |
|
|
|
|
|
|
|
|
|
return findCards(sessionId, session.getSelector(), projection); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
function findCards(sessionId, selector, projection, errors = null) { |
|
|
|
|
// check(selector, Object);
|
|
|
|
|
// check(projection, Object);
|
|
|
|
|
const userId = Meteor.userId(); |
|
|
|
|
|
|
|
|
|
let cards; |
|
|
|
|
if (!errors || !errors.hasErrors()) { |
|
|
|
|
cards = Cards.find(selector, projection); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
console.log('selector:', selector); |
|
|
|
|
console.log('projection:', projection); |
|
|
|
|
console.log('count:', cards.count()); |
|
|
|
|
const update = { |
|
|
|
|
$set: { |
|
|
|
|
totalHits: 0, |
|
|
|
|
lastHit: 0, |
|
|
|
|
resultsCount: 0, |
|
|
|
|
cards: [], |
|
|
|
|
errors: errors.errorMessages(), |
|
|
|
|
selector: SessionData.pickle(selector), |
|
|
|
|
projection: SessionData.pickle(projection), |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
if (errors) { |
|
|
|
|
update.$set.errors = errors.errorMessages(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cards) { |
|
|
|
|
update.$set.totalHits = cards.count(); |
|
|
|
|
update.$set.lastHit = |
|
|
|
|
skip + limit < cards.count() ? skip + limit : cards.count(); |
|
|
|
|
projection.skip + projection.limit < cards.count() |
|
|
|
|
? projection.skip + projection.limit |
|
|
|
|
: cards.count(); |
|
|
|
|
update.$set.cards = cards.map(card => { |
|
|
|
|
return card._id; |
|
|
|
|
}); |
|
|
|
@ -735,79 +858,9 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) { |
|
|
|
|
Checklists.find({ cardId: { $in: cards.map(c => c._id) } }), |
|
|
|
|
Attachments.find({ cardId: { $in: cards.map(c => c._id) } }), |
|
|
|
|
CardComments.find({ cardId: { $in: cards.map(c => c._id) } }), |
|
|
|
|
SessionData.find({ userId: this.userId, sessionId }), |
|
|
|
|
SessionData.find({ userId, sessionId }), |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return [SessionData.find({ userId: this.userId, sessionId })]; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Meteor.publish('brokenCards', function() { |
|
|
|
|
const user = Users.findOne({ _id: this.userId }); |
|
|
|
|
|
|
|
|
|
const permiitedBoards = [null]; |
|
|
|
|
let selector = {}; |
|
|
|
|
selector.$or = [ |
|
|
|
|
{ permission: 'public' }, |
|
|
|
|
{ members: { $elemMatch: { userId: user._id, isActive: true } } }, |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
Boards.find(selector).forEach(board => { |
|
|
|
|
permiitedBoards.push(board._id); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
selector = { |
|
|
|
|
boardId: { $in: permiitedBoards }, |
|
|
|
|
$or: [ |
|
|
|
|
{ boardId: { $in: [null, ''] } }, |
|
|
|
|
{ swimlaneId: { $in: [null, ''] } }, |
|
|
|
|
{ listId: { $in: [null, ''] } }, |
|
|
|
|
], |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const cards = Cards.find(selector, { |
|
|
|
|
fields: { |
|
|
|
|
_id: 1, |
|
|
|
|
archived: 1, |
|
|
|
|
boardId: 1, |
|
|
|
|
swimlaneId: 1, |
|
|
|
|
listId: 1, |
|
|
|
|
title: 1, |
|
|
|
|
type: 1, |
|
|
|
|
sort: 1, |
|
|
|
|
members: 1, |
|
|
|
|
assignees: 1, |
|
|
|
|
colors: 1, |
|
|
|
|
dueAt: 1, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const boards = []; |
|
|
|
|
const swimlanes = []; |
|
|
|
|
const lists = []; |
|
|
|
|
const users = []; |
|
|
|
|
|
|
|
|
|
cards.forEach(card => { |
|
|
|
|
if (card.boardId) boards.push(card.boardId); |
|
|
|
|
if (card.swimlaneId) swimlanes.push(card.swimlaneId); |
|
|
|
|
if (card.listId) lists.push(card.listId); |
|
|
|
|
if (card.members) { |
|
|
|
|
card.members.forEach(userId => { |
|
|
|
|
users.push(userId); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
if (card.assignees) { |
|
|
|
|
card.assignees.forEach(userId => { |
|
|
|
|
users.push(userId); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return [ |
|
|
|
|
cards, |
|
|
|
|
Boards.find({ _id: { $in: boards } }), |
|
|
|
|
Swimlanes.find({ _id: { $in: swimlanes } }), |
|
|
|
|
Lists.find({ _id: { $in: lists } }), |
|
|
|
|
Users.find({ _id: { $in: users } }, { fields: Users.safeFields }), |
|
|
|
|
]; |
|
|
|
|
}); |
|
|
|
|
return [SessionData.find({ userId: userId, sessionId })]; |
|
|
|
|
} |
|
|
|
|