mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 23:40:13 +01:00
Start work on paging search results
This commit is contained in:
parent
7ad1171c5f
commit
4e8fc46475
5 changed files with 348 additions and 230 deletions
|
|
@ -37,6 +37,12 @@ template(name="globalSearch")
|
||||||
a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
|
a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
|
||||||
each card in results.get
|
each card in results.get
|
||||||
+resultCard(card)
|
+resultCard(card)
|
||||||
|
if hasPreviousPage.get
|
||||||
|
button.js-previous-page
|
||||||
|
| {{_ 'previous-page' }}
|
||||||
|
if hasNextPage.get
|
||||||
|
button.js-next-page
|
||||||
|
| {{_ 'next-page' }}
|
||||||
else
|
else
|
||||||
.global-search-instructions
|
.global-search-instructions
|
||||||
h2 {{_ 'boards' }}
|
h2 {{_ 'boards' }}
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,15 @@ BlazeComponent.extendComponent({
|
||||||
this.myLabelNames = new ReactiveVar([]);
|
this.myLabelNames = new ReactiveVar([]);
|
||||||
this.myBoardNames = new ReactiveVar([]);
|
this.myBoardNames = new ReactiveVar([]);
|
||||||
this.results = new ReactiveVar([]);
|
this.results = new ReactiveVar([]);
|
||||||
|
this.hasNextPage = new ReactiveVar(false);
|
||||||
|
this.hasPreviousPage = new ReactiveVar(false);
|
||||||
this.queryParams = null;
|
this.queryParams = null;
|
||||||
this.parsingErrors = [];
|
this.parsingErrors = [];
|
||||||
this.resultsCount = 0;
|
this.resultsCount = 0;
|
||||||
this.totalHits = 0;
|
this.totalHits = 0;
|
||||||
this.queryErrors = null;
|
this.queryErrors = null;
|
||||||
this.colorMap = null;
|
this.colorMap = null;
|
||||||
|
this.resultsPerPage = 25;
|
||||||
|
|
||||||
Meteor.call('myLists', (err, data) => {
|
Meteor.call('myLists', (err, data) => {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
|
@ -100,17 +103,21 @@ BlazeComponent.extendComponent({
|
||||||
this.queryErrors = null;
|
this.queryErrors = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSessionData() {
|
||||||
|
return SessionData.findOne({
|
||||||
|
userId: Meteor.userId(),
|
||||||
|
sessionId: SessionData.getSessionId(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
getResults() {
|
getResults() {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
// console.log('getting results');
|
// console.log('getting results');
|
||||||
if (this.queryParams) {
|
if (this.queryParams) {
|
||||||
const sessionData = SessionData.findOne({
|
const sessionData = this.getSessionData();
|
||||||
userId: Meteor.userId(),
|
|
||||||
sessionId: SessionData.getSessionId(),
|
|
||||||
});
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('selector:', JSON.parse(sessionData.selector));
|
||||||
// console.log('session data:', sessionData);
|
// console.log('session data:', sessionData);
|
||||||
|
|
||||||
const cards = Cards.find({ _id: { $in: sessionData.cards } });
|
const cards = Cards.find({ _id: { $in: sessionData.cards } });
|
||||||
this.queryErrors = sessionData.errors;
|
this.queryErrors = sessionData.errors;
|
||||||
if (this.queryErrors.length) {
|
if (this.queryErrors.length) {
|
||||||
|
|
@ -121,8 +128,14 @@ BlazeComponent.extendComponent({
|
||||||
if (cards) {
|
if (cards) {
|
||||||
this.totalHits = sessionData.totalHits;
|
this.totalHits = sessionData.totalHits;
|
||||||
this.resultsCount = cards.count();
|
this.resultsCount = cards.count();
|
||||||
|
this.resultsStart = sessionData.lastHit - this.resultsCount + 1;
|
||||||
|
this.resultsEnd = sessionData.lastHit;
|
||||||
this.resultsHeading.set(this.getResultsHeading());
|
this.resultsHeading.set(this.getResultsHeading());
|
||||||
this.results.set(cards);
|
this.results.set(cards);
|
||||||
|
this.hasNextPage.set(sessionData.lastHit < sessionData.totalHits);
|
||||||
|
this.hasPreviousPage.set(
|
||||||
|
sessionData.lastHit - sessionData.resultsCount > 0,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.resultsCount = 0;
|
this.resultsCount = 0;
|
||||||
|
|
@ -243,6 +256,7 @@ BlazeComponent.extendComponent({
|
||||||
// console.log('operatorMap:', operatorMap);
|
// console.log('operatorMap:', operatorMap);
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
|
limit: this.resultsPerPage,
|
||||||
boards: [],
|
boards: [],
|
||||||
swimlanes: [],
|
swimlanes: [],
|
||||||
lists: [],
|
lists: [],
|
||||||
|
|
@ -395,6 +409,61 @@ BlazeComponent.extendComponent({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
nextPage() {
|
||||||
|
sessionData = this.getSessionData();
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
limit: this.resultsPerPage,
|
||||||
|
selector: JSON.parse(sessionData.selector),
|
||||||
|
skip: sessionData.lastHit,
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
previousPage() {
|
||||||
|
sessionData = this.getSessionData();
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
limit: this.resultsPerPage,
|
||||||
|
selector: JSON.parse(sessionData.selector),
|
||||||
|
skip:
|
||||||
|
sessionData.lastHit - sessionData.resultsCount - this.resultsPerPage,
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
getResultsHeading() {
|
getResultsHeading() {
|
||||||
if (this.resultsCount === 0) {
|
if (this.resultsCount === 0) {
|
||||||
return TAPi18n.__('no-cards-found');
|
return TAPi18n.__('no-cards-found');
|
||||||
|
|
@ -405,8 +474,8 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
return TAPi18n.__('n-n-of-n-cards-found', {
|
return TAPi18n.__('n-n-of-n-cards-found', {
|
||||||
start: 1,
|
start: this.resultsStart,
|
||||||
end: this.resultsCount,
|
end: this.resultsEnd,
|
||||||
total: this.totalHits,
|
total: this.totalHits,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -526,6 +595,14 @@ BlazeComponent.extendComponent({
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
this.searchAllBoards(evt.target.searchQuery.value);
|
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) {
|
'click .js-label-color'(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
const input = document.getElementById('global-search-input');
|
const input = document.getElementById('global-search-input');
|
||||||
|
|
|
||||||
|
|
@ -917,6 +917,8 @@
|
||||||
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
|
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
|
||||||
"operator-sort-invalid": "sort of '%s' is invalid",
|
"operator-sort-invalid": "sort of '%s' is invalid",
|
||||||
"operator-status-invalid": "'%s' is not a valid status",
|
"operator-status-invalid": "'%s' is not a valid status",
|
||||||
|
"next-page": "Next Page",
|
||||||
|
"previous-page": "Previous Page",
|
||||||
"heading-notes": "Notes",
|
"heading-notes": "Notes",
|
||||||
"globalSearch-instructions-heading": "Search Instructions",
|
"globalSearch-instructions-heading": "Search Instructions",
|
||||||
"globalSearch-instructions-description": "Searches can include operators to refine the search. Operators are specified by writing the operator name and value separated by a colon. For example, an operator specification of `list:Blocked` would limit the search to cards that are contained in a list named *Blocked*. If the value contains spaces or special characters it must be enclosed in quotation marks (e.g. `__operator_list__:\"To Review\"`).",
|
"globalSearch-instructions-description": "Searches can include operators to refine the search. Operators are specified by writing the operator name and value separated by a colon. For example, an operator specification of `list:Blocked` would limit the search to cards that are contained in a list named *Blocked*. If the value contains spaces or special characters it must be enclosed in quotation marks (e.g. `__operator_list__:\"To Review\"`).",
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,13 @@ SessionData.attachSchema(
|
||||||
type: Number,
|
type: Number,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
resultsCount: {
|
||||||
|
/**
|
||||||
|
* number of results returned
|
||||||
|
*/
|
||||||
|
type: Number,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
lastHit: {
|
lastHit: {
|
||||||
/**
|
/**
|
||||||
* the last hit returned from a report query
|
* the last hit returned from a report query
|
||||||
|
|
@ -50,6 +57,11 @@ SessionData.attachSchema(
|
||||||
type: [String],
|
type: [String],
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
selector: {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
blackbox: true,
|
||||||
|
},
|
||||||
errorMessages: {
|
errorMessages: {
|
||||||
type: [String],
|
type: [String],
|
||||||
optional: true,
|
optional: true,
|
||||||
|
|
|
||||||
|
|
@ -205,8 +205,8 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
hasErrors() {
|
hasErrors() {
|
||||||
for (const prop in this.notFound) {
|
for (const value of Object.values(this.notFound)) {
|
||||||
if (this.notFound[prop].length) {
|
if (value.length) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,245 +247,255 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
let archived = false;
|
let selector = {};
|
||||||
let endAt = null;
|
let skip = 0;
|
||||||
if (queryParams.status.length) {
|
if (queryParams.skip) {
|
||||||
queryParams.status.forEach(status => {
|
skip = queryParams.skip;
|
||||||
if (status === 'archived') {
|
}
|
||||||
archived = true;
|
let limit = 25;
|
||||||
} else if (status === 'all') {
|
if (queryParams.limit) {
|
||||||
archived = null;
|
limit = queryParams.limit;
|
||||||
} else if (status === 'ended') {
|
|
||||||
endAt = { $nin: [null, ''] };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
const selector = {
|
|
||||||
type: 'cardType-card',
|
|
||||||
// boardId: { $in: Boards.userBoardIds(userId) },
|
|
||||||
$and: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const boardsSelector = {};
|
if (queryParams.selector) {
|
||||||
if (archived !== null) {
|
selector = queryParams.selector;
|
||||||
boardsSelector.archived = archived;
|
} else {
|
||||||
if (archived) {
|
let archived = false;
|
||||||
|
let endAt = null;
|
||||||
|
if (queryParams.status.length) {
|
||||||
|
queryParams.status.forEach(status => {
|
||||||
|
if (status === 'archived') {
|
||||||
|
archived = true;
|
||||||
|
} else if (status === 'all') {
|
||||||
|
archived = null;
|
||||||
|
} else if (status === 'ended') {
|
||||||
|
endAt = { $nin: [null, ''] };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
selector = {
|
||||||
|
type: 'cardType-card',
|
||||||
|
// boardId: { $in: Boards.userBoardIds(userId) },
|
||||||
|
$and: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const boardsSelector = {};
|
||||||
|
if (archived !== null) {
|
||||||
|
boardsSelector.archived = archived;
|
||||||
|
if (archived) {
|
||||||
|
selector.boardId = { $in: Boards.userBoardIds(userId, null) };
|
||||||
|
selector.$and.push({
|
||||||
|
$or: [
|
||||||
|
{ boardId: { $in: Boards.userBoardIds(userId, archived) } },
|
||||||
|
{ swimlaneId: { $in: Swimlanes.archivedSwimlaneIds() } },
|
||||||
|
{ listId: { $in: Lists.archivedListIds() } },
|
||||||
|
{ archived: true },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
selector.boardId = { $in: Boards.userBoardIds(userId, false) };
|
||||||
|
selector.swimlaneId = { $nin: Swimlanes.archivedSwimlaneIds() };
|
||||||
|
selector.listId = { $nin: Lists.archivedListIds() };
|
||||||
|
selector.archived = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
selector.boardId = { $in: Boards.userBoardIds(userId, null) };
|
selector.boardId = { $in: Boards.userBoardIds(userId, null) };
|
||||||
|
}
|
||||||
|
if (endAt !== null) {
|
||||||
|
selector.endAt = endAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.boards.length) {
|
||||||
|
const queryBoards = [];
|
||||||
|
queryParams.boards.forEach(query => {
|
||||||
|
const boards = Boards.userSearch(userId, {
|
||||||
|
title: new RegExp(escapeForRegex(query), 'i'),
|
||||||
|
});
|
||||||
|
if (boards.count()) {
|
||||||
|
boards.forEach(board => {
|
||||||
|
queryBoards.push(board._id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errors.notFound.boards.push(query);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
selector.boardId.$in = queryBoards;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.swimlanes.length) {
|
||||||
|
const querySwimlanes = [];
|
||||||
|
queryParams.swimlanes.forEach(query => {
|
||||||
|
const swimlanes = Swimlanes.find({
|
||||||
|
title: new RegExp(escapeForRegex(query), 'i'),
|
||||||
|
});
|
||||||
|
if (swimlanes.count()) {
|
||||||
|
swimlanes.forEach(swim => {
|
||||||
|
querySwimlanes.push(swim._id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errors.notFound.swimlanes.push(query);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
selector.swimlaneId.$in = querySwimlanes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.lists.length) {
|
||||||
|
const queryLists = [];
|
||||||
|
queryParams.lists.forEach(query => {
|
||||||
|
const lists = Lists.find({
|
||||||
|
title: new RegExp(escapeForRegex(query), 'i'),
|
||||||
|
});
|
||||||
|
if (lists.count()) {
|
||||||
|
lists.forEach(list => {
|
||||||
|
queryLists.push(list._id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errors.notFound.lists.push(query);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
selector.listId.$in = queryLists;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.comments.length) {
|
||||||
|
const cardIds = CardComments.textSearch(userId, queryParams.comments).map(
|
||||||
|
com => {
|
||||||
|
return com.cardId;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (cardIds.length) {
|
||||||
|
selector._id = { $in: cardIds };
|
||||||
|
} else {
|
||||||
|
errors.notFound.comments.push(queryParams.comments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.dueAt !== null) {
|
||||||
|
selector.dueAt = { $lte: new Date(queryParams.dueAt) };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.createdAt !== null) {
|
||||||
|
selector.createdAt = { $gte: new Date(queryParams.createdAt) };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.modifiedAt !== null) {
|
||||||
|
selector.modifiedAt = { $gte: new Date(queryParams.modifiedAt) };
|
||||||
|
}
|
||||||
|
|
||||||
|
const queryMembers = [];
|
||||||
|
const queryAssignees = [];
|
||||||
|
if (queryParams.users.length) {
|
||||||
|
queryParams.users.forEach(query => {
|
||||||
|
const users = Users.find({
|
||||||
|
username: query,
|
||||||
|
});
|
||||||
|
if (users.count()) {
|
||||||
|
users.forEach(user => {
|
||||||
|
queryMembers.push(user._id);
|
||||||
|
queryAssignees.push(user._id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errors.notFound.users.push(query);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.members.length) {
|
||||||
|
queryParams.members.forEach(query => {
|
||||||
|
const users = Users.find({
|
||||||
|
username: query,
|
||||||
|
});
|
||||||
|
if (users.count()) {
|
||||||
|
users.forEach(user => {
|
||||||
|
queryMembers.push(user._id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errors.notFound.members.push(query);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.assignees.length) {
|
||||||
|
queryParams.assignees.forEach(query => {
|
||||||
|
const users = Users.find({
|
||||||
|
username: query,
|
||||||
|
});
|
||||||
|
if (users.count()) {
|
||||||
|
users.forEach(user => {
|
||||||
|
queryAssignees.push(user._id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errors.notFound.assignees.push(query);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryMembers.length && queryAssignees.length) {
|
||||||
selector.$and.push({
|
selector.$and.push({
|
||||||
$or: [
|
$or: [
|
||||||
{ boardId: { $in: Boards.userBoardIds(userId, archived) } },
|
{ members: { $in: queryMembers } },
|
||||||
{ swimlaneId: { $in: Swimlanes.archivedSwimlaneIds() } },
|
{ assignees: { $in: queryAssignees } },
|
||||||
{ listId: { $in: Lists.archivedListIds() } },
|
|
||||||
{ archived: true },
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
} else {
|
} else if (queryMembers.length) {
|
||||||
selector.boardId = { $in: Boards.userBoardIds(userId, false) };
|
selector.members = { $in: queryMembers };
|
||||||
selector.swimlaneId = { $nin: Swimlanes.archivedSwimlaneIds() };
|
} else if (queryAssignees.length) {
|
||||||
selector.listId = { $nin: Lists.archivedListIds() };
|
selector.assignees = { $in: queryAssignees };
|
||||||
selector.archived = false;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
selector.boardId = { $in: Boards.userBoardIds(userId, null) };
|
|
||||||
}
|
|
||||||
if (endAt !== null) {
|
|
||||||
selector.endAt = endAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.boards.length) {
|
if (queryParams.labels.length) {
|
||||||
const queryBoards = [];
|
queryParams.labels.forEach(label => {
|
||||||
queryParams.boards.forEach(query => {
|
const queryLabels = [];
|
||||||
const boards = Boards.userSearch(userId, {
|
|
||||||
title: new RegExp(escapeForRegex(query), 'i'),
|
|
||||||
});
|
|
||||||
if (boards.count()) {
|
|
||||||
boards.forEach(board => {
|
|
||||||
queryBoards.push(board._id);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
errors.notFound.boards.push(query);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
selector.boardId.$in = queryBoards;
|
let boards = Boards.userSearch(userId, {
|
||||||
}
|
labels: { $elemMatch: { color: label.toLowerCase() } },
|
||||||
|
|
||||||
if (queryParams.swimlanes.length) {
|
|
||||||
const querySwimlanes = [];
|
|
||||||
queryParams.swimlanes.forEach(query => {
|
|
||||||
const swimlanes = Swimlanes.find({
|
|
||||||
title: new RegExp(escapeForRegex(query), 'i'),
|
|
||||||
});
|
|
||||||
if (swimlanes.count()) {
|
|
||||||
swimlanes.forEach(swim => {
|
|
||||||
querySwimlanes.push(swim._id);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
errors.notFound.swimlanes.push(query);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
selector.swimlaneId.$in = querySwimlanes;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.lists.length) {
|
|
||||||
const queryLists = [];
|
|
||||||
queryParams.lists.forEach(query => {
|
|
||||||
const lists = Lists.find({
|
|
||||||
title: new RegExp(escapeForRegex(query), 'i'),
|
|
||||||
});
|
|
||||||
if (lists.count()) {
|
|
||||||
lists.forEach(list => {
|
|
||||||
queryLists.push(list._id);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
errors.notFound.lists.push(query);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
selector.listId.$in = queryLists;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.comments.length) {
|
|
||||||
const cardIds = CardComments.textSearch(userId, queryParams.comments).map(
|
|
||||||
com => {
|
|
||||||
return com.cardId;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (cardIds.length) {
|
|
||||||
selector._id = { $in: cardIds };
|
|
||||||
} else {
|
|
||||||
errors.notFound.comments.push(queryParams.comments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.dueAt !== null) {
|
|
||||||
selector.dueAt = { $lte: new Date(queryParams.dueAt) };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.createdAt !== null) {
|
|
||||||
selector.createdAt = { $gte: new Date(queryParams.createdAt) };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.modifiedAt !== null) {
|
|
||||||
selector.modifiedAt = { $gte: new Date(queryParams.modifiedAt) };
|
|
||||||
}
|
|
||||||
|
|
||||||
const queryMembers = [];
|
|
||||||
const queryAssignees = [];
|
|
||||||
if (queryParams.users.length) {
|
|
||||||
queryParams.users.forEach(query => {
|
|
||||||
const users = Users.find({
|
|
||||||
username: query,
|
|
||||||
});
|
|
||||||
if (users.count()) {
|
|
||||||
users.forEach(user => {
|
|
||||||
queryMembers.push(user._id);
|
|
||||||
queryAssignees.push(user._id);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
errors.notFound.users.push(query);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.members.length) {
|
|
||||||
queryParams.members.forEach(query => {
|
|
||||||
const users = Users.find({
|
|
||||||
username: query,
|
|
||||||
});
|
|
||||||
if (users.count()) {
|
|
||||||
users.forEach(user => {
|
|
||||||
queryMembers.push(user._id);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
errors.notFound.members.push(query);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.assignees.length) {
|
|
||||||
queryParams.assignees.forEach(query => {
|
|
||||||
const users = Users.find({
|
|
||||||
username: query,
|
|
||||||
});
|
|
||||||
if (users.count()) {
|
|
||||||
users.forEach(user => {
|
|
||||||
queryAssignees.push(user._id);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
errors.notFound.assignees.push(query);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryMembers.length && queryAssignees.length) {
|
|
||||||
selector.$and.push({
|
|
||||||
$or: [
|
|
||||||
{ members: { $in: queryMembers } },
|
|
||||||
{ assignees: { $in: queryAssignees } },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
} else if (queryMembers.length) {
|
|
||||||
selector.members = { $in: queryMembers };
|
|
||||||
} else if (queryAssignees.length) {
|
|
||||||
selector.assignees = { $in: queryAssignees };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryParams.labels.length) {
|
|
||||||
queryParams.labels.forEach(label => {
|
|
||||||
const queryLabels = [];
|
|
||||||
|
|
||||||
let boards = Boards.userSearch(userId, {
|
|
||||||
labels: { $elemMatch: { color: label.toLowerCase() } },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (boards.count()) {
|
|
||||||
boards.forEach(board => {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
// console.log('board:', board);
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
// console.log('board.labels:', board.labels);
|
|
||||||
board.labels
|
|
||||||
.filter(boardLabel => {
|
|
||||||
return boardLabel.color === label.toLowerCase();
|
|
||||||
})
|
|
||||||
.forEach(boardLabel => {
|
|
||||||
queryLabels.push(boardLabel._id);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
// console.log('label:', label);
|
|
||||||
const reLabel = new RegExp(escapeForRegex(label), 'i');
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
// console.log('reLabel:', reLabel);
|
|
||||||
boards = Boards.userSearch(userId, {
|
|
||||||
labels: { $elemMatch: { name: reLabel } },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (boards.count()) {
|
if (boards.count()) {
|
||||||
boards.forEach(board => {
|
boards.forEach(board => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log('board:', board);
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log('board.labels:', board.labels);
|
||||||
board.labels
|
board.labels
|
||||||
.filter(boardLabel => {
|
.filter(boardLabel => {
|
||||||
return boardLabel.name.match(reLabel);
|
return boardLabel.color === label.toLowerCase();
|
||||||
})
|
})
|
||||||
.forEach(boardLabel => {
|
.forEach(boardLabel => {
|
||||||
queryLabels.push(boardLabel._id);
|
queryLabels.push(boardLabel._id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
errors.notFound.labels.push(label);
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log('label:', label);
|
||||||
|
const reLabel = new RegExp(escapeForRegex(label), 'i');
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
// console.log('reLabel:', reLabel);
|
||||||
|
boards = Boards.userSearch(userId, {
|
||||||
|
labels: { $elemMatch: { name: reLabel } },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (boards.count()) {
|
||||||
|
boards.forEach(board => {
|
||||||
|
board.labels
|
||||||
|
.filter(boardLabel => {
|
||||||
|
return boardLabel.name.match(reLabel);
|
||||||
|
})
|
||||||
|
.forEach(boardLabel => {
|
||||||
|
queryLabels.push(boardLabel._id);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errors.notFound.labels.push(label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
selector.labelIds = { $in: queryLabels };
|
selector.labelIds = { $in: queryLabels };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let cards = null;
|
|
||||||
|
|
||||||
if (!errors.hasErrors()) {
|
|
||||||
if (queryParams.text) {
|
if (queryParams.text) {
|
||||||
const regex = new RegExp(escapeForRegex(queryParams.text), 'i');
|
const regex = new RegExp(escapeForRegex(queryParams.text), 'i');
|
||||||
|
|
||||||
|
|
@ -508,12 +518,16 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
|
||||||
if (selector.$and.length === 0) {
|
if (selector.$and.length === 0) {
|
||||||
delete selector.$and;
|
delete selector.$and;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('selector:', selector);
|
console.log('selector:', selector);
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('selector.$and:', selector.$and);
|
console.log('selector.$and:', selector.$and);
|
||||||
|
|
||||||
|
let cards = null;
|
||||||
|
|
||||||
|
if (!errors.hasErrors()) {
|
||||||
const projection = {
|
const projection = {
|
||||||
fields: {
|
fields: {
|
||||||
_id: 1,
|
_id: 1,
|
||||||
|
|
@ -532,7 +546,8 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
|
||||||
modifiedAt: 1,
|
modifiedAt: 1,
|
||||||
labelIds: 1,
|
labelIds: 1,
|
||||||
},
|
},
|
||||||
limit: 50,
|
skip,
|
||||||
|
limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (queryParams.sort === 'due') {
|
if (queryParams.sort === 'due') {
|
||||||
|
|
@ -569,27 +584,33 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('projection:', projection);
|
||||||
cards = Cards.find(selector, projection);
|
cards = Cards.find(selector, projection);
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
// console.log('count:', cards.count());
|
console.log('count:', cards.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
const update = {
|
const update = {
|
||||||
$set: {
|
$set: {
|
||||||
totalHits: 0,
|
totalHits: 0,
|
||||||
lastHit: 0,
|
lastHit: 0,
|
||||||
|
resultsCount: 0,
|
||||||
cards: [],
|
cards: [],
|
||||||
errors: errors.errorMessages(),
|
errors: errors.errorMessages(),
|
||||||
|
selector: JSON.stringify(selector),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cards) {
|
if (cards) {
|
||||||
update.$set.totalHits = cards.count();
|
update.$set.totalHits = cards.count();
|
||||||
update.$set.lastHit = cards.count() > 50 ? 50 : cards.count();
|
update.$set.lastHit =
|
||||||
|
skip + limit < cards.count() ? skip + limit : cards.count();
|
||||||
update.$set.cards = cards.map(card => {
|
update.$set.cards = cards.map(card => {
|
||||||
return card._id;
|
return card._id;
|
||||||
});
|
});
|
||||||
|
update.$set.resultsCount = update.$set.cards.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
SessionData.upsert({ userId, sessionId }, update);
|
SessionData.upsert({ userId, sessionId }, update);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue