Skip to content

Commit 8b5ab4f

Browse files
authored
Merge pull request #45324 from dominictb/fix/43845-mention-list
2 parents 019fadc + 3782e22 commit 8b5ab4f

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

src/pages/home/report/ReportActionCompose/SuggestionMention.tsx

+32-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import lodashMapValues from 'lodash/mapValues';
33
import lodashSortBy from 'lodash/sortBy';
44
import type {ForwardedRef} from 'react';
55
import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
6-
import {useOnyx} from 'react-native-onyx';
76
import type {OnyxCollection} from 'react-native-onyx';
7+
import {useOnyx} from 'react-native-onyx';
88
import * as Expensicons from '@components/Icon/Expensicons';
99
import type {Mention} from '@components/MentionSuggestions';
1010
import MentionSuggestions from '@components/MentionSuggestions';
@@ -14,6 +14,7 @@ import useCurrentReportID from '@hooks/useCurrentReportID';
1414
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
1515
import useDebounce from '@hooks/useDebounce';
1616
import useLocalize from '@hooks/useLocalize';
17+
import localeCompare from '@libs/LocaleCompare';
1718
import * as LoginUtils from '@libs/LoginUtils';
1819
import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils';
1920
import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils';
@@ -56,6 +57,30 @@ type SuggestionPersonalDetailsList = Record<
5657
| null
5758
>;
5859

60+
function getDisplayName(details: PersonalDetails) {
61+
const displayNameFromAccountID = ReportUtils.getDisplayNameForParticipant(details.accountID);
62+
if (!displayNameFromAccountID) {
63+
return details.login?.length ? details.login : '';
64+
}
65+
return displayNameFromAccountID;
66+
}
67+
68+
/**
69+
* Comparison function to sort users. It compares weights, display names, and accountIDs in that order
70+
*/
71+
function compareUserInList(first: PersonalDetails & {weight: number}, second: PersonalDetails & {weight: number}) {
72+
if (first.weight !== second.weight) {
73+
return first.weight - second.weight;
74+
}
75+
76+
const displayNameLoginOrder = localeCompare(getDisplayName(first), getDisplayName(second));
77+
if (displayNameLoginOrder !== 0) {
78+
return displayNameLoginOrder;
79+
}
80+
81+
return first.accountID - second.accountID;
82+
}
83+
5984
function SuggestionMention(
6085
{value, selection, setSelection, updateComment, isAutoSuggestionPickerLarge, measureParentContainerAndReportCursor, isComposerFocused, isGroupPolicyReport, policyID}: SuggestionProps,
6186
ref: ForwardedRef<SuggestionsRef>,
@@ -270,9 +295,11 @@ function SuggestionMention(
270295
}
271296

272297
return true;
273-
});
298+
}) as Array<PersonalDetails & {weight: number}>;
299+
300+
// At this point we are sure that the details are not null, since empty user details have been filtered in the previous step
301+
const sortedPersonalDetails = filteredPersonalDetails.sort(compareUserInList);
274302

275-
const sortedPersonalDetails = lodashSortBy(filteredPersonalDetails, ['weight', 'displayName', 'login']);
276303
sortedPersonalDetails.slice(0, CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_SUGGESTIONS - suggestions.length).forEach((detail) => {
277304
suggestions.push({
278305
text: formatLoginPrivateDomain(PersonalDetailsUtils.getDisplayNameOrDefault(detail), detail?.login),
@@ -443,3 +470,5 @@ function SuggestionMention(
443470
SuggestionMention.displayName = 'SuggestionMention';
444471

445472
export default forwardRef(SuggestionMention);
473+
474+
export {compareUserInList};

tests/unit/compareUserInListTest.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {compareUserInList} from '@pages/home/report/ReportActionCompose/SuggestionMention';
2+
3+
describe('compareUserInList', () => {
4+
it('Should compare the weight if the weight is different', () => {
5+
const first = {login: 'John Doe', weight: 1, accountID: 1};
6+
const second = {login: 'Jane Doe', weight: 2, accountID: 2};
7+
expect(compareUserInList(first, second)).toBe(-1);
8+
expect(compareUserInList(second, first)).toBe(1);
9+
});
10+
11+
it('Should compare the displayName if the weight is the same', () => {
12+
const first = {login: 'águero', weight: 2, accountID: 3};
13+
const second = {login: 'Bronn', weight: 2, accountID: 4};
14+
const third = {login: 'Carol', weight: 2, accountID: 5};
15+
expect(compareUserInList(first, second)).toBe(-1);
16+
expect(compareUserInList(first, third)).toBe(-1);
17+
expect(compareUserInList(second, third)).toBe(-1);
18+
19+
expect(compareUserInList(second, first)).toBe(1);
20+
expect(compareUserInList(third, first)).toBe(1);
21+
expect(compareUserInList(third, second)).toBe(1);
22+
});
23+
24+
it('Should compare the accountID if both the weight and displayName are the same', () => {
25+
const first = {login: 'águero', weight: 2, accountID: 6};
26+
const second = {login: 'aguero', weight: 2, accountID: 7};
27+
expect(compareUserInList(first, second)).toBe(-1);
28+
expect(compareUserInList(second, first)).toBe(1);
29+
});
30+
});

0 commit comments

Comments
 (0)