Update Global Search, Due Cards, and My Cards to use the same

code for searching and display
reviewable/pr3676/r1
John R. Supplee 4 years ago
parent 8181074238
commit a1bda1169e
  1. 16
      client/components/main/dueCards.jade
  2. 119
      client/components/main/dueCards.js
  3. 33
      client/components/main/globalSearch.jade
  4. 234
      client/components/main/globalSearch.js
  5. 8
      client/components/main/myCards.jade
  6. 253
      client/components/main/myCards.js
  7. 246
      server/publications/cards.js

@ -22,13 +22,17 @@ template(name="dueCardsModalTitle")
template(name="dueCards")
if currentUser
if isPageReady.get
.wrapper
.due-cards-dueat-list-wrapper
each card in dueCardsList
+resultCard(card)
else
if searching.get
+spinner
else if hasResults.get
.global-search-results-list-wrapper
if hasQueryErrors.get
div
each msg in errorMessages
span.global-search-error-messages
= msg
else
+resultsPaged(this)
template(name="dueCardsViewChangePopup")
if currentUser

@ -1,3 +1,5 @@
import { CardSearchPagedComponent } from '../../lib/cardSearch';
const subManager = new SubsManager();
BlazeComponent.extendComponent({
@ -40,102 +42,43 @@ BlazeComponent.extendComponent({
},
}).register('dueCardsViewChangePopup');
BlazeComponent.extendComponent({
class DueCardsComponent extends CardSearchPagedComponent {
onCreated() {
this.isPageReady = new ReactiveVar(false);
this.autorun(() => {
const handle = subManager.subscribe(
'dueCards',
Utils.dueCardsView() === 'all',
);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
this.isPageReady.set(handle.ready());
});
});
});
Meteor.subscribe('setting');
},
super.onCreated();
const queryParams = {
has: [{ field: 'dueAt', exists: true }],
limit: 5,
skip: 0,
sort: { name: 'dueAt', order: 'des' },
};
if (Utils.dueCardsView() !== 'all') {
queryParams.users = [Meteor.user().username];
}
this.autorunGlobalSearch(queryParams);
}
dueCardsView() {
// eslint-disable-next-line no-console
//console.log('sort:', Utils.dueCardsView());
return Utils.dueCardsView();
},
}
sortByBoard() {
return this.dueCardsView() === 'board';
},
}
dueCardsList() {
const allUsers = Utils.dueCardsView() === 'all';
const user = Meteor.user();
const archivedBoards = [];
Boards.find({ archived: true }).forEach(board => {
archivedBoards.push(board._id);
});
const permiitedBoards = [];
let selector = {
archived: false,
};
// for every user including admin allow her to see cards only from public boards
// or those where she is a member
//if (!user.isAdmin) {
selector.$or = [
{ permission: 'public' },
{ members: { $elemMatch: { userId: user._id, isActive: true } } },
];
//}
Boards.find(selector).forEach(board => {
permiitedBoards.push(board._id);
});
const archivedSwimlanes = [];
Swimlanes.find({ archived: true }).forEach(swimlane => {
archivedSwimlanes.push(swimlane._id);
});
const archivedLists = [];
Lists.find({ archived: true }).forEach(list => {
archivedLists.push(list._id);
});
selector = {
archived: false,
boardId: {
$nin: archivedBoards,
$in: permiitedBoards,
},
swimlaneId: { $nin: archivedSwimlanes },
listId: { $nin: archivedLists },
dueAt: { $ne: null },
endAt: null,
};
if (!allUsers) {
selector.$or = [{ members: user._id }, { assignees: user._id }];
}
const results = this.getResults();
console.log('results:', results);
const cards = [];
// eslint-disable-next-line no-console
// console.log('cards selector:', selector);
Cards.find(selector).forEach(card => {
cards.push(card);
// eslint-disable-next-line no-console
// console.log(
// 'board:',
// card.board(),
// 'swimlane:',
// card.swimlane(),
// 'list:',
// card.list(),
// );
});
if (results) {
results.forEach(card => {
cards.push(card);
});
}
cards.sort((a, b) => {
const x = a.dueAt === null ? Date('2100-12-31') : a.dueAt;
@ -148,7 +91,9 @@ BlazeComponent.extendComponent({
});
// eslint-disable-next-line no-console
// console.log('cards:', cards);
console.log('cards:', cards);
return cards;
},
}).register('dueCards');
}
}
DueCardsComponent.register('dueCards');

