From 319783b00886105bdae16d3863d183adb2f53f67 Mon Sep 17 00:00:00 2001 From: "John R. Supplee" Date: Thu, 21 Jan 2021 18:11:09 +0200 Subject: [PATCH] Global search: add new operators * add operators for due, created and modified --- client/components/main/globalSearch.js | 35 ++++++++++++++++++++++++-- i18n/en.i18n.json | 4 +++ models/cards.js | 18 +++++++++++-- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/client/components/main/globalSearch.js b/client/components/main/globalSearch.js index cfb698edc..8ad6aec2f 100644 --- a/client/components/main/globalSearch.js +++ b/client/components/main/globalSearch.js @@ -209,9 +209,12 @@ BlazeComponent.extendComponent({ operatorMap[TAPi18n.__('operator-assignee')] = 'assignees'; operatorMap[TAPi18n.__('operator-assignee-abbrev')] = 'assignees'; operatorMap[TAPi18n.__('operator-is')] = 'is'; + operatorMap[TAPi18n.__('operator-due')] = 'dueAt'; + operatorMap[TAPi18n.__('operator-created')] = 'createdAt'; + operatorMap[TAPi18n.__('operator-modified')] = 'modifiedAt'; // eslint-disable-next-line no-console - // console.log('operatorMap:', operatorMap); + console.log('operatorMap:', operatorMap); const params = { boards: [], swimlanes: [], @@ -221,6 +224,9 @@ BlazeComponent.extendComponent({ assignees: [], labels: [], is: [], + dueAt: null, + createdAt: null, + modifiedAt: null, }; let text = ''; @@ -247,8 +253,33 @@ BlazeComponent.extendComponent({ if (value in this.colorMap) { value = this.colorMap[value]; } + } else if ( + ['dueAt', 'createdAt', 'modifiedAt'].includes(operatorMap[op]) + ) { + const days = parseInt(value, 10); + if (isNaN(days)) { + if (['day', 'week', 'month', 'quarter', 'year'].includes(value)) { + value = moment() + .subtract(1, value) + .format(); + } else { + this.parsingErrors.push({ + tag: 'operator-number-expected', + value: { operator: op, value }, + }); + value = null; + } + } else { + value = moment() + .subtract(days, 'days') + .format(); + } + } + if (Array.isArray(params[operatorMap[op]])) { + params[operatorMap[op]].push(value); + } else { + params[operatorMap[op]] = value; } - params[operatorMap[op]].push(value); } else { this.parsingErrors.push({ tag: 'operator-unknown-error', diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 533b0fbb1..3e020dac7 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -895,7 +895,11 @@ "operator-assignee": "assignee", "operator-assignee-abbrev": "a", "operator-is": "is", + "operator-due": "due", + "operator-created": "created", + "operator-modified": "modified", "operator-unknown-error": "%s is not an operator", + "operator-number-expected": "operator __operator__ expected a number, got '__value__'", "heading-notes": "Notes", "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\"`).", diff --git a/models/cards.js b/models/cards.js index 65977ef2a..dd2b347bc 100644 --- a/models/cards.js +++ b/models/cards.js @@ -1954,6 +1954,18 @@ Cards.globalSearch = queryParams => { selector.listId.$in = queryLists; } + if (queryParams.dueAt !== null) { + selector.dueAt = { $gte: 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) { @@ -2079,7 +2091,7 @@ Cards.globalSearch = queryParams => { } // eslint-disable-next-line no-console - // console.log('selector:', selector); + console.log('selector:', selector); const cards = Cards.find(selector, { fields: { _id: 1, @@ -2094,13 +2106,15 @@ Cards.globalSearch = queryParams => { assignees: 1, colors: 1, dueAt: 1, + createdAt: 1, + modifiedAt: 1, labelIds: 1, }, limit: 50, }); // eslint-disable-next-line no-console - // console.log('count:', cards.count()); + console.log('count:', cards.count()); return { cards, errors }; };