Skip to content

Commit b0bdb46

Browse files
authored
Merge pull request #81157 from dukenv0307/fix/66380-part-5
refactor createFilteredOptionList and createOptionFromReport to use privateIsArchived
2 parents 45f8101 + 3e83f2f commit b0bdb46

File tree

7 files changed

+297
-11
lines changed

7 files changed

+297
-11
lines changed

src/components/OptionListContextProvider.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ function OptionsListContextProvider({children}: OptionsListProviderProps) {
5656
const [, {sourceValue: changedReportActions}] = useOnyx(ONYXKEYS.COLLECTION.REPORT_ACTIONS, {canBeMissing: true});
5757
const personalDetails = usePersonalDetails();
5858
const prevPersonalDetails = usePrevious(personalDetails);
59+
const privateIsArchivedMap = usePrivateIsArchivedMap();
5960
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
6061
const currentUserAccountID = currentUserPersonalDetails.accountID;
6162
const hasInitialData = useMemo(() => Object.keys(personalDetails ?? {}).length > 0, [personalDetails]);
62-
const privateIsArchivedMap = usePrivateIsArchivedMap();
6363

6464
const loadOptions = useCallback(() => {
6565
const optionLists = createOptionList(personalDetails, currentUserAccountID, privateIsArchivedMap, reports, reportAttributes?.reports);
@@ -226,7 +226,8 @@ function OptionsListContextProvider({children}: OptionsListProviderProps) {
226226
continue;
227227
}
228228

229-
const newReportOption = createOptionFromReport(report, personalDetails, currentUserAccountID, reportAttributes?.reports, {showPersonalDetails: true});
229+
const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report.reportID}`];
230+
const newReportOption = createOptionFromReport(report, personalDetails, currentUserAccountID, privateIsArchived, reportAttributes?.reports, {showPersonalDetails: true});
230231
const replaceIndex = options.reports.findIndex((option) => option.reportID === report.reportID);
231232
newReportOptions.push({
232233
newReportOption,

src/components/Search/SearchFiltersChatsSelector.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import {usePersonalDetails} from '@components/OnyxListItemProvider';
44
import {useOptionsList} from '@components/OptionListContextProvider';
55
import InviteMemberListItem from '@components/SelectionList/ListItem/InviteMemberListItem';
66
import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
7-
import useArchivedReportsIdSet from '@hooks/useArchivedReportsIdSet';
87
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
98
import useDebouncedState from '@hooks/useDebouncedState';
109
import useLocalize from '@hooks/useLocalize';
1110
import useOnyx from '@hooks/useOnyx';
11+
import usePrivateIsArchivedMap from '@hooks/usePrivateIsArchivedMap';
1212
import useScreenWrapperTransitionStatus from '@hooks/useScreenWrapperTransitionStatus';
1313
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
1414
import {createOptionFromReport, filterAndOrderOptions, formatSectionsFromSearchTerm, getAlternateText, getSearchOptions} from '@libs/OptionsListUtils';
@@ -61,14 +61,15 @@ function SearchFiltersChatsSelector({initialReportIDs, onFiltersUpdate, isScreen
6161
const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState('');
6262
const cleanSearchTerm = searchTerm.trim().toLowerCase();
6363
const [draftComments] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, {canBeMissing: true});
64-
const archivedReportsIdSet = useArchivedReportsIdSet();
64+
const privateIsArchivedMap = usePrivateIsArchivedMap();
6565
const [nvpDismissedProductTraining] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {canBeMissing: true});
6666

6767
const selectedOptions: OptionData[] = selectedReportIDs.map((id) => {
68+
const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${id}`];
6869
const report = getSelectedOptionData(
69-
createOptionFromReport({...reports?.[`${ONYXKEYS.COLLECTION.REPORT}${id}`], reportID: id}, personalDetails, currentUserAccountID, reportAttributesDerived),
70+
createOptionFromReport({...reports?.[`${ONYXKEYS.COLLECTION.REPORT}${id}`], reportID: id}, personalDetails, currentUserAccountID, privateIsArchived, reportAttributesDerived),
7071
);
71-
const isReportArchived = archivedReportsIdSet.has(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report.reportID}`);
72+
const isReportArchived = !!privateIsArchived;
7273
const alternateText = getAlternateText(report, {}, isReportArchived, currentUserAccountID, {}, reportAttributesDerived);
7374
return {...report, alternateText};
7475
});

src/components/Search/SearchRouter/SearchRouter.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import useKeyboardShortcut from '@hooks/useKeyboardShortcut';
2222
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
2323
import useLocalize from '@hooks/useLocalize';
2424
import useOnyx from '@hooks/useOnyx';
25+
import usePrivateIsArchivedMap from '@hooks/usePrivateIsArchivedMap';
2526
import useResponsiveLayout from '@hooks/useResponsiveLayout';
2627
import useRootNavigationState from '@hooks/useRootNavigationState';
2728
import useThemeStyles from '@hooks/useThemeStyles';
@@ -74,6 +75,7 @@ function SearchRouter({onRouterClose, shouldHideInputCaret, isSearchRouterDispla
7475
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true});
7576
const [nonPersonalAndWorkspaceCards] = useOnyx(ONYXKEYS.DERIVED.NON_PERSONAL_AND_WORKSPACE_CARD_LIST, {canBeMissing: true});
7677
const [allFeeds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, {canBeMissing: true});
78+
const privateIsArchivedMap = usePrivateIsArchivedMap();
7779
const {shouldUseNarrowLayout} = useResponsiveLayout();
7880
const listRef = useRef<SelectionListHandle>(null);
7981
const expensifyIcons = useMemoizedLazyExpensifyIcons(['MagnifyingGlass']);
@@ -112,7 +114,8 @@ function SearchRouter({onRouterClose, shouldHideInputCaret, isSearchRouterDispla
112114
return undefined;
113115
}
114116

115-
const option = createOptionFromReport(report, personalDetails, currentUserAccountID, undefined, {showPersonalDetails: true});
117+
const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${contextualReportID}`];
118+
const option = createOptionFromReport(report, personalDetails, currentUserAccountID, privateIsArchived, undefined, {showPersonalDetails: true});
116119
reportForContextualSearch = option;
117120
}
118121

