Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/components/Search/SearchContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const defaultSearchInfo: SearchResultsInfo = {

const defaultSearchContextData: SearchContextData = {
currentSearchHash: -1,
currentRecentSearchHash: -1,
currentSearchKey: undefined,
currentSearchQueryJSON: undefined,
currentSearchResults: undefined,
Expand Down Expand Up @@ -81,10 +82,10 @@ function SearchContextProvider({children}: ChildrenProps) {
const todoSearchResultsData = useTodos();

const currentSearchKey = searchContextData.currentSearchKey;
const currentSearchHash = searchContextData.currentSearchHash;
const currentRecentSearchHash = searchContextData.currentRecentSearchHash;
const {accountID} = useCurrentUserPersonalDetails();
const suggestedSearches = useMemo(() => getSuggestedSearches(accountID), [accountID]);
const shouldUseLiveData = !!currentSearchKey && isTodoSearch(currentSearchHash, suggestedSearches);
const shouldUseLiveData = !!currentSearchKey && isTodoSearch(currentRecentSearchHash, suggestedSearches);

// If viewing a to-do search, use live data from useTodos, otherwise return the snapshot data
// We do this so that we can show the counters for the to-do search results without visiting the specific to-do page, e.g. show `Approve [3]` while viewing the `Submit` to-do search.
Expand All @@ -109,15 +110,16 @@ function SearchContextProvider({children}: ChildrenProps) {
return snapshotSearchResults ?? undefined;
}, [shouldUseLiveData, currentSearchKey, todoSearchResultsData, snapshotSearchResults]);

const setCurrentSearchHashAndKey = useCallback((searchHash: number, searchKey: SearchKey | undefined) => {
const setCurrentSearchHashAndKey = useCallback((searchHash: number, recentHash: number, searchKey: SearchKey | undefined) => {
setSearchContextData((prevState) => {
if (searchHash === prevState.currentSearchHash && searchKey === prevState.currentSearchKey) {
if (searchHash === prevState.currentSearchHash && recentHash === prevState.currentRecentSearchHash && searchKey === prevState.currentSearchKey) {
return prevState;
}

return {
...prevState,
currentSearchHash: searchHash,
currentRecentSearchHash: recentHash,
currentSearchKey: searchKey,
};
});
Expand Down
8 changes: 4 additions & 4 deletions src/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ function Search({
searchRequestResponseStatusCode,
onDEWModalOpen,
}: SearchProps) {
const {type, status, sortBy, sortOrder, hash, similarSearchHash, groupBy, view} = queryJSON;
const {type, status, sortBy, sortOrder, hash, recentSearchHash, similarSearchHash, groupBy, view} = queryJSON;

const {isOffline} = useNetwork();
const prevIsOffline = usePrevious(isOffline);
Expand Down Expand Up @@ -276,7 +276,7 @@ function Search({

const {defaultCardFeed} = useCardFeedsForDisplay();
const suggestedSearches = useMemo(() => getSuggestedSearches(accountID, defaultCardFeed?.id), [defaultCardFeed?.id, accountID]);
const searchKey = useMemo(() => Object.values(suggestedSearches).find((search) => search.similarSearchHash === similarSearchHash)?.key, [suggestedSearches, similarSearchHash]);
const searchKey = useMemo(() => Object.values(suggestedSearches).find((search) => search.recentSearchHash === recentSearchHash)?.key, [suggestedSearches, recentSearchHash]);
const searchDataType = useMemo(() => (shouldUseLiveData ? CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT : searchResults?.search?.type), [shouldUseLiveData, searchResults?.search?.type]);
const shouldCalculateTotals = useSearchShouldCalculateTotals(searchKey, hash, offset === 0);

Expand Down Expand Up @@ -307,9 +307,9 @@ function Search({

const clearTransactionsAndSetHashAndKey = useCallback(() => {
clearSelectedTransactions(hash);
setCurrentSearchHashAndKey(hash, searchKey);
setCurrentSearchHashAndKey(hash, recentSearchHash, searchKey);
setCurrentSearchQueryJSON(queryJSON);
}, [hash, searchKey, clearSelectedTransactions, setCurrentSearchHashAndKey, setCurrentSearchQueryJSON, queryJSON]);
}, [hash, recentSearchHash, searchKey, clearSelectedTransactions, setCurrentSearchHashAndKey, setCurrentSearchQueryJSON, queryJSON]);

useFocusEffect(clearTransactionsAndSetHashAndKey);

Expand Down
3 changes: 2 additions & 1 deletion src/components/Search/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ type SearchCustomColumnIds =

type SearchContextData = {
currentSearchHash: number;
currentRecentSearchHash: number;
currentSearchKey: SearchKey | undefined;
currentSearchQueryJSON: SearchQueryJSON | undefined;
currentSearchResults: SearchResults | undefined;
Expand All @@ -168,7 +169,7 @@ type SearchContextProps = SearchContextData & {
currentSearchResults: SearchResults | undefined;
/** Whether we're on a main to-do search and should use live Onyx data instead of snapshots */
shouldUseLiveData: boolean;
setCurrentSearchHashAndKey: (hash: number, key: SearchKey | undefined) => void;
setCurrentSearchHashAndKey: (hash: number, recentHash: number, key: SearchKey | undefined) => void;
setCurrentSearchQueryJSON: (searchQueryJSON: SearchQueryJSON | undefined) => void;
/** If you want to set `selectedTransactionIDs`, pass an array as the first argument, object/record otherwise */
setSelectedTransactions: {
Expand Down
47 changes: 45 additions & 2 deletions src/libs/SearchUIUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ type SearchTypeMenuItem = {
searchQueryJSON: SearchQueryJSON | undefined;
hash: number;
similarSearchHash: number;
recentSearchHash: number;
badgeText?: string;
emptyState?: {
title: TranslationPaths;
Expand Down Expand Up @@ -528,6 +529,9 @@ function createTopSearchMenuItem(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
};
}

Expand Down Expand Up @@ -566,6 +570,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.REPORTS]: {
key: CONST.SEARCH.SEARCH_KEYS.REPORTS,
Expand All @@ -582,6 +589,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.CHATS]: {
key: CONST.SEARCH.SEARCH_KEYS.CHATS,
Expand All @@ -598,6 +608,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.SUBMIT]: {
key: CONST.SEARCH.SEARCH_KEYS.SUBMIT,
Expand All @@ -618,6 +631,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.APPROVE]: {
key: CONST.SEARCH.SEARCH_KEYS.APPROVE,
Expand All @@ -638,6 +654,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.PAY]: {
key: CONST.SEARCH.SEARCH_KEYS.PAY,
Expand All @@ -659,6 +678,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.EXPORT]: {
key: CONST.SEARCH.SEARCH_KEYS.EXPORT,
Expand All @@ -680,6 +702,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.STATEMENTS]: {
key: CONST.SEARCH.SEARCH_KEYS.STATEMENTS,
Expand All @@ -701,6 +726,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.UNAPPROVED_CASH]: {
key: CONST.SEARCH.SEARCH_KEYS.UNAPPROVED_CASH,
Expand All @@ -722,6 +750,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.UNAPPROVED_CARD]: {
key: CONST.SEARCH.SEARCH_KEYS.UNAPPROVED_CARD,
Expand All @@ -743,6 +774,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.RECONCILIATION]: {
key: CONST.SEARCH.SEARCH_KEYS.RECONCILIATION,
Expand All @@ -764,6 +798,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.TOP_SPENDERS]: {
key: CONST.SEARCH.SEARCH_KEYS.TOP_SPENDERS,
Expand Down Expand Up @@ -797,6 +834,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
[CONST.SEARCH.SEARCH_KEYS.TOP_CATEGORIES]: createTopSearchMenuItem(
CONST.SEARCH.SEARCH_KEYS.TOP_CATEGORIES,
Expand Down Expand Up @@ -839,6 +879,9 @@ function getSuggestedSearches(
get similarSearchHash() {
return this.searchQueryJSON?.similarSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
get recentSearchHash() {
return this.searchQueryJSON?.recentSearchHash ?? CONST.DEFAULT_NUMBER_ID;
},
},
};
}
Expand Down Expand Up @@ -3411,9 +3454,9 @@ function isCorrectSearchUserName(displayName?: string) {
return displayName && displayName.toUpperCase() !== CONST.REPORT.OWNER_EMAIL_FAKE;
}

function isTodoSearch(hash: number, suggestedSearches: Record<string, SearchTypeMenuItem>) {
function isTodoSearch(recentSearchHash: number, suggestedSearches: Record<string, SearchTypeMenuItem>) {
const TODO_KEYS: SearchKey[] = [CONST.SEARCH.SEARCH_KEYS.SUBMIT, CONST.SEARCH.SEARCH_KEYS.APPROVE, CONST.SEARCH.SEARCH_KEYS.PAY, CONST.SEARCH.SEARCH_KEYS.EXPORT];
const matchedSearchKey = Object.values(suggestedSearches).find((search) => search.hash === hash)?.key;
const matchedSearchKey = Object.values(suggestedSearches).find((search) => search.recentSearchHash === recentSearchHash)?.key;
return !!matchedSearchKey && TODO_KEYS.includes(matchedSearchKey);
}

Expand Down
1 change: 1 addition & 0 deletions tests/ui/CategoryListItemHeaderTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const mockedUseResponsiveLayout = useResponsiveLayout as jest.MockedFunction<typ
// Mock search context with all required SearchContextProps fields
const mockSearchContext = {
currentSearchHash: 12345,
currentRecentSearchHash: 12345,
currentSearchKey: undefined,
currentSearchQueryJSON: undefined,
currentSearchResults: undefined,
Expand Down
1 change: 1 addition & 0 deletions tests/ui/MerchantListItemHeaderTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const mockedUseResponsiveLayout = useResponsiveLayout as jest.MockedFunction<typ
// Mock search context with all required SearchContextProps fields
const mockSearchContext = {
currentSearchHash: 12345,
currentRecentSearchHash: 12345,
currentSearchKey: undefined,
currentSearchQueryJSON: undefined,
currentSearchResults: undefined,
Expand Down
1 change: 1 addition & 0 deletions tests/ui/MonthListItemHeaderTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const mockedUseResponsiveLayout = useResponsiveLayout as jest.MockedFunction<typ
// Mock search context with all required SearchContextProps fields
const mockSearchContext = {
currentSearchHash: 12345,
currentRecentSearchHash: 12345,
currentSearchKey: undefined,
currentSearchQueryJSON: undefined,
currentSearchResults: undefined,
Expand Down
1 change: 1 addition & 0 deletions tests/ui/ReportListItemHeaderTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jest.mock('@components/AvatarWithDisplayName.tsx');
// Mock search context
const mockSearchContext = {
currentSearchHash: 12345,
currentRecentSearchHash: 12345,
selectedReports: {},
selectedTransactionIDs: [],
selectedTransactions: {},
Expand Down
1 change: 1 addition & 0 deletions tests/ui/WeekListItemHeaderTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const mockedUseResponsiveLayout = useResponsiveLayout as jest.MockedFunction<typ
// Mock search context with all required SearchContextProps fields
const mockSearchContext = {
currentSearchHash: 12345,
currentRecentSearchHash: 12345,
currentSearchKey: undefined,
currentSearchQueryJSON: undefined,
currentSearchResults: undefined,
Expand Down
1 change: 1 addition & 0 deletions tests/ui/YearListItemHeaderTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const mockedUseResponsiveLayout = useResponsiveLayout as jest.MockedFunction<typ
// Mock search context with all required SearchContextProps fields
const mockSearchContext = {
currentSearchHash: 12345,
currentRecentSearchHash: 12345,
currentSearchKey: undefined,
currentSearchQueryJSON: undefined,
currentSearchResults: undefined,
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/hooks/useSuggestedSearchDefaultNavigationTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function createApproveMenuItem(): SearchTypeMenuItem {
searchQueryJSON: undefined,
hash: 1,
similarSearchHash: 101,
recentSearchHash: 1001,
};
}

Expand All @@ -41,6 +42,7 @@ function createSubmitMenuItem(): SearchTypeMenuItem {
searchQueryJSON: undefined,
hash: 2,
similarSearchHash: 202,
recentSearchHash: 2002,
};
}

Expand All @@ -56,6 +58,7 @@ function createExpenseMenuItem(): SearchTypeMenuItem {
searchQueryJSON: undefined,
hash: 3,
similarSearchHash: 303,
recentSearchHash: 3003,
};
}

Expand All @@ -71,6 +74,7 @@ function createExpenseReportMenuItem(): SearchTypeMenuItem {
searchQueryJSON: undefined,
hash: 4,
similarSearchHash: 404,
recentSearchHash: 4004,
};
}

Expand All @@ -86,6 +90,7 @@ function createChatMenuItem(): SearchTypeMenuItem {
searchQueryJSON: undefined,
hash: 5,
similarSearchHash: 505,
recentSearchHash: 5005,
};
}

Expand Down
Loading