@ -10,6 +10,23 @@ template(name="globalSearchModalTitle")
i.fa.fa-keyboard-o
| {{_ 'globalSearch-title'}}
template(name="resultsPaged")
h1
= resultsHeading.get
a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
each card in results.get
+resultCard(card)
table.global-search-footer
tr
td.global-search-previous-page
if hasPreviousPage.get
button.js-previous-page
| {{_ 'previous-page' }}
td.global-search-next-page(align="right")
if hasNextPage.get
button.js-next-page
| {{_ 'next-page' }}
template(name="globalSearch")
if currentUser
.wrapper
@ -32,21 +49,7 @@ template(name="globalSearch")
span.global-search-error-messages
= msg
else
h1
= resultsHeading.get
a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
each card in results.get
+resultCard(card)
table.global-search-footer
tr
td.global-search-previous-page
if hasPreviousPage.get
button.js-previous-page
| {{_ 'previous-page' }}
td.global-search-next-page(align="right")
if hasNextPage.get
button.js-next-page
| {{_ 'next-page' }}
+resultsPaged(this)
else
.global-search-page
.global-search-help

@ -1,4 +1,6 @@
const subManager = new SubsManager();
import { CardSearchPagedComponent } from '../../lib/cardSearch';
// const subManager = new SubsManager();
BlazeComponent.extendComponent({
events() {
@ -34,27 +36,15 @@ BlazeComponent.extendComponent({
},
}).register('globalSearchViewChangePopup');
BlazeComponent.extendComponent({
class GlobalSearchComponent extends CardSearchPagedComponent {
onCreated() {
this.searching = new ReactiveVar(false);
this.hasResults = new ReactiveVar(false);
this.hasQueryErrors = new ReactiveVar(false);
this.query = new ReactiveVar('');
this.resultsHeading = new ReactiveVar('');
this.searchLink = new ReactiveVar(null);
super.onCreated();
this.myLists = new ReactiveVar([]);
this.myLabelNames = new ReactiveVar([]);
this.myBoardNames = new ReactiveVar([]);
this.results = new ReactiveVar([]);
this.hasNextPage = new ReactiveVar(false);
this.hasPreviousPage = new ReactiveVar(false);
this.queryParams = null;
this.parsingErrors = [];
this.resultsCount = 0;
this.totalHits = 0;
this.queryErrors = null;
this.colorMap = null;
this.resultsPerPage = 25;
this.queryParams = null;
Meteor.call('myLists', (err, data) => {
if (!err) {
@ -73,7 +63,7 @@ BlazeComponent.extendComponent({
this.myBoardNames.set(data);
}
});
},
}
onRendered() {
Meteor.subscribe('setting');
@ -87,67 +77,19 @@ BlazeComponent.extendComponent({
if (Session.get('globalQuery')) {
this.searchAllBoards(Session.get('globalQuery'));
}
},
}
resetSearch() {
this.searching.set(false);
this.results.set([]);
this.hasResults.set(false);
this.hasQueryErrors.set(false);
this.resultsHeading.set('');
super.resetSearch();
this.parsingErrors = [];
this.resultsCount = 0;
this.totalHits = 0;
this.queryErrors = null;
},
getSessionData() {
return SessionData.findOne({
userId: Meteor.userId(),
sessionId: SessionData.getSessionId(),
});
},
getResults() {
// eslint-disable-next-line no-console
// console.log('getting results');
if (this.queryParams) {
const sessionData = this.getSessionData();
// eslint-disable-next-line no-console
// console.log('selector:', sessionData.getSelector());
// console.log('session data:', sessionData);
const projection = sessionData.getProjection();
projection.skip = 0;
const cards = Cards.find({ _id: { $in: sessionData.cards } }, projection);
this.queryErrors = sessionData.errors;
if (this.queryErrors.length) {
this.hasQueryErrors.set(true);
return null;
}
if (cards) {
this.totalHits = sessionData.totalHits;
this.resultsCount = cards.count();
this.resultsStart = sessionData.lastHit - this.resultsCount + 1;
this.resultsEnd = sessionData.lastHit;
this.resultsHeading.set(this.getResultsHeading());
this.results.set(cards);
this.hasNextPage.set(sessionData.lastHit < sessionData.totalHits);
this.hasPreviousPage.set(
sessionData.lastHit - sessionData.resultsCount > 0,
);
}
}
this.resultsCount = 0;
return null;
},
}
errorMessages() {
if (this.parsingErrors.length) {
return this.parsingErrorMessages();
}
return this.queryErrorMessages();
},
}
parsingErrorMessages() {
const messages = [];
@ -159,21 +101,7 @@ BlazeComponent.extendComponent({
}
return messages;
},
queryErrorMessages() {
messages = [];
this.queryErrors.forEach(err => {
let value = err.color ? TAPi18n.__(`color-${err.value}`) : err.value;
if (!value) {
value = err.value;
}
messages.push(TAPi18n.__(err.tag, value));
});
return messages;
},
}
searchAllBoards(query) {
query = query.trim();
@ -300,7 +228,7 @@ BlazeComponent.extendComponent({
let text = '';
while (query) {
m = query.match(reOperator1);
let m = query.match(reOperator1);
if (!m) {
m = query.match(reOperator2);
if (m) {
@ -326,7 +254,7 @@ BlazeComponent.extendComponent({
// console.log('found color:', value);
}
} else if (['dueAt', 'createdAt', 'modifiedAt'].includes(operator)) {
let days = parseInt(value, 10);
const days = parseInt(value, 10);
let duration = null;
if (isNaN(days)) {
// duration was specified as text
@ -335,7 +263,8 @@ BlazeComponent.extendComponent({
let date = null;
switch (duration) {
case 'week':
let week = moment().week();
// eslint-disable-next-line no-case-declarations
const week = moment().week();
if (week === 52) {
date = moment(1, 'W');
date.set('year', date.year() + 1);
@ -344,7 +273,8 @@ BlazeComponent.extendComponent({
}
break;
case 'month':
let month = moment().month();
// eslint-disable-next-line no-case-declarations
const month = moment().month();
// .month() is zero indexed
if (month === 11) {
date = moment(1, 'M');
@ -354,7 +284,8 @@ BlazeComponent.extendComponent({
}
break;
case 'quarter':
let quarter = moment().quarter();
// eslint-disable-next-line no-case-declarations
const quarter = moment().quarter();
if (quarter === 4) {
date = moment(1, 'Q');
date.set('year', date.year() + 1);
@ -384,22 +315,20 @@ BlazeComponent.extendComponent({
});
value = null;
}
} else if (operator === 'dueAt') {
value = {
operator: '$lt',
value: moment(moment().format('YYYY-MM-DD'))
.add(days + 1, duration ? duration : 'days')
.format(),
};
} else {
if (operator === 'dueAt') {
value = {
operator: '$lt',
value: moment(moment().format('YYYY-MM-DD'))
.add(days + 1, duration ? duration : 'days')
.format(),
};
} else {
value = {
operator: '$gte',
value: moment(moment().format('YYYY-MM-DD'))
.subtract(days, duration ? duration : 'days')
.format(),
};
}
value = {
operator: '$gte',
value: moment(moment().format('YYYY-MM-DD'))
.subtract(days, duration ? duration : 'days')
.format(),
};
}
} else if (operator === 'sort') {
let negated = false;
@ -502,81 +431,11 @@ BlazeComponent.extendComponent({
return;
}
this.autorun(() => {
const handle = Meteor.subscribe(
'globalSearch',
SessionData.getSessionId(),
params,
);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
if (handle.ready()) {
this.getResults();
this.searching.set(false);
this.hasResults.set(true);
}
});
});
});
},
nextPage() {
const sessionData = this.getSessionData();
this.autorun(() => {
const handle = Meteor.subscribe('nextPage', sessionData.sessionId);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
if (handle.ready()) {
this.getResults();
this.searching.set(false);
this.hasResults.set(true);
}
});
});
});
},
previousPage() {
const sessionData = this.getSessionData();
this.autorun(() => {
const handle = Meteor.subscribe('previousPage', sessionData.sessionId);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
if (handle.ready()) {
this.getResults();
this.searching.set(false);
this.hasResults.set(true);
}
});
});
});
},
getResultsHeading() {
if (this.resultsCount === 0) {
return TAPi18n.__('no-cards-found');
} else if (this.resultsCount === 1) {
return TAPi18n.__('one-card-found');
} else if (this.resultsCount === this.totalHits) {
return TAPi18n.__('n-cards-found', this.resultsCount);
}
return TAPi18n.__('n-n-of-n-cards-found', {
start: this.resultsStart,
end: this.resultsEnd,
total: this.totalHits,
});
},
getSearchHref() {
const baseUrl = window.location.href.replace(/([?#].*$|\s*$)/, '');
return `${baseUrl}?q=${encodeURIComponent(this.query.get())}`;
},
this.autorunGlobalSearch(params);
}
searchInstructions() {
tags = {
const tags = {
operator_board: TAPi18n.__('operator-board'),
operator_list: TAPi18n.__('operator-list'),
operator_swimlane: TAPi18n.__('operator-swimlane'),
@ -654,7 +513,7 @@ BlazeComponent.extendComponent({
[
'globalSearch-instructions-operator-has',
'globalSearch-instructions-operator-sort',
'globalSearch-instructions-operator-limit'
'globalSearch-instructions-operator-limit',
].forEach(instruction => {
text += `\n* ${TAPi18n.__(instruction, tags)}`;
});
@ -672,7 +531,7 @@ BlazeComponent.extendComponent({
});
return text;
},
}
labelColors() {
return Boards.simpleSchema()._schema['labels.$.color'].allowedValues.map(
@ -680,23 +539,16 @@ BlazeComponent.extendComponent({
return { color, name: TAPi18n.__(`color-${color}`) };
},
);
},
}
events() {
return [
{
...super.events()[0],
'submit .js-search-query-form'(evt) {
evt.preventDefault();
this.searchAllBoards(evt.target.searchQuery.value);
},
'click .js-next-page'(evt) {
evt.preventDefault();
this.nextPage();
},
'click .js-previous-page'(evt) {
evt.preventDefault();
this.previousPage();
},
'click .js-label-color'(evt) {
evt.preventDefault();
const input = document.getElementById('global-search-input');
@ -739,5 +591,7 @@ BlazeComponent.extendComponent({
},
},
];
},
}).register('globalSearch');
}
}
GlobalSearchComponent.register('globalSearch');

@ -24,14 +24,16 @@ template(name="myCardsModalTitle")
template(name="myCards")
if currentUser
if isPageReady.get
if searching.get
+spinner
else
.wrapper
if $eq myCardsSort 'board'
each board in myCardsList
.my-cards-board-wrapper
.my-cards-board-title(class=board.colorClass, id="header")
a(href=board.absoluteUrl)
+viewer
+viewer
= board.title
each swimlane in board.mySwimlanes
.my-cards-swimlane-title(class="{{#if swimlane.colorClass}}{{ swimlane.colorClass }}{{else}}swimlane-default-color{{/if}}")
@ -50,8 +52,6 @@ template(name="myCards")
.my-cards-dueat-list-wrapper
each card in myDueCardsList
+resultCard(card)
else
+spinner
template(name="myCardsSortChangePopup")
if currentUser

@ -1,3 +1,5 @@
import {CardSearchPagedComponent} from "../../lib/cardSearch";
const subManager = new SubsManager();
BlazeComponent.extendComponent({
@ -42,177 +44,139 @@ BlazeComponent.extendComponent({
},
}).register('myCardsSortChangePopup');
BlazeComponent.extendComponent({
class MyCardsComponent extends CardSearchPagedComponent {
onCreated() {
this.isPageReady = new ReactiveVar(false);
super.onCreated();
this.autorun(() => {
const handle = subManager.subscribe('myCards');
Tracker.nonreactive(() => {
Tracker.autorun(() => {
this.isPageReady.set(handle.ready());
});
});
});
const queryParams = {
users: [Meteor.user().username],
sort: { name: 'dueAt', order: 'des' },
};
this.autorunGlobalSearch(queryParams);
Meteor.subscribe('setting');
},
}
myCardsSort() {
// eslint-disable-next-line no-console
//console.log('sort:', Utils.myCardsSort());
return Utils.myCardsSort();
},
}
sortByBoard() {
return this.myCardsSort() === 'board';
},
}
myCardsList() {
const userId = Meteor.userId();
const boards = [];
let board = null;
let swimlane = null;
let list = null;
const cursor = Cards.find(
{
$or: [{ members: userId }, { assignees: userId }],
archived: false,
},
{
sort: {
boardId: 1,
swimlaneId: 1,
listId: 1,
sort: 1,
},
},
);
const cursor = this.getResults();
let newBoard = false;
let newSwimlane = false;
let newList = false;
if (cursor) {
let newBoard = false;
let newSwimlane = false;
let newList = false;
cursor.forEach(card => {
// eslint-disable-next-line no-console
// console.log('card:', card.title);
if (list === null || card.listId !== list._id) {
cursor.forEach(card => {
// eslint-disable-next-line no-console
// console.log('new list');
list = card.getList();
if (list.archived) {
list = null;
return;
// console.log('card:', card.title);
if (list === null || card.listId !== list._id) {
// eslint-disable-next-line no-console
// console.log('new list');
list = card.getList();
if (list.archived) {
list = null;
return;
}
list.myCards = [card];
newList = true;
}
list.myCards = [card];
newList = true;
}
if (swimlane === null || card.swimlaneId !== swimlane._id) {
// eslint-disable-next-line no-console
// console.log('new swimlane');
swimlane = card.getSwimlane();
if (swimlane.archived) {
swimlane = null;
return;
if (swimlane === null || card.swimlaneId !== swimlane._id) {
// eslint-disable-next-line no-console
// console.log('new swimlane');
swimlane = card.getSwimlane();
if (swimlane.archived) {
swimlane = null;
return;
}
swimlane.myLists = [list];
newSwimlane = true;
}
swimlane.myLists = [list];
newSwimlane = true;
}
if (board === null || card.boardId !== board._id) {
// eslint-disable-next-line no-console
// console.log('new board');
board = card.getBoard();
if (board.archived) {
board = null;
return;
if (board === null || card.boardId !== board._id) {
// eslint-disable-next-line no-console
// console.log('new board');
board = card.getBoard();
if (board.archived) {
board = null;
return;
}
// eslint-disable-next-line no-console
// console.log('board:', b, b._id, b.title);
board.mySwimlanes = [swimlane];
newBoard = true;
}
if (newBoard) {
boards.push(board);
} else if (newSwimlane) {
board.mySwimlanes.push(swimlane);
} else if (newList) {
swimlane.myLists.push(list);
} else {
list.myCards.push(card);
}
// eslint-disable-next-line no-console
// console.log('board:', b, b._id, b.title);
board.mySwimlanes = [swimlane];
newBoard = true;
}
if (newBoard) {
boards.push(board);
} else if (newSwimlane) {
board.mySwimlanes.push(swimlane);
} else if (newList) {
swimlane.myLists.push(list);
} else {
list.myCards.push(card);
}
newBoard = false;
newSwimlane = false;
newList = false;
});
// sort the data structure
boards.forEach(board => {
board.mySwimlanes.forEach(swimlane => {
swimlane.myLists.forEach(list => {
list.myCards.sort((a, b) => {
newBoard = false;
newSwimlane = false;
newList = false;
});
// sort the data structure
boards.forEach(board => {
board.mySwimlanes.forEach(swimlane => {
swimlane.myLists.forEach(list => {
list.myCards.sort((a, b) => {
return a.sort - b.sort;
});
});
swimlane.myLists.sort((a, b) => {
return a.sort - b.sort;
});
});
swimlane.myLists.sort((a, b) => {
board.mySwimlanes.sort((a, b) => {
return a.sort - b.sort;
});
});
board.mySwimlanes.sort((a, b) => {
return a.sort - b.sort;
});
});
boards.sort((a, b) => {
let x = a.sort;
let y = b.sort;
// show the template board last
if (a.type === 'template-container') {
x = 99999999;
} else if (b.type === 'template-container') {
y = 99999999;
}
return x - y;
});
boards.sort((a, b) => {
let x = a.sort;
let y = b.sort;
// eslint-disable-next-line no-console
// console.log('boards:', boards);
return boards;
},
myDueCardsList() {
const userId = Meteor.userId();
// show the template board last
if (a.type === 'template-container') {
x = 99999999;
} else if (b.type === 'template-container') {
y = 99999999;
}
return x - y;
});
const cursor = Cards.find(
{
$or: [{ members: userId }, { assignees: userId }],
archived: false,
},
{
sort: {
dueAt: -1,
boardId: 1,
swimlaneId: 1,
listId: 1,
sort: 1,
},
},
);
// eslint-disable-next-line no-console
// console.log('boards:', boards);
return boards;
}
// eslint-disable-next-line no-console
// console.log('cursor:', cursor);
return [];
}
myDueCardsList() {
const cursor = this.getResults();
const cards = [];
cursor.forEach(card => {
if (
!card.getBoard().archived &&
!card.getSwimlane().archived &&
!card.getList().archived
) {
cards.push(card);
}
cards.push(card);
});
cards.sort((a, b) => {
@ -228,23 +192,6 @@ BlazeComponent.extendComponent({
// eslint-disable-next-line no-console
// console.log('cursor:', cards);
return cards;
},
events() {
return [
{
// 'click .js-my-card'(evt) {
// const card = this.currentData().card;
// // eslint-disable-next-line no-console
// console.log('currentData():', this.currentData());
// // eslint-disable-next-line no-console
// console.log('card:', card);
// if (card) {
// Utils.goCardId(card._id);
// }
// evt.preventDefault();
// },
},
];
},
}).register('myCards');
}
}
MyCardsComponent.register('myCards');

@ -5,175 +5,38 @@ Meteor.publish('card', cardId => {
return Cards.find({ _id: cardId });
});
Meteor.publish('myCards', function() {
const userId = Meteor.userId();
const archivedBoards = [];
Boards.find({ archived: true }).forEach(board => {
archivedBoards.push(board._id);
});
const archivedSwimlanes = [];
Swimlanes.find({ archived: true }).forEach(swimlane => {
archivedSwimlanes.push(swimlane._id);
});
Meteor.publish('myCards', function(sessionId) {
const archivedLists = [];
Lists.find({ archived: true }).forEach(list => {
archivedLists.push(list._id);
});
selector = {
archived: false,
boardId: { $nin: archivedBoards },
swimlaneId: { $nin: archivedSwimlanes },
listId: { $nin: archivedLists },
$or: [{ members: userId }, { assignees: userId }],
const queryParams = {
users: [Meteor.user().username],
// limit: 25,
skip: 0,
// sort: { name: 'dueAt', order: 'des' },
};
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 buildQuery(sessionId, queryParams);
});
Meteor.publish('dueCards', function(allUsers = false) {
check(allUsers, Boolean);
// eslint-disable-next-line no-console
// console.log('all users:', allUsers);
const user = Users.findOne({ _id: this.userId });
const archivedBoards = [];
Boards.find({ archived: true }).forEach(board => {
archivedBoards.push(board._id);
});
const permiitedBoards = [];
let selector = {
archived: false,
};
selector.$or = [
{ permission: 'public' },
{ members: { $elemMatch: { userId: user._id, isActive: true } } },
];
Boards.find(selector).forEach(board => {
permiitedBoards.push(board._id);
});
const archivedSwimlanes = [];
Swimlanes.find({ archived: true }).forEach(swimlane => {
archivedSwimlanes.push(swimlane._id);
});
const archivedLists = [];
Lists.find({ archived: true }).forEach(list => {
archivedLists.push(list._id);
});
selector = {
archived: false,
boardId: { $nin: archivedBoards, $in: permiitedBoards },
swimlaneId: { $nin: archivedSwimlanes },
listId: { $nin: archivedLists },
dueAt: { $ne: null },
endAt: null,
};
if (!allUsers) {
selector.$or = [{ members: user._id }, { assignees: user._id }];
}
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('dueCards', function(sessionId, allUsers = false) {
// check(sessionId, String);
// check(allUsers, Boolean);
//
// // eslint-disable-next-line no-console
// // console.log('all users:', allUsers);
//
// const queryParams = {
// has: [{ field: 'dueAt', exists: true }],
// limit: 25,
// skip: 0,
// sort: { name: 'dueAt', order: 'des' },
// };
//
// if (!allUsers) {
// queryParams.users = [Meteor.user().username];
// }
//
// return buildQuery(sessionId, queryParams);
// });
Meteor.publish('globalSearch', function(sessionId, queryParams) {
check(sessionId, String);
@ -182,9 +45,11 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
// eslint-disable-next-line no-console
// console.log('queryParams:', queryParams);
return buildQuery(sessionId, queryParams);
});
function buildQuery(sessionId, queryParams) {
const userId = Meteor.userId();
// eslint-disable-next-line no-console
// console.log('userId:', userId);
const errors = new (class {
constructor() {
@ -267,7 +132,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
let archived = false;
let endAt = null;
if (queryParams.status.length) {
if (queryParams.status && queryParams.status.length) {
queryParams.status.forEach(status => {
if (status === 'archived') {
archived = true;
@ -320,7 +185,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
selector.endAt = endAt;
}
if (queryParams.boards.length) {
if (queryParams.boards && queryParams.boards.length) {
const queryBoards = [];
queryParams.boards.forEach(query => {
const boards = Boards.userSearch(userId, {
@ -338,7 +203,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
selector.boardId.$in = queryBoards;
}
if (queryParams.swimlanes.length) {
if (queryParams.swimlanes && queryParams.swimlanes.length) {
const querySwimlanes = [];
queryParams.swimlanes.forEach(query => {
const swimlanes = Swimlanes.find({
@ -360,7 +225,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
selector.swimlaneId.$in = querySwimlanes;
}
if (queryParams.lists.length) {
if (queryParams.lists && queryParams.lists.length) {
const queryLists = [];
queryParams.lists.forEach(query => {
const lists = Lists.find({
@ -382,7 +247,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
selector.listId.$in = queryLists;
}
if (queryParams.comments.length) {
if (queryParams.comments && queryParams.comments.length) {
const cardIds = CardComments.textSearch(userId, queryParams.comments).map(
com => {
return com.cardId;
@ -398,15 +263,15 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
['dueAt', 'createdAt', 'modifiedAt'].forEach(field => {
if (queryParams[field]) {
selector[field] = {};
selector[field][queryParams[field]['operator']] = new Date(
queryParams[field]['value'],
selector[field][queryParams[field].operator] = new Date(
queryParams[field].value,
);
}
});
const queryMembers = [];
const queryAssignees = [];
if (queryParams.users.length) {
if (queryParams.users && queryParams.users.length) {
queryParams.users.forEach(query => {
const users = Users.find({
username: query,
@ -422,7 +287,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
});
}
if (queryParams.members.length) {
if (queryParams.members && queryParams.members.length) {
queryParams.members.forEach(query => {
const users = Users.find({
username: query,
@ -437,7 +302,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
});
}
if (queryParams.assignees.length) {
if (queryParams.assignees && queryParams.assignees.length) {
queryParams.assignees.forEach(query => {
const users = Users.find({
username: query,
@ -465,7 +330,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
selector.assignees = { $in: queryAssignees };
}
if (queryParams.labels.length) {
if (queryParams.labels && queryParams.labels.length) {
queryParams.labels.forEach(label => {
const queryLabels = [];
@ -516,16 +381,26 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
});
}
if (queryParams.has.length) {
if (queryParams.has && queryParams.has.length) {
queryParams.has.forEach(has => {
switch (has.field) {
case 'attachment':
const attachments = Attachments.find({}, { fields: { cardId: 1 } });
selector.$and.push({ _id: { $in: attachments.map(a => a.cardId) } });
selector.$and.push({
_id: {
$in: Attachments.find({}, { fields: { cardId: 1 } }).map(
a => a.cardId,
),
},
});
break;
case 'checklist':
const checklists = Checklists.find({}, { fields: { cardId: 1 } });
selector.$and.push({ _id: { $in: checklists.map(a => a.cardId) } });
selector.$and.push({
_id: {
$in: Checklists.find({}, { fields: { cardId: 1 } }).map(
a => a.cardId,
),
},
});
break;
case 'description':
case 'startAt':
@ -677,7 +552,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
// console.log('projection:', projection);
return findCards(sessionId, selector, projection, errors);
});
}
Meteor.publish('brokenCards', function() {
const user = Users.findOne({ _id: this.userId });
@ -773,7 +648,8 @@ function findCards(sessionId, selector, projection, errors = null) {
const userId = Meteor.userId();
// eslint-disable-next-line no-console
// console.log('selector:', selector);
console.log('selector:', selector);
console.log('selector.$and:', selector.$and);
// eslint-disable-next-line no-console
// console.log('projection:', projection);
let cards;
@ -879,5 +755,5 @@ function findCards(sessionId, selector, projection, errors = null) {
];
}
return [SessionData.find({ userId: userId, sessionId })];
return [SessionData.find({ userId, sessionId })];
}

Loading…
Cancel
Save