@@ -174,6 +177,7 @@ function SearchRouter({onRouterClose, shouldHideInputCaret, isSearchRouterDispla
174177
reports,
175178
personalDetails,
176179
currentUserAccountID,
180+
privateIsArchivedMap,
177181
],
178182
);
179183

src/hooks/useFilteredOptions.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
77
import type Beta from '@src/types/onyx/Beta';
88
import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails';
99
import useOnyx from './useOnyx';
10+
import usePrivateIsArchivedMap from './usePrivateIsArchivedMap';
1011

1112
type UseFilteredOptionsConfig = {
1213
/** Maximum number of recent reports to pre-filter and process (default: 500). */
@@ -79,11 +80,13 @@ function useFilteredOptions(config: UseFilteredOptionsConfig = {}): UseFilteredO
7980
});
8081
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
8182

83+
const privateIsArchivedMap = usePrivateIsArchivedMap();
84+
8285
const totalReports = allReports ? Object.keys(allReports).length : 0;
8386

8487
const options: OptionList | null =
8588
enabled && allReports && allPersonalDetails
86-
? createFilteredOptionList(allPersonalDetails, allReports, currentUserPersonalDetails.accountID, reportAttributesDerived, {
89+
? createFilteredOptionList(allPersonalDetails, allReports, currentUserPersonalDetails.accountID, reportAttributesDerived, privateIsArchivedMap, {
8790
maxRecentReports: reportsLimit,
8891
includeP2P,
8992
searchTerm,

src/libs/OptionsListUtils/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,7 @@ function createFilteredOptionList(
13461346
reports: OnyxCollection<Report>,
13471347
currentUserAccountID: number,
13481348
reportAttributesDerived: ReportAttributesDerivedValue['reports'] | undefined,
1349+
privateIsArchivedMap: PrivateIsArchivedMap,
13491350
options: {
13501351
maxRecentReports?: number;
13511352
includeP2P?: boolean;
@@ -1429,9 +1430,19 @@ function createFilteredOptionList(
14291430
? Object.values(personalDetails ?? {}).map((personalDetail) => {
14301431
const accountID = personalDetail?.accountID ?? CONST.DEFAULT_NUMBER_ID;
14311432

1433+
const report = reportMapForAccountIDs[accountID];
1434+
const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`];
14321435
return {
14331436
item: personalDetail,
1434-
...createOption([accountID], personalDetails, reportMapForAccountIDs[accountID], currentUserAccountID, {showPersonalDetails: true}, reportAttributesDerived),
1437+
...createOption(
1438+
[accountID],
1439+
personalDetails,
1440+
reportMapForAccountIDs[accountID],
1441+
currentUserAccountID,
1442+
{showPersonalDetails: true},
1443+
reportAttributesDerived,
1444+
privateIsArchived,
1445+
),
14351446
};
14361447
})
14371448
: [];
@@ -1446,14 +1457,15 @@ function createOptionFromReport(
14461457
report: Report,
14471458
personalDetails: OnyxEntry<PersonalDetailsList>,
14481459
currentUserAccountID: number,
1460+
privateIsArchived: string | undefined,
14491461
reportAttributesDerived?: ReportAttributesDerivedValue['reports'],
14501462
config?: PreviewConfig,
14511463
) {
14521464
const accountIDs = getParticipantsAccountIDsForDisplay(report);
14531465

14541466
return {
14551467
item: report,
1456-
...createOption(accountIDs, personalDetails, report, currentUserAccountID, config, reportAttributesDerived),
1468+
...createOption(accountIDs, personalDetails, report, currentUserAccountID, config, reportAttributesDerived, privateIsArchived),
14571469
};
14581470
}
14591471

tests/unit/OptionListContextProviderTest.tsx

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ import React from 'react';
33
import {usePersonalDetails} from '@components/OnyxListItemProvider';
44
import OptionListContextProvider, {useOptionsList} from '@components/OptionListContextProvider';
55
import useOnyx from '@hooks/useOnyx';
6-
import {createOptionList} from '@libs/OptionsListUtils';
6+
import usePrivateIsArchivedMap from '@hooks/usePrivateIsArchivedMap';
7+
import type {OptionList, SearchOption} from '@libs/OptionsListUtils';
8+
import {createOptionFromReport, createOptionList} from '@libs/OptionsListUtils';
79
import ONYXKEYS from '@src/ONYXKEYS';
10+
import type {Report} from '@src/types/onyx';
811

912
jest.mock('@libs/OptionsListUtils', () => {
1013
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
@@ -19,13 +22,16 @@ jest.mock('@libs/OptionsListUtils', () => {
1922
});
2023

2124
jest.mock('@hooks/useOnyx', () => jest.fn());
25+
jest.mock('@hooks/usePrivateIsArchivedMap', () => jest.fn());
2226
jest.mock('@components/OnyxListItemProvider', () => ({
2327
usePersonalDetails: jest.fn(),
2428
}));
2529

2630
const mockCreateOptionList = createOptionList as jest.MockedFunction<typeof createOptionList>;
31+
const mockCreateOptionFromReport = createOptionFromReport as jest.MockedFunction<typeof createOptionFromReport>;
2732
const mockUseOnyx = useOnyx as jest.MockedFunction<typeof useOnyx>;
2833
const mockUsePersonalDetails = usePersonalDetails as jest.MockedFunction<typeof usePersonalDetails>;
34+
const mockUsePrivateIsArchivedMap = usePrivateIsArchivedMap as jest.MockedFunction<typeof usePrivateIsArchivedMap>;
2935

3036
const wrapper: React.FC<{children: React.ReactNode}> = ({children}) => <OptionListContextProvider>{children}</OptionListContextProvider>;
3137

@@ -49,6 +55,7 @@ describe('OptionListContextProvider', () => {
4955

5056
mockCreateOptionList.mockReturnValue({reports: [], personalDetails: []});
5157
mockUsePersonalDetails.mockReturnValue({});
58+
mockUsePrivateIsArchivedMap.mockReturnValue({});
5259

5360
mockUseOnyx.mockImplementation(((key: string) => {
5461
if (key === ONYXKEYS.DERIVED.REPORT_ATTRIBUTES) {
@@ -114,4 +121,54 @@ describe('OptionListContextProvider', () => {
114121

115122
expect(mockCreateOptionList).toHaveBeenCalledTimes(1);
116123
});
124+
125+
it('passes privateIsArchived to createOptionFromReport when personal details change', () => {
126+
const reportID = '1';
127+
const accountID = '12345';
128+
const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${reportID}`;
129+
const report = {
130+
reportID,
131+
participants: {[accountID]: {notificationPreference: 'always'}},
132+
};
133+
134+
const archivedKey = `${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportID}`;
135+
mockUsePrivateIsArchivedMap.mockReturnValue({[archivedKey]: 'true'});
136+
137+
const initialPersonalDetails = {[accountID]: {accountID: Number(accountID), firstName: 'John', lastName: 'Doe', login: 'john@test.com', displayName: 'John Doe'}};
138+
mockUsePersonalDetails.mockReturnValue(initialPersonalDetails);
139+
140+
onyxState = {
141+
...onyxState,
142+
[ONYXKEYS.COLLECTION.REPORT]: {[reportKey]: report},
143+
};
144+
onyxSourceValues = {
145+
...onyxSourceValues,
146+
[ONYXKEYS.COLLECTION.REPORT]: {[reportKey]: report},
147+
};
148+
149+
const mockReportOption = {reportID, item: report, text: 'John Doe', keyForList: reportID} as unknown as SearchOption<Report>;
150+
mockCreateOptionList.mockReturnValue({
151+
reports: [mockReportOption],
152+
personalDetails: [],
153+
} as OptionList);
154+
mockCreateOptionFromReport.mockReturnValue(mockReportOption);
155+
156+
const {result, rerender} = renderHook(({shouldInitialize}) => useOptionsList({shouldInitialize}), {
157+
initialProps: {shouldInitialize: false},
158+
wrapper,
159+
});
160+
161+
act(() => {
162+
result.current.initializeOptions();
163+
});
164+
165+
mockCreateOptionFromReport.mockClear();
166+
167+
// Change personal details to trigger the update effect
168+
const updatedPersonalDetails = {[accountID]: {accountID: Number(accountID), firstName: 'Jane', lastName: 'Doe', login: 'john@test.com', displayName: 'Jane Doe'}};
169+
mockUsePersonalDetails.mockReturnValue(updatedPersonalDetails);
170+
rerender({shouldInitialize: false});
171+
172+
expect(mockCreateOptionFromReport).toHaveBeenCalledWith(report, updatedPersonalDetails, expect.any(Number), 'true', undefined, {showPersonalDetails: true});
173+
});
117174
});

0 commit comments

Comments
 (0)