Skip to content
Open
4 changes: 2 additions & 2 deletions src/components/Search/SearchAutocompleteList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,11 @@ function SearchAutocompleteList({

const reportOptions: OptionData[] = [...orderedOptions.recentReports, ...orderedOptions.personalDetails];
if (searchOptions.userToInvite) {
reportOptions.push(searchOptions.userToInvite);
reportOptions.push({...searchOptions.userToInvite, alternateText: translate('common.invite')});
}

return reportOptions.slice(0, 20);
}, [autocompleteQueryValue, searchOptions]);
}, [autocompleteQueryValue, searchOptions, translate]);

const debounceHandleSearch = useDebounce(() => {
if (!handleSearch || !autocompleteQueryWithoutFilters) {
Expand Down
7 changes: 5 additions & 2 deletions src/libs/OptionsListUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1922,13 +1922,16 @@ function canCreateOptimisticPersonalDetailOption({
currentUserOption?: SearchOptionData | null;
searchValue: string;
}) {
if (recentReportOptions.length + personalDetailsOptions.length > 0) {
const normalizedSearchValue = addSMSDomainIfPhoneNumber(searchValue ?? '').toLowerCase();
const hasExactLoginMatch =
recentReportOptions.some((o) => o.login?.toLowerCase() === normalizedSearchValue) || personalDetailsOptions.some((o) => o.login?.toLowerCase() === normalizedSearchValue);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Compare raw phone logins before adding invite row

The new exact-match gate only compares option logins against addSMSDomainIfPhoneNumber(searchValue), which misses existing contacts whose login is stored as raw E.164 (e.g. +15005550006 without @expensify.sms). In that case, typing that exact phone number still passes canCreateOptimisticPersonalDetailOption, so userToInvite is created even though an exact contact already exists, yielding a duplicate/inaccurate “Invite” result. This regression is reachable in flows where phone logins are kept without the SMS suffix.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@15antonian
Check this comment please

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, addressed. Updated canCreateOptimisticPersonalDetailOption to also match logins stored as raw E.164 (no @expensify.sms suffix), and added two regression tests covering both storage formats. Existing tests still pass.

if (hasExactLoginMatch) {
return false;
}
if (!currentUserOption) {
return true;
}
return currentUserOption.login !== addSMSDomainIfPhoneNumber(searchValue ?? '').toLowerCase() && currentUserOption.login !== searchValue?.toLowerCase();
return currentUserOption.login !== normalizedSearchValue && currentUserOption.login !== searchValue?.toLowerCase();
}

/**
Expand Down
Loading
Loading