diff --git a/src/components/Search/SearchContext.tsx b/src/components/Search/SearchContext.tsx
index 30825ed3bfba..f3206868d556 100644
--- a/src/components/Search/SearchContext.tsx
+++ b/src/components/Search/SearchContext.tsx
@@ -1,6 +1,6 @@
import React, {useCallback, useContext, useMemo, useState} from 'react';
import type {ReportActionListItemType, ReportListItemType, TransactionListItemType} from '@components/SelectionList/types';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchUIUtils from '@libs/SearchUIUtils';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import type {SearchContext, SelectedTransactions} from './types';
@@ -23,8 +23,8 @@ function getReportsFromSelectedTransactions(data: TransactionListItemType[] | Re
return (data ?? [])
.filter(
(item) =>
- !SearchUtils.isTransactionListItemType(item) &&
- !SearchUtils.isReportActionListItemType(item) &&
+ !SearchUIUtils.isTransactionListItemType(item) &&
+ !SearchUIUtils.isReportActionListItemType(item) &&
item.reportID &&
item?.transactions?.every((transaction: {keyForList: string | number}) => selectedTransactions[transaction.keyForList]?.isSelected),
)
diff --git a/src/components/Search/SearchPageHeader.tsx b/src/components/Search/SearchPageHeader.tsx
index 4c383021645f..51f6c68c11ae 100644
--- a/src/components/Search/SearchPageHeader.tsx
+++ b/src/components/Search/SearchPageHeader.tsx
@@ -23,7 +23,7 @@ import * as SearchActions from '@libs/actions/Search';
import Log from '@libs/Log';
import Navigation from '@libs/Navigation/Navigation';
import {getAllTaxRates} from '@libs/PolicyUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import SearchSelectedNarrow from '@pages/Search/SearchSelectedNarrow';
import variables from '@styles/variables';
import CONST from '@src/CONST';
@@ -136,8 +136,8 @@ function SearchPageHeader({queryJSON, hash}: SearchPageHeaderProps) {
const [isDownloadErrorModalVisible, setIsDownloadErrorModalVisible] = useState(false);
const {status, type} = queryJSON;
- const isCannedQuery = SearchUtils.isCannedSearchQuery(queryJSON);
- const headerText = isCannedQuery ? translate(getHeaderContent(type).titleText) : SearchUtils.getSearchHeaderTitle(queryJSON, personalDetails, cardList, reports, taxRates);
+ const isCannedQuery = SearchQueryUtils.isCannedSearchQuery(queryJSON);
+ const headerText = isCannedQuery ? translate(getHeaderContent(type).titleText) : SearchQueryUtils.getSearchHeaderTitle(queryJSON, personalDetails, cardList, reports, taxRates);
const [inputValue, setInputValue] = useState(headerText);
useEffect(() => {
@@ -327,7 +327,7 @@ function SearchPageHeader({queryJSON, hash}: SearchPageHeaderProps) {
}
const onPress = () => {
- const filterFormValues = SearchUtils.buildFilterFormValuesFromQuery(queryJSON, policyCategories, policyTagsLists, currencyList, personalDetails, cardList, reports, taxRates);
+ const filterFormValues = SearchQueryUtils.buildFilterFormValuesFromQuery(queryJSON, policyCategories, policyTagsLists, currencyList, personalDetails, cardList, reports, taxRates);
SearchActions.updateAdvancedFilters(filterFormValues);
Navigation.navigate(ROUTES.SEARCH_ADVANCED_FILTERS);
@@ -337,10 +337,10 @@ function SearchPageHeader({queryJSON, hash}: SearchPageHeaderProps) {
if (!inputValue) {
return;
}
- const inputQueryJSON = SearchUtils.buildSearchQueryJSON(inputValue);
+ const inputQueryJSON = SearchQueryUtils.buildSearchQueryJSON(inputValue);
if (inputQueryJSON) {
- const standardizedQuery = SearchUtils.standardizeQueryJSON(inputQueryJSON, cardList, taxRates);
- const query = SearchUtils.buildSearchQueryString(standardizedQuery);
+ const standardizedQuery = SearchQueryUtils.standardizeQueryJSON(inputQueryJSON, cardList, taxRates);
+ const query = SearchQueryUtils.buildSearchQueryString(standardizedQuery);
SearchActions.clearAllFilters();
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query}));
} else {
diff --git a/src/components/Search/SearchRouter/SearchRouter.tsx b/src/components/Search/SearchRouter/SearchRouter.tsx
index 924cf366415a..43709e4f8a13 100644
--- a/src/components/Search/SearchRouter/SearchRouter.tsx
+++ b/src/components/Search/SearchRouter/SearchRouter.tsx
@@ -16,7 +16,7 @@ import Log from '@libs/Log';
import * as OptionsListUtils from '@libs/OptionsListUtils';
import {getAllTaxRates} from '@libs/PolicyUtils';
import type {OptionData} from '@libs/ReportUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import Navigation from '@navigation/Navigation';
import variables from '@styles/variables';
import * as Report from '@userActions/Report';
@@ -117,7 +117,7 @@ function SearchRouter() {
return;
}
listRef.current?.updateAndScrollToFocusedIndex(0);
- const queryJSON = SearchUtils.buildSearchQueryJSON(userQuery);
+ const queryJSON = SearchQueryUtils.buildSearchQueryJSON(userQuery);
if (queryJSON) {
setUserSearchQuery(queryJSON);
@@ -148,8 +148,8 @@ function SearchRouter() {
return;
}
closeSearchRouter();
- const standardizedQuery = SearchUtils.standardizeQueryJSON(query, cardList, taxRates);
- const queryString = SearchUtils.buildSearchQueryString(standardizedQuery);
+ const standardizedQuery = SearchQueryUtils.standardizeQueryJSON(query, cardList, taxRates);
+ const queryString = SearchQueryUtils.buildSearchQueryString(standardizedQuery);
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: queryString}));
clearUserQuery();
},
diff --git a/src/components/Search/SearchRouter/SearchRouterList.tsx b/src/components/Search/SearchRouter/SearchRouterList.tsx
index 20ade90843d7..89a59f23647b 100644
--- a/src/components/Search/SearchRouter/SearchRouterList.tsx
+++ b/src/components/Search/SearchRouter/SearchRouterList.tsx
@@ -15,7 +15,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import {getAllTaxRates} from '@libs/PolicyUtils';
import type {OptionData} from '@libs/ReportUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import * as Report from '@userActions/Report';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
@@ -113,7 +113,7 @@ function SearchRouterList(
{
text: `${translate('search.searchIn')} ${reportForContextualSearch.text ?? reportForContextualSearch.alternateText}`,
singleIcon: Expensicons.MagnifyingGlass,
- query: SearchUtils.getContextualSuggestionQuery(reportForContextualSearch.reportID),
+ query: SearchQueryUtils.getContextualSuggestionQuery(reportForContextualSearch.reportID),
itemStyle: styles.activeComponentBG,
keyForList: 'contextualSearch',
isContextualSearchItem: true,
@@ -123,9 +123,9 @@ function SearchRouterList(
}
const recentSearchesData = recentSearches?.map(({query}) => {
- const searchQueryJSON = SearchUtils.buildSearchQueryJSON(query);
+ const searchQueryJSON = SearchQueryUtils.buildSearchQueryJSON(query);
return {
- text: searchQueryJSON ? SearchUtils.getSearchHeaderTitle(searchQueryJSON, personalDetails, cardList, reports, taxRates) : query,
+ text: searchQueryJSON ? SearchQueryUtils.getSearchHeaderTitle(searchQueryJSON, personalDetails, cardList, reports, taxRates) : query,
singleIcon: Expensicons.History,
query,
keyForList: query,
@@ -152,7 +152,7 @@ function SearchRouterList(
if (!item?.query) {
return;
}
- onSearchSubmit(SearchUtils.buildSearchQueryJSON(item?.query));
+ onSearchSubmit(SearchQueryUtils.buildSearchQueryJSON(item?.query));
}
// Handle selection of "Recent chat"
diff --git a/src/components/Search/SearchStatusBar.tsx b/src/components/Search/SearchStatusBar.tsx
index afba2acc415c..07b57f8acab8 100644
--- a/src/components/Search/SearchStatusBar.tsx
+++ b/src/components/Search/SearchStatusBar.tsx
@@ -11,7 +11,7 @@ import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type {SearchDataTypes} from '@src/types/onyx/SearchResults';
@@ -177,7 +177,7 @@ function SearchStatusBar({queryJSON, onStatusChange}: SearchStatusBarProps) {
{options.map((item, index) => {
const onPress = singleExecution(() => {
onStatusChange?.();
- const query = SearchUtils.buildSearchQueryString({...queryJSON, status: item.status});
+ const query = SearchQueryUtils.buildSearchQueryString({...queryJSON, status: item.status});
Navigation.setParams({q: query});
});
const isActive = queryJSON.status === item.status;
diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx
index 670cfef54df8..a360d116a345 100644
--- a/src/components/Search/index.tsx
+++ b/src/components/Search/index.tsx
@@ -22,7 +22,8 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import Log from '@libs/Log';
import memoize from '@libs/memoize';
import * as ReportUtils from '@libs/ReportUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
+import * as SearchUIUtils from '@libs/SearchUIUtils';
import Navigation from '@navigation/Navigation';
import type {AuthScreensParamList} from '@navigation/types';
import EmptySearchView from '@pages/Search/EmptySearchView';
@@ -60,11 +61,11 @@ function mapToItemWithSelectionInfo(
canSelectMultiple: boolean,
shouldAnimateInHighlight: boolean,
) {
- if (SearchUtils.isReportActionListItemType(item)) {
+ if (SearchUIUtils.isReportActionListItemType(item)) {
return item;
}
- return SearchUtils.isTransactionListItemType(item)
+ return SearchUIUtils.isTransactionListItemType(item)
? mapToTransactionItemWithSelectionInfo(item, selectedTransactions, canSelectMultiple, shouldAnimateInHighlight)
: {
...item,
@@ -139,7 +140,7 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
const getItemHeight = useCallback(
(item: TransactionListItemType | ReportListItemType | ReportActionListItemType) => {
- if (SearchUtils.isTransactionListItemType(item) || SearchUtils.isReportActionListItemType(item)) {
+ if (SearchUIUtils.isTransactionListItemType(item) || SearchUIUtils.isReportActionListItemType(item)) {
return isLargeScreenWidth ? variables.optionRowHeight + listItemPadding : transactionItemMobileHeight + listItemPadding;
}
@@ -186,9 +187,9 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
const isDataLoaded = searchResults?.data !== undefined && searchResults?.search?.type === type && searchResults?.search?.status === status;
const shouldShowLoadingState = !isOffline && !isDataLoaded;
const shouldShowLoadingMoreItems = !shouldShowLoadingState && searchResults?.search?.isLoading && searchResults?.search?.offset > 0;
- const isSearchResultsEmpty = !searchResults?.data || SearchUtils.isSearchResultsEmpty(searchResults);
+ const isSearchResultsEmpty = !searchResults?.data || SearchUIUtils.isSearchResultsEmpty(searchResults);
const prevIsSearchResultEmpty = usePrevious(isSearchResultsEmpty);
- const data = searchResults === undefined ? [] : SearchUtils.getSections(type, status, searchResults.data, searchResults.search);
+ const data = searchResults === undefined ? [] : SearchUIUtils.getSections(type, status, searchResults.data, searchResults.search);
useEffect(() => {
/** We only want to display the skeleton for the status filters the first time we load them for a specific data type */
@@ -260,8 +261,8 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
return {null};
}
- const ListItem = SearchUtils.getListItem(type, status);
- const sortedData = SearchUtils.getSortedSections(type, status, data, sortBy, sortOrder);
+ const ListItem = SearchUIUtils.getListItem(type, status);
+ const sortedData = SearchUIUtils.getSortedSections(type, status, data, sortBy, sortOrder);
const sortedSelectedData = sortedData.map((item) => {
const baseKey = `${ONYXKEYS.COLLECTION.TRANSACTION}${(item as TransactionListItemType).transactionID}`;
// Check if the base key matches the newSearchResultKey (TransactionListItemType)
@@ -288,10 +289,10 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
}
const toggleTransaction = (item: TransactionListItemType | ReportListItemType | ReportActionListItemType) => {
- if (SearchUtils.isReportActionListItemType(item)) {
+ if (SearchUIUtils.isReportActionListItemType(item)) {
return;
}
- if (SearchUtils.isTransactionListItemType(item)) {
+ if (SearchUIUtils.isTransactionListItemType(item)) {
if (!item.keyForList) {
return;
}
@@ -322,21 +323,21 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
const openReport = (item: TransactionListItemType | ReportListItemType | ReportActionListItemType) => {
const isFromSelfDM = item.reportID === CONST.REPORT.UNREPORTED_REPORTID;
- let reportID = SearchUtils.isTransactionListItemType(item) && (!item.isFromOneTransactionReport || isFromSelfDM) ? item.transactionThreadReportID : item.reportID;
+ let reportID = SearchUIUtils.isTransactionListItemType(item) && (!item.isFromOneTransactionReport || isFromSelfDM) ? item.transactionThreadReportID : item.reportID;
if (!reportID) {
return;
}
// If we're trying to open a legacy transaction without a transaction thread, let's create the thread and navigate the user
- if (SearchUtils.isTransactionListItemType(item) && reportID === '0' && item.moneyRequestReportActionID) {
+ if (SearchUIUtils.isTransactionListItemType(item) && reportID === '0' && item.moneyRequestReportActionID) {
reportID = ReportUtils.generateReportID();
SearchActions.createTransactionThread(hash, item.transactionID, reportID, item.moneyRequestReportActionID);
}
const backTo = Navigation.getActiveRoute();
- if (SearchUtils.isReportActionListItemType(item)) {
+ if (SearchUIUtils.isReportActionListItemType(item)) {
const reportActionID = item.reportActionID;
Navigation.navigate(ROUTES.SEARCH_REPORT.getRoute({reportID, reportActionID, backTo}));
return;
@@ -372,11 +373,11 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
};
const onSortPress = (column: SearchColumnType, order: SortOrder) => {
- const newQuery = SearchUtils.buildSearchQueryString({...queryJSON, sortBy: column, sortOrder: order});
+ const newQuery = SearchQueryUtils.buildSearchQueryString({...queryJSON, sortBy: column, sortOrder: order});
navigation.setParams({q: newQuery});
};
- const shouldShowYear = SearchUtils.shouldShowYear(searchResults?.data);
+ const shouldShowYear = SearchUIUtils.shouldShowYear(searchResults?.data);
const shouldShowSorting = sortableSearchStatuses.includes(status);
return (
@@ -401,7 +402,7 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
)
}
isSelected={(item) =>
- status !== CONST.SEARCH.STATUS.EXPENSE.ALL && SearchUtils.isReportListItemType(item)
+ status !== CONST.SEARCH.STATUS.EXPENSE.ALL && SearchUIUtils.isReportListItemType(item)
? item.transactions.some((transaction) => selectedTransactions[transaction.keyForList]?.isSelected)
: !!item.isSelected
}
diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx
index 06bf8eb6434a..892be8eca96c 100644
--- a/src/components/SelectionList/BaseSelectionList.tsx
+++ b/src/components/SelectionList/BaseSelectionList.tsx
@@ -24,7 +24,7 @@ import useSingleExecution from '@hooks/useSingleExecution';
import useThemeStyles from '@hooks/useThemeStyles';
import getSectionsWithIndexOffset from '@libs/getSectionsWithIndexOffset';
import Log from '@libs/Log';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchUIUtils from '@libs/SearchUIUtils';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
@@ -437,7 +437,7 @@ function BaseSelectionList(
const showTooltip = shouldShowTooltips && normalizedIndex < 10;
const handleOnCheckboxPress = () => {
- if (SearchUtils.isReportListItemType(item)) {
+ if (SearchUIUtils.isReportListItemType(item)) {
return onCheckboxPress;
}
return onCheckboxPress ? () => onCheckboxPress(item) : undefined;
diff --git a/src/components/SelectionList/Search/ExpenseItemHeaderNarrow.tsx b/src/components/SelectionList/Search/ExpenseItemHeaderNarrow.tsx
index 424bbd50d7b2..5b643c148731 100644
--- a/src/components/SelectionList/Search/ExpenseItemHeaderNarrow.tsx
+++ b/src/components/SelectionList/Search/ExpenseItemHeaderNarrow.tsx
@@ -7,7 +7,7 @@ import {PressableWithFeedback} from '@components/Pressable';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchUIUtils from '@libs/SearchUIUtils';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import type {SearchPersonalDetails, SearchTransactionAction} from '@src/types/onyx/SearchResults';
@@ -50,7 +50,7 @@ function ExpenseItemHeaderNarrow({
const theme = useTheme();
// It might happen that we are missing display names for `From` or `To`, we only display arrow icon if both names exist
- const shouldDisplayArrowIcon = SearchUtils.isCorrectSearchUserName(participantFromDisplayName) && SearchUtils.isCorrectSearchUserName(participantToDisplayName);
+ const shouldDisplayArrowIcon = SearchUIUtils.isCorrectSearchUserName(participantFromDisplayName) && SearchUIUtils.isCorrectSearchUserName(participantToDisplayName);
return (
diff --git a/src/components/SelectionList/Search/ReportListItem.tsx b/src/components/SelectionList/Search/ReportListItem.tsx
index 147e1686be5b..7e283557819a 100644
--- a/src/components/SelectionList/Search/ReportListItem.tsx
+++ b/src/components/SelectionList/Search/ReportListItem.tsx
@@ -110,7 +110,7 @@ function ReportListItem({
const participantFrom = reportItem.from;
const participantTo = reportItem.to;
- // These values should come as part of the item via SearchUtils.getSections() but ReportListItem is not yet 100% handled
+ // These values should come as part of the item via SearchUIUtils.getSections() but ReportListItem is not yet 100% handled
// This will be simplified in future once sorting of ReportListItem is done
const participantFromDisplayName = participantFrom?.displayName ?? participantFrom?.login ?? '';
const participantToDisplayName = participantTo?.displayName ?? participantTo?.login ?? '';
diff --git a/src/components/SelectionList/Search/UserInfoCell.tsx b/src/components/SelectionList/Search/UserInfoCell.tsx
index 3a6c98178a3b..6a653471683a 100644
--- a/src/components/SelectionList/Search/UserInfoCell.tsx
+++ b/src/components/SelectionList/Search/UserInfoCell.tsx
@@ -4,7 +4,7 @@ import Avatar from '@components/Avatar';
import Text from '@components/Text';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchUIUtils from '@libs/SearchUIUtils';
import CONST from '@src/CONST';
import type {SearchPersonalDetails} from '@src/types/onyx/SearchResults';
@@ -18,7 +18,7 @@ function UserInfoCell({participant, displayName}: UserInfoCellProps) {
const {isLargeScreenWidth} = useResponsiveLayout();
const avatarURL = participant?.avatar;
- if (!SearchUtils.isCorrectSearchUserName(displayName)) {
+ if (!SearchUIUtils.isCorrectSearchUserName(displayName)) {
return null;
}
diff --git a/src/components/SelectionList/SearchTableHeader.tsx b/src/components/SelectionList/SearchTableHeader.tsx
index f54532a7f318..5cae23eb9ab5 100644
--- a/src/components/SelectionList/SearchTableHeader.tsx
+++ b/src/components/SelectionList/SearchTableHeader.tsx
@@ -5,7 +5,7 @@ import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchUIUtils from '@libs/SearchUIUtils';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type * as OnyxTypes from '@src/types/onyx';
@@ -39,12 +39,12 @@ const expenseHeaders: SearchColumnConfig[] = [
{
columnName: CONST.SEARCH.TABLE_COLUMNS.MERCHANT,
translationKey: 'common.merchant',
- shouldShow: (data: OnyxTypes.SearchResults['data']) => SearchUtils.getShouldShowMerchant(data),
+ shouldShow: (data: OnyxTypes.SearchResults['data']) => SearchUIUtils.getShouldShowMerchant(data),
},
{
columnName: CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION,
translationKey: 'common.description',
- shouldShow: (data: OnyxTypes.SearchResults['data']) => !SearchUtils.getShouldShowMerchant(data),
+ shouldShow: (data: OnyxTypes.SearchResults['data']) => !SearchUIUtils.getShouldShowMerchant(data),
},
{
columnName: CONST.SEARCH.TABLE_COLUMNS.FROM,
diff --git a/src/hooks/useDeleteSavedSearch.tsx b/src/hooks/useDeleteSavedSearch.tsx
index 668f9048e7fb..19e5def4601d 100644
--- a/src/hooks/useDeleteSavedSearch.tsx
+++ b/src/hooks/useDeleteSavedSearch.tsx
@@ -1,7 +1,7 @@
import React, {useState} from 'react';
import ConfirmModal from '@components/ConfirmModal';
import Navigation from '@libs/Navigation/Navigation';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import * as SearchActions from '@userActions/Search';
import ROUTES from '@src/ROUTES';
import useLocalize from './useLocalize';
@@ -22,7 +22,7 @@ export default function useDeleteSavedSearch() {
SearchActions.clearAdvancedFilters();
Navigation.navigate(
ROUTES.SEARCH_CENTRAL_PANE.getRoute({
- query: SearchUtils.buildCannedSearchQuery(),
+ query: SearchQueryUtils.buildCannedSearchQuery(),
}),
);
};
diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx
index f103504cbd86..40910014faa9 100644
--- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx
+++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx
@@ -28,7 +28,7 @@ import onyxSubscribe from '@libs/onyxSubscribe';
import * as Pusher from '@libs/Pusher/pusher';
import PusherConnectionManager from '@libs/PusherConnectionManager';
import * as ReportUtils from '@libs/ReportUtils';
-import {buildSearchQueryString} from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import * as SessionUtils from '@libs/SessionUtils';
import ConnectionCompletePage from '@pages/ConnectionCompletePage';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
@@ -93,7 +93,7 @@ const loadWorkspaceJoinUser = () => require('@pages/worksp
function getCentralPaneScreenInitialParams(screenName: CentralPaneName, initialReportID?: string): Partial> {
if (screenName === SCREENS.SEARCH.CENTRAL_PANE) {
// Generate default query string with buildSearchQueryString without argument.
- return {q: buildSearchQueryString()};
+ return {q: SearchQueryUtils.buildSearchQueryString()};
}
if (screenName === SCREENS.REPORT) {
diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx
index 16a3e5e098f6..0aa3a343b71d 100644
--- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx
+++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx
@@ -15,7 +15,7 @@ import interceptAnonymousUser from '@libs/interceptAnonymousUser';
import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList, RootStackParamList, State} from '@libs/Navigation/types';
import * as PolicyUtils from '@libs/PolicyUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import type {BrickRoad} from '@libs/WorkspacesSettingsUtils';
import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils';
import navigationRef from '@navigation/navigationRef';
@@ -42,7 +42,7 @@ type BottomTabBarProps = {
* Otherwise policyID will be inserted into query
*/
function handleQueryWithPolicyID(query: SearchQueryString, activePolicyID?: string): SearchQueryString {
- const queryJSON = SearchUtils.buildSearchQueryJSON(query);
+ const queryJSON = SearchQueryUtils.buildSearchQueryJSON(query);
if (!queryJSON) {
return query;
}
@@ -57,7 +57,7 @@ function handleQueryWithPolicyID(query: SearchQueryString, activePolicyID?: stri
queryJSON.policyID = policyID;
}
- return SearchUtils.buildSearchQueryString(queryJSON);
+ return SearchQueryUtils.buildSearchQueryString(queryJSON);
}
function BottomTabBar({selectedTab}: BottomTabBarProps) {
@@ -101,7 +101,7 @@ function BottomTabBar({selectedTab}: BottomTabBarProps) {
return;
}
- const defaultCannedQuery = SearchUtils.buildCannedSearchQuery();
+ const defaultCannedQuery = SearchQueryUtils.buildCannedSearchQuery();
// when navigating to search we might have an activePolicyID set from workspace switcher
const query = activeWorkspaceID ? `${defaultCannedQuery} ${CONST.SEARCH.SYNTAX_ROOT_KEYS.POLICY_ID}:${activeWorkspaceID}` : defaultCannedQuery;
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query}));
diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx
index 4684eb9637be..3b4879839ae0 100644
--- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx
+++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx
@@ -15,7 +15,7 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import Performance from '@libs/Performance';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import SignInButton from '@pages/home/sidebar/SignInButton';
import * as Session from '@userActions/Session';
import Timing from '@userActions/Timing';
@@ -68,7 +68,7 @@ function TopBar({breadcrumbLabel, activeWorkspaceID, shouldDisplaySearch = true,
accessibilityLabel={translate('common.cancel')}
style={[styles.textBlue]}
onPress={() => {
- Navigation.goBack(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: SearchUtils.buildCannedSearchQuery()}));
+ Navigation.goBack(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: SearchQueryUtils.buildCannedSearchQuery()}));
}}
>
{translate('common.cancel')}
diff --git a/src/libs/Navigation/AppNavigator/createCustomPlatformStackBottomTabNavigator/BottomTabBar.tsx b/src/libs/Navigation/AppNavigator/createCustomPlatformStackBottomTabNavigator/BottomTabBar.tsx
index cbcfa4b84677..3bf029012b36 100644
--- a/src/libs/Navigation/AppNavigator/createCustomPlatformStackBottomTabNavigator/BottomTabBar.tsx
+++ b/src/libs/Navigation/AppNavigator/createCustomPlatformStackBottomTabNavigator/BottomTabBar.tsx
@@ -17,7 +17,7 @@ import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
import {isCentralPaneName} from '@libs/NavigationUtils';
import * as PolicyUtils from '@libs/PolicyUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import type {BrickRoad} from '@libs/WorkspacesSettingsUtils';
import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils';
import navigationRef from '@navigation/navigationRef';
@@ -47,7 +47,7 @@ type BottomTabBarProps = {
* Otherwise policyID will be inserted into query
*/
function handleQueryWithPolicyID(query: SearchQueryString, activePolicyID?: string): SearchQueryString {
- const queryJSON = SearchUtils.buildSearchQueryJSON(query);
+ const queryJSON = SearchQueryUtils.buildSearchQueryJSON(query);
if (!queryJSON) {
return query;
}
@@ -62,7 +62,7 @@ function handleQueryWithPolicyID(query: SearchQueryString, activePolicyID?: stri
queryJSON.policyID = policyID;
}
- return SearchUtils.buildSearchQueryString(queryJSON);
+ return SearchQueryUtils.buildSearchQueryString(queryJSON);
}
function BottomTabBar({selectedTab}: BottomTabBarProps) {
@@ -130,7 +130,7 @@ function BottomTabBar({selectedTab}: BottomTabBarProps) {
return;
}
- const defaultCannedQuery = SearchUtils.buildCannedSearchQuery();
+ const defaultCannedQuery = SearchQueryUtils.buildCannedSearchQuery();
// when navigating to search we might have an activePolicyID set from workspace switcher
const query = activeWorkspaceID ? `${defaultCannedQuery} ${CONST.SEARCH.SYNTAX_ROOT_KEYS.POLICY_ID}:${activeWorkspaceID}` : defaultCannedQuery;
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query}));
diff --git a/src/libs/Navigation/AppNavigator/createCustomPlatformStackBottomTabNavigator/TopBar.tsx b/src/libs/Navigation/AppNavigator/createCustomPlatformStackBottomTabNavigator/TopBar.tsx
index 4684eb9637be..3b4879839ae0 100644
--- a/src/libs/Navigation/AppNavigator/createCustomPlatformStackBottomTabNavigator/TopBar.tsx
+++ b/src/libs/Navigation/AppNavigator/createCustomPlatformStackBottomTabNavigator/TopBar.tsx
@@ -15,7 +15,7 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import Performance from '@libs/Performance';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import SignInButton from '@pages/home/sidebar/SignInButton';
import * as Session from '@userActions/Session';
import Timing from '@userActions/Timing';
@@ -68,7 +68,7 @@ function TopBar({breadcrumbLabel, activeWorkspaceID, shouldDisplaySearch = true,
accessibilityLabel={translate('common.cancel')}
style={[styles.textBlue]}
onPress={() => {
- Navigation.goBack(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: SearchUtils.buildCannedSearchQuery()}));
+ Navigation.goBack(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: SearchQueryUtils.buildCannedSearchQuery()}));
}}
>
{translate('common.cancel')}
diff --git a/src/libs/Navigation/extractPolicyIDFromQuery.ts b/src/libs/Navigation/extractPolicyIDFromQuery.ts
index bd0464f4aab6..f091690c16f2 100644
--- a/src/libs/Navigation/extractPolicyIDFromQuery.ts
+++ b/src/libs/Navigation/extractPolicyIDFromQuery.ts
@@ -1,4 +1,4 @@
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import type {NavigationPartialRoute} from './types';
function extractPolicyIDFromQuery(route?: NavigationPartialRoute) {
@@ -11,12 +11,12 @@ function extractPolicyIDFromQuery(route?: NavigationPartialRoute) {
}
const queryString = route.params.q as string;
- const queryJSON = SearchUtils.buildSearchQueryJSON(queryString);
+ const queryJSON = SearchQueryUtils.buildSearchQueryJSON(queryString);
if (!queryJSON) {
return undefined;
}
- return SearchUtils.getPolicyIDFromSearchQuery(queryJSON);
+ return SearchQueryUtils.getPolicyIDFromSearchQuery(queryJSON);
}
export default extractPolicyIDFromQuery;
diff --git a/src/libs/Navigation/switchPolicyID.ts b/src/libs/Navigation/switchPolicyID.ts
index 5ccc2da54418..16e705258e58 100644
--- a/src/libs/Navigation/switchPolicyID.ts
+++ b/src/libs/Navigation/switchPolicyID.ts
@@ -4,7 +4,7 @@ import {getPathFromState} from '@react-navigation/native';
import type {Writable} from 'type-fest';
import getIsNarrowLayout from '@libs/getIsNarrowLayout';
import {isCentralPaneName} from '@libs/NavigationUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import CONST from '@src/CONST';
import type {Route} from '@src/ROUTES';
import ROUTES from '@src/ROUTES';
@@ -83,7 +83,7 @@ export default function switchPolicyID(navigation: NavigationContainerRef>;
const action: StackNavigationAction = getActionFromState(stateFromPath, linkingConfig.config);
@@ -110,16 +110,16 @@ export default function switchPolicyID(navigation: NavigationContainerRef {
- const isExpenseReport = transactionItem.reportType === CONST.REPORT.TYPE.EXPENSE;
-
- const formattedFrom = from?.displayName ?? from?.login ?? '';
- const formattedTo = to?.displayName ?? to?.login ?? '';
- const formattedTotal = TransactionUtils.getAmount(transactionItem, isExpenseReport);
- const date = transactionItem?.modifiedCreated ? transactionItem.modifiedCreated : transactionItem?.created;
- const merchant = TransactionUtils.getMerchant(transactionItem);
- const formattedMerchant = merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || merchant === CONST.TRANSACTION.DEFAULT_MERCHANT ? '' : merchant;
-
- return {
- formattedFrom,
- formattedTo,
- date,
- formattedTotal,
- formattedMerchant,
- };
-}
-
-type ReportKey = `${typeof ONYXKEYS.COLLECTION.REPORT}${string}`;
-
-type TransactionKey = `${typeof ONYXKEYS.COLLECTION.TRANSACTION}${string}`;
-
-type ReportActionKey = `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS}${string}`;
-
-function isReportEntry(key: string): key is ReportKey {
- return key.startsWith(ONYXKEYS.COLLECTION.REPORT);
-}
-
-function isTransactionEntry(key: string): key is TransactionKey {
- return key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION);
-}
-
-function isReportActionEntry(key: string): key is ReportActionKey {
- return key.startsWith(ONYXKEYS.COLLECTION.REPORT_ACTIONS);
-}
-
-function getShouldShowMerchant(data: OnyxTypes.SearchResults['data']): boolean {
- return Object.keys(data).some((key) => {
- if (isTransactionEntry(key)) {
- const item = data[key];
- const merchant = item.modifiedMerchant ? item.modifiedMerchant : item.merchant ?? '';
- return merchant !== '' && merchant !== CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT && merchant !== CONST.TRANSACTION.DEFAULT_MERCHANT;
- }
- return false;
- });
-}
-
-const currentYear = new Date().getFullYear();
-
-function isReportListItemType(item: ListItem): item is ReportListItemType {
- return 'transactions' in item;
-}
-
-function isTransactionListItemType(item: TransactionListItemType | ReportListItemType | ReportActionListItemType): item is TransactionListItemType {
- const transactionListItem = item as TransactionListItemType;
- return transactionListItem.transactionID !== undefined;
-}
-
-function isReportActionListItemType(item: TransactionListItemType | ReportListItemType | ReportActionListItemType): item is ReportActionListItemType {
- const reportActionListItem = item as ReportActionListItemType;
- return reportActionListItem.reportActionID !== undefined;
-}
-
-function shouldShowYear(data: TransactionListItemType[] | ReportListItemType[] | OnyxTypes.SearchResults['data']): boolean {
- if (Array.isArray(data)) {
- return data.some((item: TransactionListItemType | ReportListItemType) => {
- if (isReportListItemType(item)) {
- // If the item is a ReportListItemType, iterate over its transactions and check them
- return item.transactions.some((transaction) => {
- const transactionYear = new Date(TransactionUtils.getCreated(transaction)).getFullYear();
- return transactionYear !== currentYear;
- });
- }
-
- const createdYear = new Date(item?.modifiedCreated ? item.modifiedCreated : item?.created || '').getFullYear();
- return createdYear !== currentYear;
- });
- }
-
- for (const key in data) {
- if (isTransactionEntry(key)) {
- const item = data[key];
- const date = TransactionUtils.getCreated(item);
-
- if (DateUtils.doesDateBelongToAPastYear(date)) {
- return true;
- }
- } else if (isReportActionEntry(key)) {
- const item = data[key];
- for (const action of Object.values(item)) {
- const date = action.created;
-
- if (DateUtils.doesDateBelongToAPastYear(date)) {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-function getTransactionsSections(data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search']): TransactionListItemType[] {
- const shouldShowMerchant = getShouldShowMerchant(data);
-
- const doesDataContainAPastYearTransaction = shouldShowYear(data);
-
- return Object.keys(data)
- .filter(isTransactionEntry)
- .map((key) => {
- const transactionItem = data[key];
- const from = data.personalDetailsList?.[transactionItem.accountID];
- const to = transactionItem.managerID ? data.personalDetailsList?.[transactionItem.managerID] : emptyPersonalDetails;
-
- const {formattedFrom, formattedTo, formattedTotal, formattedMerchant, date} = getTransactionItemCommonFormattedProperties(transactionItem, from, to);
-
- return {
- ...transactionItem,
- from,
- to,
- formattedFrom,
- formattedTo,
- formattedTotal,
- formattedMerchant,
- date,
- shouldShowMerchant,
- shouldShowCategory: metadata?.columnsToShow?.shouldShowCategoryColumn,
- shouldShowTag: metadata?.columnsToShow?.shouldShowTagColumn,
- shouldShowTax: metadata?.columnsToShow?.shouldShowTaxColumn,
- keyForList: transactionItem.transactionID,
- shouldShowYear: doesDataContainAPastYearTransaction,
- };
- });
-}
-
-function getReportActionsSections(data: OnyxTypes.SearchResults['data']): ReportActionListItemType[] {
- const reportActionItems: ReportActionListItemType[] = [];
- for (const key in data) {
- if (isReportActionEntry(key)) {
- const reportActions = data[key];
- for (const reportAction of Object.values(reportActions)) {
- const from = data.personalDetailsList?.[reportAction.accountID];
- if (ReportActionsUtils.isDeletedAction(reportAction)) {
- // eslint-disable-next-line no-continue
- continue;
- }
- reportActionItems.push({
- ...reportAction,
- from,
- formattedFrom: from?.displayName ?? from?.login ?? '',
- date: reportAction.created,
- keyForList: reportAction.reportActionID,
- });
- }
- }
- }
- return reportActionItems;
-}
-
-function getIOUReportName(data: OnyxTypes.SearchResults['data'], reportItem: SearchReport) {
- const payerPersonalDetails = reportItem.managerID ? data.personalDetailsList?.[reportItem.managerID] : emptyPersonalDetails;
- const payerName = payerPersonalDetails?.displayName ?? payerPersonalDetails?.login ?? translateLocal('common.hidden');
- const formattedAmount = CurrencyUtils.convertToDisplayString(reportItem.total ?? 0, reportItem.currency ?? CONST.CURRENCY.USD);
- if (reportItem.action === CONST.SEARCH.ACTION_TYPES.VIEW) {
- return translateLocal('iou.payerOwesAmount', {
- payer: payerName,
- amount: formattedAmount,
- });
- }
-
- if (reportItem.action === CONST.SEARCH.ACTION_TYPES.PAID) {
- return translateLocal('iou.payerPaidAmount', {
- payer: payerName,
- amount: formattedAmount,
- });
- }
-
- return reportItem.reportName;
-}
-
-function getReportSections(data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search']): ReportListItemType[] {
- const shouldShowMerchant = getShouldShowMerchant(data);
-
- const doesDataContainAPastYearTransaction = shouldShowYear(data);
-
- const reportIDToTransactions: Record = {};
- for (const key in data) {
- if (isReportEntry(key)) {
- const reportItem = {...data[key]};
- const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${reportItem.reportID}`;
- const transactions = reportIDToTransactions[reportKey]?.transactions ?? [];
- const isIOUReport = reportItem.type === CONST.REPORT.TYPE.IOU;
-
- reportIDToTransactions[reportKey] = {
- ...reportItem,
- keyForList: reportItem.reportID,
- from: data.personalDetailsList?.[reportItem.accountID ?? -1],
- to: reportItem.managerID ? data.personalDetailsList?.[reportItem.managerID] : emptyPersonalDetails,
- transactions,
- reportName: isIOUReport ? getIOUReportName(data, reportItem) : reportItem.reportName,
- };
- } else if (isTransactionEntry(key)) {
- const transactionItem = {...data[key]};
- const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${transactionItem.reportID}`;
-
- const from = data.personalDetailsList?.[transactionItem.accountID];
- const to = transactionItem.managerID ? data.personalDetailsList?.[transactionItem.managerID] : emptyPersonalDetails;
-
- const {formattedFrom, formattedTo, formattedTotal, formattedMerchant, date} = getTransactionItemCommonFormattedProperties(transactionItem, from, to);
-
- const transaction = {
- ...transactionItem,
- from,
- to,
- formattedFrom,
- formattedTo,
- formattedTotal,
- formattedMerchant,
- date,
- shouldShowMerchant,
- shouldShowCategory: metadata?.columnsToShow?.shouldShowCategoryColumn,
- shouldShowTag: metadata?.columnsToShow?.shouldShowTagColumn,
- shouldShowTax: metadata?.columnsToShow?.shouldShowTaxColumn,
- keyForList: transactionItem.transactionID,
- shouldShowYear: doesDataContainAPastYearTransaction,
- };
- if (reportIDToTransactions[reportKey]?.transactions) {
- reportIDToTransactions[reportKey].transactions.push(transaction);
- } else if (reportIDToTransactions[reportKey]) {
- reportIDToTransactions[reportKey].transactions = [transaction];
- }
- }
- }
-
- return Object.values(reportIDToTransactions);
-}
-
-function getListItem(type: SearchDataTypes, status: SearchStatus): ListItemType {
- if (type === CONST.SEARCH.DATA_TYPES.CHAT) {
- return ChatListItem;
- }
- if (status === CONST.SEARCH.STATUS.EXPENSE.ALL) {
- return TransactionListItem;
- }
- return ReportListItem;
-}
-
-function getSections(type: SearchDataTypes, status: SearchStatus, data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search']) {
- if (type === CONST.SEARCH.DATA_TYPES.CHAT) {
- return getReportActionsSections(data);
- }
- if (status === CONST.SEARCH.STATUS.EXPENSE.ALL) {
- return getTransactionsSections(data, metadata);
- }
- return getReportSections(data, metadata);
-}
-
-function getSortedSections(type: SearchDataTypes, status: SearchStatus, data: ListItemDataType, sortBy?: SearchColumnType, sortOrder?: SortOrder) {
- if (type === CONST.SEARCH.DATA_TYPES.CHAT) {
- return getSortedReportActionData(data as ReportActionListItemType[]);
- }
- if (status === CONST.SEARCH.STATUS.EXPENSE.ALL) {
- return getSortedTransactionData(data as TransactionListItemType[], sortBy, sortOrder);
- }
- return getSortedReportData(data as ReportListItemType[]);
-}
-
-function getSortedTransactionData(data: TransactionListItemType[], sortBy?: SearchColumnType, sortOrder?: SortOrder) {
- if (!sortBy || !sortOrder) {
- return data;
- }
-
- const sortingProperty = columnNamesToSortingProperty[sortBy];
-
- if (!sortingProperty) {
- return data;
- }
-
- return data.sort((a, b) => {
- const aValue = sortingProperty === 'comment' ? a.comment?.comment : a[sortingProperty];
- const bValue = sortingProperty === 'comment' ? b.comment?.comment : b[sortingProperty];
-
- if (aValue === undefined || bValue === undefined) {
- return 0;
- }
-
- // We are guaranteed that both a and b will be string or number at the same time
- if (typeof aValue === 'string' && typeof bValue === 'string') {
- return sortOrder === CONST.SEARCH.SORT_ORDER.ASC ? aValue.toLowerCase().localeCompare(bValue) : bValue.toLowerCase().localeCompare(aValue);
- }
-
- const aNum = aValue as number;
- const bNum = bValue as number;
-
- return sortOrder === CONST.SEARCH.SORT_ORDER.ASC ? aNum - bNum : bNum - aNum;
- });
-}
-
-function getReportNewestTransactionDate(report: ReportListItemType) {
- return report.transactions?.reduce((max, curr) => (curr.modifiedCreated ?? curr.created > (max?.created ?? '') ? curr : max), report.transactions.at(0))?.created;
-}
-
-function getSortedReportData(data: ReportListItemType[]) {
- return data.sort((a, b) => {
- const aNewestTransaction = getReportNewestTransactionDate(a);
- const bNewestTransaction = getReportNewestTransactionDate(b);
-
- if (!aNewestTransaction || !bNewestTransaction) {
- return 0;
- }
-
- return bNewestTransaction.toLowerCase().localeCompare(aNewestTransaction);
- });
-}
-
-function getSortedReportActionData(data: ReportActionListItemType[]) {
- return data.sort((a, b) => {
- const aValue = a?.created;
- const bValue = b?.created;
-
- if (aValue === undefined || bValue === undefined) {
- return 0;
- }
-
- return bValue.toLowerCase().localeCompare(aValue);
- });
-}
-
-function isSearchResultsEmpty(searchResults: SearchResults) {
- return !Object.keys(searchResults?.data).some((key) => key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION));
-}
-
-function getQueryHashFromString(query: SearchQueryString): number {
- return UserUtils.hashText(query, 2 ** 32);
-}
-
-function getExpenseTypeTranslationKey(expenseType: ValueOf): TranslationPaths {
- // eslint-disable-next-line default-case
- switch (expenseType) {
- case CONST.SEARCH.TRANSACTION_TYPE.DISTANCE:
- return 'common.distance';
- case CONST.SEARCH.TRANSACTION_TYPE.CARD:
- return 'common.card';
- case CONST.SEARCH.TRANSACTION_TYPE.CASH:
- return 'iou.cash';
- }
-}
-
-/* Search query related */
-
-/**
- * Update string query with all the default params that are set by parser
- */
-function normalizeQuery(query: string) {
- const normalizedQueryJSON = buildSearchQueryJSON(query);
- return buildSearchQueryString(normalizedQueryJSON);
-}
-
/**
* @private
* returns Date filter query string part, which needs special logic
@@ -544,9 +142,12 @@ function buildSearchQueryJSON(query: SearchQueryString) {
const flatFilters = getFilters(result);
// Add the full input and hash to the results
+ const queryHash = UserUtils.hashText(query, 2 ** 32);
+
+ result.hash = queryHash;
result.inputQuery = query;
- result.hash = getQueryHashFromString(query);
result.flatFilters = flatFilters;
+
return result;
} catch (e) {
console.error(`Error when parsing SearchQuery: "${query}"`, e);
@@ -795,7 +396,7 @@ function buildFilterString(filterName: string, queryFilters: QueryFilter[]) {
} else if (filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.KEYWORD) {
filterValueString += `${delimiter}${sanitizeString(queryFilter.value.toString())}`;
} else {
- filterValueString += ` ${filterName}${operatorToSignMap[queryFilter.operator]}${sanitizeString(queryFilter.value.toString())}`;
+ filterValueString += ` ${filterName}${operatorToCharMap[queryFilter.operator]}${sanitizeString(queryFilter.value.toString())}`;
}
});
@@ -855,34 +456,9 @@ function buildCannedSearchQuery({
} = {}): SearchQueryString {
const queryString = policyID ? `type:${type} status:${status} policyID:${policyID}` : `type:${type} status:${status}`;
- return normalizeQuery(queryString);
-}
-
-function getOverflowMenu(itemName: string, hash: number, inputQuery: string, showDeleteModal: (hash: number) => void, isMobileMenu?: boolean, closeMenu?: () => void) {
- return [
- {
- text: translateLocal('common.rename'),
- onSelected: () => {
- if (isMobileMenu && closeMenu) {
- closeMenu();
- }
- Navigation.navigate(ROUTES.SEARCH_SAVED_SEARCH_RENAME.getRoute({name: encodeURIComponent(itemName), jsonQuery: inputQuery}));
- },
- icon: Expensicons.Pencil,
- shouldShowRightIcon: false,
- shouldShowRightComponent: false,
- shouldCallAfterModalHide: true,
- },
- {
- text: translateLocal('common.delete'),
- onSelected: () => showDeleteModal(hash),
- icon: Expensicons.Trashcan,
- shouldShowRightIcon: false,
- shouldShowRightComponent: false,
- shouldCallAfterModalHide: true,
- shouldCloseAllModals: true,
- },
- ];
+ // Parse the query to fill all default query fields with values
+ const normalizedQueryJSON = buildSearchQueryJSON(queryString);
+ return buildSearchQueryString(normalizedQueryJSON);
}
/**
@@ -969,32 +545,15 @@ function getContextualSuggestionQuery(reportID: string) {
return `type:chat in:${reportID}`;
}
-function isCorrectSearchUserName(displayName?: string) {
- return displayName && displayName.toUpperCase() !== CONST.REPORT.OWNER_EMAIL_FAKE;
-}
-
export {
- getContextualSuggestionQuery,
- buildQueryStringFromFilterFormValues,
buildSearchQueryJSON,
buildSearchQueryString,
+ buildQueryStringFromFilterFormValues,
buildFilterFormValuesFromQuery,
getPolicyIDFromSearchQuery,
- getListItem,
- getSections,
- getShouldShowMerchant,
- getSortedSections,
- isReportListItemType,
- isSearchResultsEmpty,
- isTransactionListItemType,
- isReportActionListItemType,
getSearchHeaderTitle,
- normalizeQuery,
- shouldShowYear,
buildCannedSearchQuery,
isCannedSearchQuery,
- getExpenseTypeTranslationKey,
- getOverflowMenu,
- isCorrectSearchUserName,
standardizeQueryJSON,
+ getContextualSuggestionQuery,
};
diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts
new file mode 100644
index 000000000000..89c28eb6c39f
--- /dev/null
+++ b/src/libs/SearchUIUtils.ts
@@ -0,0 +1,440 @@
+import type {ValueOf} from 'type-fest';
+import type {SearchColumnType, SearchStatus, SortOrder} from '@components/Search/types';
+import ChatListItem from '@components/SelectionList/ChatListItem';
+import ReportListItem from '@components/SelectionList/Search/ReportListItem';
+import TransactionListItem from '@components/SelectionList/Search/TransactionListItem';
+import type {ListItem, ReportActionListItemType, ReportListItemType, TransactionListItemType} from '@components/SelectionList/types';
+import * as Expensicons from '@src/components/Icon/Expensicons';
+import CONST from '@src/CONST';
+import type {TranslationPaths} from '@src/languages/types';
+import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
+import type * as OnyxTypes from '@src/types/onyx';
+import type SearchResults from '@src/types/onyx/SearchResults';
+import type {ListItemDataType, ListItemType, SearchDataTypes, SearchPersonalDetails, SearchReport, SearchTransaction} from '@src/types/onyx/SearchResults';
+import * as CurrencyUtils from './CurrencyUtils';
+import DateUtils from './DateUtils';
+import {translateLocal} from './Localize';
+import Navigation from './Navigation/Navigation';
+import * as ReportActionsUtils from './ReportActionsUtils';
+import * as TransactionUtils from './TransactionUtils';
+
+const columnNamesToSortingProperty = {
+ [CONST.SEARCH.TABLE_COLUMNS.TO]: 'formattedTo' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.FROM]: 'formattedFrom' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.DATE]: 'date' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.TAG]: 'tag' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.MERCHANT]: 'formattedMerchant' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT]: 'formattedTotal' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.CATEGORY]: 'category' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.TYPE]: 'transactionType' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.ACTION]: 'action' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION]: 'comment' as const,
+ [CONST.SEARCH.TABLE_COLUMNS.TAX_AMOUNT]: null,
+ [CONST.SEARCH.TABLE_COLUMNS.RECEIPT]: null,
+};
+
+const emptyPersonalDetails = {
+ accountID: CONST.REPORT.OWNER_ACCOUNT_ID_FAKE,
+ avatar: '',
+ displayName: undefined,
+ login: undefined,
+};
+/* Search list and results related */
+
+/**
+ * @private
+ */
+function getTransactionItemCommonFormattedProperties(
+ transactionItem: SearchTransaction,
+ from: SearchPersonalDetails,
+ to: SearchPersonalDetails,
+): Pick {
+ const isExpenseReport = transactionItem.reportType === CONST.REPORT.TYPE.EXPENSE;
+
+ const formattedFrom = from?.displayName ?? from?.login ?? '';
+ const formattedTo = to?.displayName ?? to?.login ?? '';
+ const formattedTotal = TransactionUtils.getAmount(transactionItem, isExpenseReport);
+ const date = transactionItem?.modifiedCreated ? transactionItem.modifiedCreated : transactionItem?.created;
+ const merchant = TransactionUtils.getMerchant(transactionItem);
+ const formattedMerchant = merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT || merchant === CONST.TRANSACTION.DEFAULT_MERCHANT ? '' : merchant;
+
+ return {
+ formattedFrom,
+ formattedTo,
+ date,
+ formattedTotal,
+ formattedMerchant,
+ };
+}
+
+type ReportKey = `${typeof ONYXKEYS.COLLECTION.REPORT}${string}`;
+
+type TransactionKey = `${typeof ONYXKEYS.COLLECTION.TRANSACTION}${string}`;
+
+type ReportActionKey = `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS}${string}`;
+
+function isReportEntry(key: string): key is ReportKey {
+ return key.startsWith(ONYXKEYS.COLLECTION.REPORT);
+}
+
+function isTransactionEntry(key: string): key is TransactionKey {
+ return key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION);
+}
+
+function isReportActionEntry(key: string): key is ReportActionKey {
+ return key.startsWith(ONYXKEYS.COLLECTION.REPORT_ACTIONS);
+}
+
+function getShouldShowMerchant(data: OnyxTypes.SearchResults['data']): boolean {
+ return Object.keys(data).some((key) => {
+ if (isTransactionEntry(key)) {
+ const item = data[key];
+ const merchant = item.modifiedMerchant ? item.modifiedMerchant : item.merchant ?? '';
+ return merchant !== '' && merchant !== CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT && merchant !== CONST.TRANSACTION.DEFAULT_MERCHANT;
+ }
+ return false;
+ });
+}
+
+const currentYear = new Date().getFullYear();
+
+function isReportListItemType(item: ListItem): item is ReportListItemType {
+ return 'transactions' in item;
+}
+
+function isTransactionListItemType(item: TransactionListItemType | ReportListItemType | ReportActionListItemType): item is TransactionListItemType {
+ const transactionListItem = item as TransactionListItemType;
+ return transactionListItem.transactionID !== undefined;
+}
+
+function isReportActionListItemType(item: TransactionListItemType | ReportListItemType | ReportActionListItemType): item is ReportActionListItemType {
+ const reportActionListItem = item as ReportActionListItemType;
+ return reportActionListItem.reportActionID !== undefined;
+}
+
+function shouldShowYear(data: TransactionListItemType[] | ReportListItemType[] | OnyxTypes.SearchResults['data']): boolean {
+ if (Array.isArray(data)) {
+ return data.some((item: TransactionListItemType | ReportListItemType) => {
+ if (isReportListItemType(item)) {
+ // If the item is a ReportListItemType, iterate over its transactions and check them
+ return item.transactions.some((transaction) => {
+ const transactionYear = new Date(TransactionUtils.getCreated(transaction)).getFullYear();
+ return transactionYear !== currentYear;
+ });
+ }
+
+ const createdYear = new Date(item?.modifiedCreated ? item.modifiedCreated : item?.created || '').getFullYear();
+ return createdYear !== currentYear;
+ });
+ }
+
+ for (const key in data) {
+ if (isTransactionEntry(key)) {
+ const item = data[key];
+ const date = TransactionUtils.getCreated(item);
+
+ if (DateUtils.doesDateBelongToAPastYear(date)) {
+ return true;
+ }
+ } else if (isReportActionEntry(key)) {
+ const item = data[key];
+ for (const action of Object.values(item)) {
+ const date = action.created;
+
+ if (DateUtils.doesDateBelongToAPastYear(date)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+function getTransactionsSections(data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search']): TransactionListItemType[] {
+ const shouldShowMerchant = getShouldShowMerchant(data);
+
+ const doesDataContainAPastYearTransaction = shouldShowYear(data);
+
+ return Object.keys(data)
+ .filter(isTransactionEntry)
+ .map((key) => {
+ const transactionItem = data[key];
+ const from = data.personalDetailsList?.[transactionItem.accountID];
+ const to = transactionItem.managerID ? data.personalDetailsList?.[transactionItem.managerID] : emptyPersonalDetails;
+
+ const {formattedFrom, formattedTo, formattedTotal, formattedMerchant, date} = getTransactionItemCommonFormattedProperties(transactionItem, from, to);
+
+ return {
+ ...transactionItem,
+ from,
+ to,
+ formattedFrom,
+ formattedTo,
+ formattedTotal,
+ formattedMerchant,
+ date,
+ shouldShowMerchant,
+ shouldShowCategory: metadata?.columnsToShow?.shouldShowCategoryColumn,
+ shouldShowTag: metadata?.columnsToShow?.shouldShowTagColumn,
+ shouldShowTax: metadata?.columnsToShow?.shouldShowTaxColumn,
+ keyForList: transactionItem.transactionID,
+ shouldShowYear: doesDataContainAPastYearTransaction,
+ };
+ });
+}
+
+function getReportActionsSections(data: OnyxTypes.SearchResults['data']): ReportActionListItemType[] {
+ const reportActionItems: ReportActionListItemType[] = [];
+ for (const key in data) {
+ if (isReportActionEntry(key)) {
+ const reportActions = data[key];
+ for (const reportAction of Object.values(reportActions)) {
+ const from = data.personalDetailsList?.[reportAction.accountID];
+ if (ReportActionsUtils.isDeletedAction(reportAction)) {
+ // eslint-disable-next-line no-continue
+ continue;
+ }
+ reportActionItems.push({
+ ...reportAction,
+ from,
+ formattedFrom: from?.displayName ?? from?.login ?? '',
+ date: reportAction.created,
+ keyForList: reportAction.reportActionID,
+ });
+ }
+ }
+ }
+ return reportActionItems;
+}
+
+function getIOUReportName(data: OnyxTypes.SearchResults['data'], reportItem: SearchReport) {
+ const payerPersonalDetails = reportItem.managerID ? data.personalDetailsList?.[reportItem.managerID] : emptyPersonalDetails;
+ const payerName = payerPersonalDetails?.displayName ?? payerPersonalDetails?.login ?? translateLocal('common.hidden');
+ const formattedAmount = CurrencyUtils.convertToDisplayString(reportItem.total ?? 0, reportItem.currency ?? CONST.CURRENCY.USD);
+ if (reportItem.action === CONST.SEARCH.ACTION_TYPES.VIEW) {
+ return translateLocal('iou.payerOwesAmount', {
+ payer: payerName,
+ amount: formattedAmount,
+ });
+ }
+
+ if (reportItem.action === CONST.SEARCH.ACTION_TYPES.PAID) {
+ return translateLocal('iou.payerPaidAmount', {
+ payer: payerName,
+ amount: formattedAmount,
+ });
+ }
+
+ return reportItem.reportName;
+}
+
+function getReportSections(data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search']): ReportListItemType[] {
+ const shouldShowMerchant = getShouldShowMerchant(data);
+
+ const doesDataContainAPastYearTransaction = shouldShowYear(data);
+
+ const reportIDToTransactions: Record = {};
+ for (const key in data) {
+ if (isReportEntry(key)) {
+ const reportItem = {...data[key]};
+ const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${reportItem.reportID}`;
+ const transactions = reportIDToTransactions[reportKey]?.transactions ?? [];
+ const isIOUReport = reportItem.type === CONST.REPORT.TYPE.IOU;
+
+ reportIDToTransactions[reportKey] = {
+ ...reportItem,
+ keyForList: reportItem.reportID,
+ from: data.personalDetailsList?.[reportItem.accountID ?? -1],
+ to: reportItem.managerID ? data.personalDetailsList?.[reportItem.managerID] : emptyPersonalDetails,
+ transactions,
+ reportName: isIOUReport ? getIOUReportName(data, reportItem) : reportItem.reportName,
+ };
+ } else if (isTransactionEntry(key)) {
+ const transactionItem = {...data[key]};
+ const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${transactionItem.reportID}`;
+
+ const from = data.personalDetailsList?.[transactionItem.accountID];
+ const to = transactionItem.managerID ? data.personalDetailsList?.[transactionItem.managerID] : emptyPersonalDetails;
+
+ const {formattedFrom, formattedTo, formattedTotal, formattedMerchant, date} = getTransactionItemCommonFormattedProperties(transactionItem, from, to);
+
+ const transaction = {
+ ...transactionItem,
+ from,
+ to,
+ formattedFrom,
+ formattedTo,
+ formattedTotal,
+ formattedMerchant,
+ date,
+ shouldShowMerchant,
+ shouldShowCategory: metadata?.columnsToShow?.shouldShowCategoryColumn,
+ shouldShowTag: metadata?.columnsToShow?.shouldShowTagColumn,
+ shouldShowTax: metadata?.columnsToShow?.shouldShowTaxColumn,
+ keyForList: transactionItem.transactionID,
+ shouldShowYear: doesDataContainAPastYearTransaction,
+ };
+ if (reportIDToTransactions[reportKey]?.transactions) {
+ reportIDToTransactions[reportKey].transactions.push(transaction);
+ } else if (reportIDToTransactions[reportKey]) {
+ reportIDToTransactions[reportKey].transactions = [transaction];
+ }
+ }
+ }
+
+ return Object.values(reportIDToTransactions);
+}
+
+function getListItem(type: SearchDataTypes, status: SearchStatus): ListItemType {
+ if (type === CONST.SEARCH.DATA_TYPES.CHAT) {
+ return ChatListItem;
+ }
+ if (status === CONST.SEARCH.STATUS.EXPENSE.ALL) {
+ return TransactionListItem;
+ }
+ return ReportListItem;
+}
+
+function getSections(type: SearchDataTypes, status: SearchStatus, data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search']) {
+ if (type === CONST.SEARCH.DATA_TYPES.CHAT) {
+ return getReportActionsSections(data);
+ }
+ if (status === CONST.SEARCH.STATUS.EXPENSE.ALL) {
+ return getTransactionsSections(data, metadata);
+ }
+ return getReportSections(data, metadata);
+}
+
+function getSortedSections(type: SearchDataTypes, status: SearchStatus, data: ListItemDataType, sortBy?: SearchColumnType, sortOrder?: SortOrder) {
+ if (type === CONST.SEARCH.DATA_TYPES.CHAT) {
+ return getSortedReportActionData(data as ReportActionListItemType[]);
+ }
+ if (status === CONST.SEARCH.STATUS.EXPENSE.ALL) {
+ return getSortedTransactionData(data as TransactionListItemType[], sortBy, sortOrder);
+ }
+ return getSortedReportData(data as ReportListItemType[]);
+}
+
+function getSortedTransactionData(data: TransactionListItemType[], sortBy?: SearchColumnType, sortOrder?: SortOrder) {
+ if (!sortBy || !sortOrder) {
+ return data;
+ }
+
+ const sortingProperty = columnNamesToSortingProperty[sortBy];
+
+ if (!sortingProperty) {
+ return data;
+ }
+
+ return data.sort((a, b) => {
+ const aValue = sortingProperty === 'comment' ? a.comment?.comment : a[sortingProperty];
+ const bValue = sortingProperty === 'comment' ? b.comment?.comment : b[sortingProperty];
+
+ if (aValue === undefined || bValue === undefined) {
+ return 0;
+ }
+
+ // We are guaranteed that both a and b will be string or number at the same time
+ if (typeof aValue === 'string' && typeof bValue === 'string') {
+ return sortOrder === CONST.SEARCH.SORT_ORDER.ASC ? aValue.toLowerCase().localeCompare(bValue) : bValue.toLowerCase().localeCompare(aValue);
+ }
+
+ const aNum = aValue as number;
+ const bNum = bValue as number;
+
+ return sortOrder === CONST.SEARCH.SORT_ORDER.ASC ? aNum - bNum : bNum - aNum;
+ });
+}
+
+function getReportNewestTransactionDate(report: ReportListItemType) {
+ return report.transactions?.reduce((max, curr) => (curr.modifiedCreated ?? curr.created > (max?.created ?? '') ? curr : max), report.transactions.at(0))?.created;
+}
+
+function getSortedReportData(data: ReportListItemType[]) {
+ return data.sort((a, b) => {
+ const aNewestTransaction = getReportNewestTransactionDate(a);
+ const bNewestTransaction = getReportNewestTransactionDate(b);
+
+ if (!aNewestTransaction || !bNewestTransaction) {
+ return 0;
+ }
+
+ return bNewestTransaction.toLowerCase().localeCompare(aNewestTransaction);
+ });
+}
+
+function getSortedReportActionData(data: ReportActionListItemType[]) {
+ return data.sort((a, b) => {
+ const aValue = a?.created;
+ const bValue = b?.created;
+
+ if (aValue === undefined || bValue === undefined) {
+ return 0;
+ }
+
+ return bValue.toLowerCase().localeCompare(aValue);
+ });
+}
+
+function isSearchResultsEmpty(searchResults: SearchResults) {
+ return !Object.keys(searchResults?.data).some((key) => key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION));
+}
+
+function getExpenseTypeTranslationKey(expenseType: ValueOf): TranslationPaths {
+ // eslint-disable-next-line default-case
+ switch (expenseType) {
+ case CONST.SEARCH.TRANSACTION_TYPE.DISTANCE:
+ return 'common.distance';
+ case CONST.SEARCH.TRANSACTION_TYPE.CARD:
+ return 'common.card';
+ case CONST.SEARCH.TRANSACTION_TYPE.CASH:
+ return 'iou.cash';
+ }
+}
+
+function getOverflowMenu(itemName: string, hash: number, inputQuery: string, showDeleteModal: (hash: number) => void, isMobileMenu?: boolean, closeMenu?: () => void) {
+ return [
+ {
+ text: translateLocal('common.rename'),
+ onSelected: () => {
+ if (isMobileMenu && closeMenu) {
+ closeMenu();
+ }
+ Navigation.navigate(ROUTES.SEARCH_SAVED_SEARCH_RENAME.getRoute({name: encodeURIComponent(itemName), jsonQuery: inputQuery}));
+ },
+ icon: Expensicons.Pencil,
+ shouldShowRightIcon: false,
+ shouldShowRightComponent: false,
+ shouldCallAfterModalHide: true,
+ },
+ {
+ text: translateLocal('common.delete'),
+ onSelected: () => showDeleteModal(hash),
+ icon: Expensicons.Trashcan,
+ shouldShowRightIcon: false,
+ shouldShowRightComponent: false,
+ shouldCallAfterModalHide: true,
+ shouldCloseAllModals: true,
+ },
+ ];
+}
+
+function isCorrectSearchUserName(displayName?: string) {
+ return displayName && displayName.toUpperCase() !== CONST.REPORT.OWNER_EMAIL_FAKE;
+}
+
+export {
+ getListItem,
+ getSections,
+ getShouldShowMerchant,
+ getSortedSections,
+ isReportListItemType,
+ isSearchResultsEmpty,
+ isTransactionListItemType,
+ isReportActionListItemType,
+ shouldShowYear,
+ getExpenseTypeTranslationKey,
+ getOverflowMenu,
+ isCorrectSearchUserName,
+};
diff --git a/src/pages/Search/AdvancedSearchFilters.tsx b/src/pages/Search/AdvancedSearchFilters.tsx
index 6e117a8baaab..14b6bb37179a 100644
--- a/src/pages/Search/AdvancedSearchFilters.tsx
+++ b/src/pages/Search/AdvancedSearchFilters.tsx
@@ -20,7 +20,8 @@ import Navigation from '@libs/Navigation/Navigation';
import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils';
import {getAllTaxRates} from '@libs/PolicyUtils';
import * as ReportUtils from '@libs/ReportUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
+import * as SearchUIUtils from '@libs/SearchUIUtils';
import * as SearchActions from '@userActions/Search';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
@@ -237,7 +238,7 @@ function getFilterExpenseDisplayTitle(filters: Partial filterValue.includes(expenseType))
- .map((expenseType) => translate(SearchUtils.getExpenseTypeTranslationKey(expenseType)))
+ .map((expenseType) => translate(SearchUIUtils.getExpenseTypeTranslationKey(expenseType)))
.join(', ')
: undefined;
}
@@ -266,8 +267,8 @@ function AdvancedSearchFilters() {
currentType = CONST.SEARCH.DATA_TYPES.EXPENSE;
}
- const queryString = useMemo(() => SearchUtils.buildQueryStringFromFilterFormValues(searchAdvancedFilters), [searchAdvancedFilters]);
- const queryJSON = useMemo(() => SearchUtils.buildSearchQueryJSON(queryString || SearchUtils.buildCannedSearchQuery()), [queryString]);
+ const queryString = useMemo(() => SearchQueryUtils.buildQueryStringFromFilterFormValues(searchAdvancedFilters), [searchAdvancedFilters]);
+ const queryJSON = useMemo(() => SearchQueryUtils.buildSearchQueryJSON(queryString || SearchQueryUtils.buildCannedSearchQuery()), [queryString]);
const applyFiltersAndNavigate = () => {
SearchActions.clearAllFilters();
@@ -337,7 +338,7 @@ function AdvancedSearchFilters() {
})
.sort((a, b) => (a?.description ?? '')?.localeCompare(b?.description ?? ''));
- const displaySearchButton = queryJSON && !SearchUtils.isCannedSearchQuery(queryJSON);
+ const displaySearchButton = queryJSON && !SearchQueryUtils.isCannedSearchQuery(queryJSON);
return (
<>
diff --git a/src/pages/Search/SavedSearchRenamePage.tsx b/src/pages/Search/SavedSearchRenamePage.tsx
index 00180cd5de7f..98a33759682c 100644
--- a/src/pages/Search/SavedSearchRenamePage.tsx
+++ b/src/pages/Search/SavedSearchRenamePage.tsx
@@ -10,7 +10,7 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as SearchActions from '@libs/actions/Search';
import Navigation from '@libs/Navigation/Navigation';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
@@ -34,7 +34,7 @@ function SavedSearchRenamePage({route}: {route: {params: {q: string; name: strin
};
const onSaveSearch = () => {
- const queryJSON = SearchUtils.buildSearchQueryJSON(q || SearchUtils.buildCannedSearchQuery()) ?? ({} as SearchQueryJSON);
+ const queryJSON = SearchQueryUtils.buildSearchQueryJSON(q || SearchQueryUtils.buildCannedSearchQuery()) ?? ({} as SearchQueryJSON);
SearchActions.saveSearch({
queryJSON,
diff --git a/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersExpenseTypePage.tsx b/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersExpenseTypePage.tsx
index ea97340fed14..f0e90912302d 100644
--- a/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersExpenseTypePage.tsx
+++ b/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersExpenseTypePage.tsx
@@ -8,7 +8,7 @@ import SearchMultipleSelectionPicker from '@components/Search/SearchMultipleSele
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
-import {getExpenseTypeTranslationKey} from '@libs/SearchUtils';
+import {getExpenseTypeTranslationKey} from '@libs/SearchUIUtils';
import * as SearchActions from '@userActions/Search';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx
index 82c502febaf8..2289eb7b0a85 100644
--- a/src/pages/Search/SearchPage.tsx
+++ b/src/pages/Search/SearchPage.tsx
@@ -9,7 +9,7 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
@@ -20,8 +20,8 @@ function SearchPage({route}: SearchPageProps) {
const styles = useThemeStyles();
const {q} = route.params;
- const queryJSON = useMemo(() => SearchUtils.buildSearchQueryJSON(q), [q]);
- const handleOnBackButtonPress = () => Navigation.goBack(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: SearchUtils.buildCannedSearchQuery()}));
+ const queryJSON = useMemo(() => SearchQueryUtils.buildSearchQueryJSON(q), [q]);
+ const handleOnBackButtonPress = () => Navigation.goBack(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: SearchQueryUtils.buildCannedSearchQuery()}));
// On small screens this page is not displayed, the configuration is in the file: src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx
// To avoid calling hooks in the Search component when this page isn't visible, we return null here.
diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx
index 5bda7cd0056e..dfb671da7af1 100644
--- a/src/pages/Search/SearchPageBottomTab.tsx
+++ b/src/pages/Search/SearchPageBottomTab.tsx
@@ -13,7 +13,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
import TopBar from '@navigation/AppNavigator/createCustomBottomTabNavigator/TopBar';
import variables from '@styles/variables';
import ONYXKEYS from '@src/ONYXKEYS';
@@ -60,15 +60,15 @@ function SearchPageBottomTab() {
});
const searchParams = activeCentralPaneRoute?.params as AuthScreensParamList[typeof SCREENS.SEARCH.CENTRAL_PANE];
- const parsedQuery = SearchUtils.buildSearchQueryJSON(searchParams?.q);
+ const parsedQuery = SearchQueryUtils.buildSearchQueryJSON(searchParams?.q);
const isSearchNameModified = searchParams?.name === searchParams?.q;
const searchName = isSearchNameModified ? undefined : searchParams?.name;
- const policyIDFromSearchQuery = parsedQuery && SearchUtils.getPolicyIDFromSearchQuery(parsedQuery);
+ const policyIDFromSearchQuery = parsedQuery && SearchQueryUtils.getPolicyIDFromSearchQuery(parsedQuery);
const isActiveCentralPaneRoute = activeCentralPaneRoute?.name === SCREENS.SEARCH.CENTRAL_PANE;
const queryJSON = isActiveCentralPaneRoute ? parsedQuery : undefined;
const policyID = isActiveCentralPaneRoute ? policyIDFromSearchQuery : undefined;
- const handleOnBackButtonPress = () => Navigation.goBack(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: SearchUtils.buildCannedSearchQuery()}));
+ const handleOnBackButtonPress = () => Navigation.goBack(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: SearchQueryUtils.buildCannedSearchQuery()}));
if (!queryJSON) {
return (
@@ -100,7 +100,7 @@ function SearchPageBottomTab() {
breadcrumbLabel={translate('common.search')}
shouldDisplaySearch={false}
shouldDisplaySearchRouter={shouldUseNarrowLayout}
- isCustomSearchQuery={shouldUseNarrowLayout && !SearchUtils.isCannedSearchQuery(queryJSON)}
+ isCustomSearchQuery={shouldUseNarrowLayout && !SearchQueryUtils.isCannedSearchQuery(queryJSON)}
/>
{shouldUseNarrowLayout ? (
diff --git a/src/pages/Search/SearchTypeMenu.tsx b/src/pages/Search/SearchTypeMenu.tsx
index 70e7c20fee13..4aec50986f84 100644
--- a/src/pages/Search/SearchTypeMenu.tsx
+++ b/src/pages/Search/SearchTypeMenu.tsx
@@ -20,7 +20,8 @@ import useThemeStyles from '@hooks/useThemeStyles';
import * as SearchActions from '@libs/actions/Search';
import Navigation from '@libs/Navigation/Navigation';
import {getAllTaxRates} from '@libs/PolicyUtils';
-import * as SearchUtils from '@libs/SearchUtils';
+import * as SearchQueryUtils from '@libs/SearchQueryUtils';
+import * as SearchUIUtils from '@libs/SearchUIUtils';
import variables from '@styles/variables';
import * as Expensicons from '@src/components/Icon/Expensicons';
import CONST from '@src/CONST';
@@ -73,7 +74,7 @@ function SearchTypeMenu({queryJSON, searchName}: SearchTypeMenuProps) {
type: CONST.SEARCH.DATA_TYPES.EXPENSE,
icon: Expensicons.Receipt,
getRoute: (policyID?: string) => {
- const query = SearchUtils.buildCannedSearchQuery({policyID});
+ const query = SearchQueryUtils.buildCannedSearchQuery({policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
},
@@ -82,7 +83,7 @@ function SearchTypeMenu({queryJSON, searchName}: SearchTypeMenuProps) {
type: CONST.SEARCH.DATA_TYPES.CHAT,
icon: Expensicons.ChatBubbles,
getRoute: (policyID?: string) => {
- const query = SearchUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.CHAT, status: CONST.SEARCH.STATUS.CHAT.ALL, policyID});
+ const query = SearchQueryUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.CHAT, status: CONST.SEARCH.STATUS.CHAT.ALL, policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
},
@@ -91,7 +92,7 @@ function SearchTypeMenu({queryJSON, searchName}: SearchTypeMenuProps) {
type: CONST.SEARCH.DATA_TYPES.INVOICE,
icon: Expensicons.InvoiceGeneric,
getRoute: (policyID?: string) => {
- const query = SearchUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.INVOICE, status: CONST.SEARCH.STATUS.INVOICE.ALL, policyID});
+ const query = SearchQueryUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.INVOICE, status: CONST.SEARCH.STATUS.INVOICE.ALL, policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
},
@@ -100,22 +101,22 @@ function SearchTypeMenu({queryJSON, searchName}: SearchTypeMenuProps) {
type: CONST.SEARCH.DATA_TYPES.TRIP,
icon: Expensicons.Suitcase,
getRoute: (policyID?: string) => {
- const query = SearchUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.TRIP, status: CONST.SEARCH.STATUS.TRIP.ALL, policyID});
+ const query = SearchQueryUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.TRIP, status: CONST.SEARCH.STATUS.TRIP.ALL, policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
},
];
const getOverflowMenu = useCallback(
- (itemName: string, itemHash: number, itemQuery: string) => SearchUtils.getOverflowMenu(itemName, itemHash, itemQuery, showDeleteModal),
+ (itemName: string, itemHash: number, itemQuery: string) => SearchUIUtils.getOverflowMenu(itemName, itemHash, itemQuery, showDeleteModal),
[showDeleteModal],
);
const createSavedSearchMenuItem = (item: SaveSearchItem, key: string, isNarrow: boolean, index: number) => {
let title = item.name;
if (title === item.query) {
- const jsonQuery = SearchUtils.buildSearchQueryJSON(item.query) ?? ({} as SearchQueryJSON);
- title = SearchUtils.getSearchHeaderTitle(jsonQuery, personalDetails, cardList, reports, taxRates);
+ const jsonQuery = SearchQueryUtils.buildSearchQueryJSON(item.query) ?? ({} as SearchQueryJSON);
+ title = SearchQueryUtils.getSearchHeaderTitle(jsonQuery, personalDetails, cardList, reports, taxRates);
}
const baseMenuItem: SavedSearchMenuItem = {
@@ -216,11 +217,11 @@ function SearchTypeMenu({queryJSON, searchName}: SearchTypeMenuProps) {
[styles],
);
- const isCannedQuery = SearchUtils.isCannedSearchQuery(queryJSON);
+ const isCannedQuery = SearchQueryUtils.isCannedSearchQuery(queryJSON);
const activeItemIndex = isCannedQuery ? typeMenuItems.findIndex((item) => item.type === type) : -1;
if (shouldUseNarrowLayout) {
- const title = searchName ?? (isCannedQuery ? undefined : SearchUtils.getSearchHeaderTitle(queryJSON, personalDetails, cardList, reports, taxRates));
+ const title = searchName ?? (isCannedQuery ? undefined : SearchQueryUtils.getSearchHeaderTitle(queryJSON, personalDetails, cardList, reports, taxRates));
return (
setIsPopoverVisible(true), []);
const closeMenu = useCallback(() => setIsPopoverVisible(false), []);
const onPress = () => {
- const values = SearchUtils.buildFilterFormValuesFromQuery(queryJSON, policyCategories, policyTagsLists, currencyList, personalDetails, cardList, reports, taxRates);
+ const values = SearchQueryUtils.buildFilterFormValuesFromQuery(queryJSON, policyCategories, policyTagsLists, currencyList, personalDetails, cardList, reports, taxRates);
SearchActions.updateAdvancedFilters(values);
Navigation.navigate(ROUTES.SEARCH_ADVANCED_FILTERS);
};
@@ -140,7 +141,7 @@ function SearchTypeMenuNarrow({typeMenuItems, activeItemIndex, queryJSON, title,
shouldShowRightComponent: true,
rightComponent: (
{
- const query = SearchUtils.buildQueryStringFromFilterFormValues({merchant: CONST.EXPENSIFY_MERCHANT});
+ const query = SearchQueryUtils.buildQueryStringFromFilterFormValues({merchant: CONST.EXPENSIFY_MERCHANT});
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query}));
}, []);