-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide autocomplete suggestions in SearchRouterList #51237
Provide autocomplete suggestions in SearchRouterList #51237
Conversation
Should we somehow limit the list of autosuggestions @luacmartins? This is POC implementation of autosuggestions for some of filters(the ones linked in description) poc.movI don't see much designs connected to autocomplete. |
@SzymczakJ I think we should only offer suggestions once the user typed at least one character after the filter key, e.g. |
Agree with Carlos that we'd suggest on the first character after the filter key. |
@SzymczakJ we discussed internally and the behavior we want for this is:
Does that make sense? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a quick glance the logic and data flow looks good 👌
I hope that in future we can somehow split the logic so that SearchRouter
does not become a "god component"
const singlePolicyTagsList: PolicyTagLists | undefined = allPoliciesTagsLists?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`]; | ||
if (!singlePolicyTagsList) { | ||
const uniqueTagNames = new Set<string>(); | ||
const tagListsUnpacked = Object.values(allPoliciesTagsLists ?? {}).filter((item) => !!item) as PolicyTagLists[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is possible to use default argument instead, and do
getAutoCompleteTagsList(allPoliciesTagsLists: OnyxCollection<PolicyTagLists> = {}, policyID?: string)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe our hands are tied by OnyxCollection which can be undefined.
const [cardList = {}] = useOnyx(ONYXKEYS.CARD_LIST); | ||
const cardsAutocompleteList = Object.values(cardList ?? {}).map((card) => card.bank); | ||
const personalDetails = usePersonalDetails(); | ||
const participantsAutocompleteList = Object.values(personalDetails) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I'm not sure there's a way around it. Maybe we can create a custom hook, useAutocomplete so the logic lives outside the component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is still WIP so maybe you might be aware of these issues already, but I wanted to point them out anyways so we can get ahead and make sure they don't make to the final version of the PR:
- I think we should limit the number of suggestions to maybe 10 sorted alphabetically. You can see on the list that if I type from, a full list of all personalDetails comes up, which seems a bit useless.
- Cycling through the options should update the query string, e.g. when I press the arrow keys to select a different option, the query in the router should update to include the currently active suggestion.
- Selecting an autocomplete suggestion runs the query, but it drops the filter key. Note in the video how I selected
from:t3@t.com
but the final search dropped thefrom:
part
Screen.Recording.2024-10-23.at.9.49.14.AM.mov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very small stuff, feel free to open PR when you're ready.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, this is looking really good. Just gonna report a few bugs that I found
BUG?: Pressing tab cycles through the options as it should, but it also removes the focus from the text input so the user has to click back into the input. This doesn't happen with the arrow navigation so users can keep typing into the input. We should make this behavior consistent. Tab: Screen.Recording.2024-10-25.at.12.52.50.PM.movArrows Screen.Recording.2024-10-25.at.12.54.18.PM.mov |
BUG: We should make suggestions case insensitive. For example, when searching for a currency, it correctly returns the results if I search in upper case, but nothing when searching in lower case Screen.Recording.2024-10-25.at.12.56.50.PM.mov |
BUG: Searching for categories with space results in no results and incorrect final syntax. Screen.Recording.2024-10-25.at.1.00.21.PM.mov |
This was also the tab behaviour of ChatFinderPage. I tried to make it not defocus TextInput but after investigating it for some time, I think we would need to modify https://github.com/Expensify/react-native-key-command library, which makes this "bug" harder to fix. |
@ikevin127 kind bump 🙇 |
Thanks for looking into it. I think it's ok to do this as a polish or wait until we get feedback that we should implement this. |
I'll start reviewing in ~ 1 hour. |
Reviewer Checklist
Screenshots/VideosAndroid: Nativeandroid.webmAndroid: mWeb Chromeandroid-mweb.webmiOS: Nativeios.mp4iOS: mWeb Safariios-mweb.mp4MacOS: Chrome / Safariweb.movMacOS: Desktopdesktop.mov |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Left a few small comments. We also have conflicts now and product is still testing this branch to make sure things are what we expect.
); | ||
return; | ||
} | ||
default: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB we can DRY the code above since they all run the same logic, just on different lists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this code looks easily "DRYable", but with Mateusz PR these switch cases will become much more distinct. Let's not add conflicts to his branch, as he said in #51237 (comment) 😄. After merging these two PRs we could put up a small clean-up PR.
return Array.from(uniqueCategoryNames); | ||
} | ||
return Object.values(singlePolicyRecentCategories ?? {}).map((category) => category); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB maybe we could DRY the logic in some of these functions too since the logic is 95% identical
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as in #51237 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's address the variable reaming/typos above
@ikevin127 @luacmartins @SzymczakJ Because of that I would like to suggest any NAB's and other improvements are not done here, but I will instead do them in my PR 😁 it will greatly help me. |
It results in infinite loading, because it doesn't make sense from UI point of view(we cannot be on an Expense tab and on Chat tab on the same moment). On the other hand I think that we shouldn't limit the user, even though his query may produce something that doesn't make sense. Maybe we could provide some modal on SearchResultsPage that tells user that 'This query doesn't make sense'. WDYT @luacmartins
No autocomplete was added for input "category:X ," because of the limitations of our parser. Here is my solution for this: when user adds "," to add another autocomplete then the spaces before "," are trimmed so our parser can parse it properly. Please check it out @luacmartins @ikevin127 and tell me WDYT proposal.mov |
Yea, I agree that this is an issue, but it also happens on main today because a user can type that. So NAB for this PR. I think ultimately, we need to improve the parser to validate some of these keys, like type, status, sortBy, sortOrder, etc so we handle this more gracefully. NAB for now though
I like it! Thanks for fixing that! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks to everybody for addressing and the issues!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM and tests well. Just waiting on final approval from the product team!
🧪🧪 Use the links below to test this adhoc build on Android, iOS, Desktop, and Web. Happy testing! 🧪🧪
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by https://github.com/luacmartins in version: 9.0.56-0 🚀
|
Details
This PR adds autocomplete in SearchRouter for simple keys like categories, tags, etc.. Searching with 'in:' keyword is not yet fully supported(reportIDs instead of full names will be visible in text input)
Fixed Issues
$ #50942
$ #50947
$ #50957
$ #50952
$ #50953
$ #50954
$ #50955
$ #50956
$ #50948
$ #50945
PROPOSAL:
Tests
Offline tests
QA Steps
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
android.mov
Android: mWeb Chrome
androidweb.mov
iOS: Native
ios.mov
iOS: mWeb Safari
iosweb.mov
MacOS: Chrome / Safari
web.mov
MacOS: Desktop
desktop.mov