PR3: Add debounce logic to user search#1742
Conversation
1d1df62 to
99399bc
Compare
eb64d34 to
391560a
Compare
| .then(items => { | ||
| res.status(OK).send({ items, total, rowsPerPage: ROWS_PER_PAGE, }); | ||
| }) | ||
| .catch((e) => { |
There was a problem hiding this comment.
you can remove the "e" in the catch, since you're not using it
7fb53f2 to
abef8fd
Compare
| const parts = query.trim().split(/\s+/); | ||
| const first = parts[0]; | ||
| const last = parts[parts.length - 1]; | ||
| const nameRegex = new RegExp(`^${first}.*${last}`, 'i'); |
There was a problem hiding this comment.
what if we do a match using whatever the user typed
so if i was searching for person one, i could match it by typing pone
| const nameRegex = new RegExp(`^${first}.*${last}`, 'i'); | |
| const query = req.body.query.replace(/\s/g, ''); | |
| const pattern = new RegExp(`.*${query}.*`); |
another example the above would match on would be person o, as right now the pr's logic is expecting the entire first and last name to by typed out to do a match
There was a problem hiding this comment.
New suggestion: Instead of matching the first and last name, the backend will match the record using the input sequence:
const query = req.body.query.replace(/\s/g, '');
const fuzzyPattern = query.split('').join('.*');
const pattern = new RegExp(fuzzyPattern, 'i');
This trades off O(n) performance for maximum flexibility. Note: this approach does not ignore discrepancies in middle names.
| { | ||
| $expr: { | ||
| $regexMatch: { | ||
| input: { $concat: ['$firstName', ' ', '$lastName'] }, |
There was a problem hiding this comment.
see other comment about regex change, we can just do
| input: { $concat: ['$firstName', ' ', '$lastName'] }, | |
| input: { $concat: ['$firstName', '$lastName'] }, |
| const limit = Math.min(Number(req.body.limit) || ROWS_PER_PAGE, ROWS_PER_PAGE); | ||
| let maybeOr = {}; | ||
| const query = req.body.query; | ||
| if (query) { |
There was a problem hiding this comment.
if the user didnt pass a query in should we even bother displaying suggestions?
if (!req.body.query) {
return res.status(OK).send({ items: [] });
}| }; | ||
| } | ||
|
|
||
| const sortColumn = req.query.sort || 'joinDate'; |
There was a problem hiding this comment.
is there a way to have mongodb return the result based on best match? https://stackoverflow.com/a/27224578
There was a problem hiding this comment.
Done!
Implement scoring approach:
const aScore = Math.min(tokenScores(aName, input), tokenScores(aEmail, input));
const bScore = Math.min(tokenScores(bName, input), tokenScores(bEmail, input));
return aScore - bScore;
| User.find(maybeOr, { password: 0, }, { skip, limit }) | ||
| .sort({ [sortColumn] : sortOrder }) | ||
| .then(items => { | ||
| res.status(OK).send({ items, total, rowsPerPage: ROWS_PER_PAGE, }); |
There was a problem hiding this comment.
total and rowsPerPage are unused in the frontend, can we remove it
| res.status(OK).send({ items, total, rowsPerPage: ROWS_PER_PAGE, }); | ||
| }) | ||
| .catch(() => { | ||
| res.sendStatus(BAD_REQUEST); |
There was a problem hiding this comment.
import logger and log the error, would be good for debugging
| const ROWS_PER_PAGE = 20; | ||
|
|
||
| // Search for all members using either first name, last name or email | ||
| router.post('/shortcutsearchusers', async function(req, res) { |
There was a problem hiding this comment.
this api can go in User.js instead of a new file
There was a problem hiding this comment.
Done! Migrated codes to user.js
c13cf4c to
cc96df4
Compare
cc96df4 to
b568e60
Compare
|
|
||
| it('Should return status code 401 if access level is invalid', async () => { | ||
| accessLevel = MEMBERSHIP_STATE.MEMBER; | ||
| setTokenStatus(accessLevel >= requiredLevel, {accessLevel}); |
There was a problem hiding this comment.
each line with accessLevel >= requiredLevel, please hardcode it to true/false, it will read much easier
| if (str.startsWith(token)) return score + 0; // highest score for exact match | ||
| else if (str.includes(token)) return score + 1; // lower score for partial match | ||
| else return score + 2; // lowest score for no match |
There was a problem hiding this comment.
| if (str.startsWith(token)) return score + 0; // highest score for exact match | |
| else if (str.includes(token)) return score + 1; // lower score for partial match | |
| else return score + 2; // lowest score for no match | |
| if (str.startsWith(token)) return score + 0; // highest score for exact match | |
| if (str.includes(token)) return score + 1; // lower score for partial match | |
| return score + 2; // lowest score for no match |
Co-authored-by: Evan Ugarte <36345325+evanugarte@users.noreply.github.com>
Merge #1748 first.
This PR builds on top of PR2 (search UI) and introduces debounce logic to reduce API calls during user input.
Officer and Admin can search for users.
UI screenshots:
Light mode:

Dark mode:
