diff --git a/src/components/Search/SearchAutocompleteList.tsx b/src/components/Search/SearchAutocompleteList.tsx index 2ce9c5329a70..4be2810d9d1a 100644 --- a/src/components/Search/SearchAutocompleteList.tsx +++ b/src/components/Search/SearchAutocompleteList.tsx @@ -13,6 +13,7 @@ import UserListItem from '@components/SelectionList/UserListItem'; import useActiveWorkspace from '@hooks/useActiveWorkspace'; import useFastSearchFromOptions from '@hooks/useFastSearchFromOptions'; import useLocalize from '@hooks/useLocalize'; +import usePermissions from '@hooks/usePermissions'; import usePolicy from '@hooks/usePolicy'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -23,7 +24,7 @@ import memoize from '@libs/memoize'; import {combineOrderingOfReportsAndPersonalDetails, getSearchOptions, getValidPersonalDetailOptions} from '@libs/OptionsListUtils'; import type {Options, SearchOption} from '@libs/OptionsListUtils'; import Performance from '@libs/Performance'; -import {getAllTaxRates, getCleanedTagName} from '@libs/PolicyUtils'; +import {getAllTaxRates, getCleanedTagName, shouldShowPolicy} from '@libs/PolicyUtils'; import type {OptionData} from '@libs/ReportUtils'; import { getAutocompleteCategories, @@ -145,11 +146,12 @@ function SearchAutocompleteList( const {activeWorkspaceID} = useActiveWorkspace(); const policy = usePolicy(activeWorkspaceID); - const [betas] = useOnyx(ONYXKEYS.BETAS); - const [recentSearches] = useOnyx(ONYXKEYS.RECENT_SEARCHES); + const [betas] = useOnyx(ONYXKEYS.BETAS, {canBeMissing: true}); + const [recentSearches] = useOnyx(ONYXKEYS.RECENT_SEARCHES, {canBeMissing: true}); const personalDetails = usePersonalDetails(); - const [reports = {}] = useOnyx(ONYXKEYS.COLLECTION.REPORT); + const [reports = {}] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: true}); const taxRates = getAllTaxRates(); + const {canUseLeftHandBar} = usePermissions(); const {options, areOptionsInitialized} = useOptionsList(); const searchOptions = useMemo(() => { @@ -167,8 +169,8 @@ function SearchAutocompleteList( const expenseTypes = Object.values(CONST.SEARCH.TRANSACTION_TYPE); const booleanTypes = Object.values(CONST.SEARCH.BOOLEAN); - const [userCardList] = useOnyx(ONYXKEYS.CARD_LIST); - const [workspaceCardFeeds] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST); + const [userCardList] = useOnyx(ONYXKEYS.CARD_LIST, {canBeMissing: true}); + const [workspaceCardFeeds] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST, {canBeMissing: true}); const allCards = useMemo(() => mergeCardListWithWorkspaceFeeds(workspaceCardFeeds ?? CONST.EMPTY_OBJECT, userCardList), [userCardList, workspaceCardFeeds]); const cardAutocompleteList = Object.values(allCards); const cardFeedNamesWithType = useMemo(() => { @@ -210,8 +212,8 @@ function SearchAutocompleteList( const taxAutocompleteList = useMemo(() => getAutocompleteTaxList(taxRates, policy), [policy, taxRates]); - const [allPolicyCategories] = useOnyx(ONYXKEYS.COLLECTION.POLICY_CATEGORIES); - const [allRecentCategories] = useOnyx(ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES); + const [allPolicyCategories] = useOnyx(ONYXKEYS.COLLECTION.POLICY_CATEGORIES, {canBeMissing: false}); + const [allRecentCategories] = useOnyx(ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES, {canBeMissing: true}); const categoryAutocompleteList = useMemo(() => { return getAutocompleteCategories(allPolicyCategories, activeWorkspaceID); }, [activeWorkspaceID, allPolicyCategories]); @@ -219,11 +221,22 @@ function SearchAutocompleteList( return getAutocompleteRecentCategories(allRecentCategories, activeWorkspaceID); }, [activeWorkspaceID, allRecentCategories]); - const [currencyList] = useOnyx(ONYXKEYS.CURRENCY_LIST); + const [policies = {}] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: false}); + const [currentUserLogin] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.email, canBeMissing: false}); + + const workspaceList = useMemo( + () => + Object.values(policies) + .filter((singlePolicy) => !!singlePolicy && shouldShowPolicy(singlePolicy, false, currentUserLogin) && !singlePolicy?.isJoinRequestPending) + .map((singlePolicy) => ({id: singlePolicy?.id, name: singlePolicy?.name ?? ''})), + [policies, currentUserLogin], + ); + + const [currencyList] = useOnyx(ONYXKEYS.CURRENCY_LIST, {canBeMissing: false}); const currencyAutocompleteList = Object.keys(currencyList ?? {}).filter((currency) => !currencyList?.[currency]?.retired); - const [recentCurrencyAutocompleteList] = useOnyx(ONYXKEYS.RECENTLY_USED_CURRENCIES); - const [allPoliciesTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS); - const [allRecentTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS); + const [recentCurrencyAutocompleteList] = useOnyx(ONYXKEYS.RECENTLY_USED_CURRENCIES, {canBeMissing: true}); + const [allPoliciesTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS, {canBeMissing: false}); + const [allRecentTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS, {canBeMissing: true}); const tagAutocompleteList = useMemo(() => { return getAutocompleteTags(allPoliciesTags, activeWorkspaceID); }, [activeWorkspaceID, allPoliciesTags]); @@ -403,6 +416,22 @@ function SearchAutocompleteList( text: value, })); } + case CONST.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID: { + if (!canUseLeftHandBar) { + return []; + } + const filteredPolicies = workspaceList + .filter((workspace) => workspace.name.toLowerCase().includes(autocompleteValue.toLowerCase()) && !alreadyAutocompletedKeys.includes(workspace.name.toLowerCase())) + .sort() + .slice(0, 10); + + return filteredPolicies.map((workspace) => ({ + filterKey: CONST.SEARCH.SEARCH_USER_FRIENDLY_KEYS.POLICY_ID, + text: workspace.name, + autocompleteID: workspace.id, + mapKey: CONST.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID, + })); + } default: { return []; } @@ -419,14 +448,16 @@ function SearchAutocompleteList( getParticipantsAutocompleteList, searchOptions.recentReports, typeAutocompleteList, + groupByAutocompleteList, statusAutocompleteList, expenseTypes, feedAutoCompleteList, workspaceCardFeeds, cardAutocompleteList, allCards, - groupByAutocompleteList, booleanTypes, + workspaceList, + canUseLeftHandBar, ]); const sortedRecentSearches = useMemo(() => { diff --git a/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx b/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx index 0be5ef0ae02c..b4c58a0712e7 100644 --- a/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx +++ b/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx @@ -36,6 +36,7 @@ import { buildUserReadableQueryString, buildUserReadableQueryStringWithPolicyID, getQueryWithUpdatedValues, + getQueryWithUpdatedValuesWithoutPolicy, isDefaultExpensesQuery, isDefaultExpensesQueryWithPolicyIDCheck, sanitizeSearchValue, @@ -68,11 +69,11 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo const theme = useTheme(); const {shouldUseNarrowLayout: displayNarrowHeader} = useResponsiveLayout(); const personalDetails = usePersonalDetails(); - const [reports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); - const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); + const [reports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: true}); + const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: false}); const taxRates = useMemo(() => getAllTaxRates(), []); - const [userCardList] = useOnyx(ONYXKEYS.CARD_LIST); - const [workspaceCardFeeds] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST); + const [userCardList] = useOnyx(ONYXKEYS.CARD_LIST, {canBeMissing: false}); + const [workspaceCardFeeds] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST, {canBeMissing: true}); const allCards = useMemo(() => mergeCardListWithWorkspaceFeeds(workspaceCardFeeds ?? CONST.EMPTY_OBJECT, userCardList), [userCardList, workspaceCardFeeds]); const cardFeedNamesWithType = useMemo(() => { return getCardFeedNamesWithType({workspaceCardFeeds, translate}); @@ -121,9 +122,9 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo }, [isDefaultQuery, queryText]); useEffect(() => { - const substitutionsMap = buildSubstitutionsMap(originalInputQuery, personalDetails, reports, taxRates, allCards, cardFeedNamesWithType); + const substitutionsMap = buildSubstitutionsMap(originalInputQuery, personalDetails, reports, taxRates, allCards, cardFeedNamesWithType, policies, canUseLeftHandBar); setAutocompleteSubstitutions(substitutionsMap); - }, [cardFeedNamesWithType, allCards, originalInputQuery, personalDetails, reports, taxRates]); + }, [cardFeedNamesWithType, allCards, originalInputQuery, personalDetails, reports, taxRates, policies, canUseLeftHandBar]); useEffect(() => { if (searchRouterListVisible) { @@ -167,7 +168,7 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo const submitSearch = useCallback( (queryString: SearchQueryString) => { const queryWithSubstitutions = getQueryWithSubstitutions(queryString, autocompleteSubstitutions); - const updatedQuery = getQueryWithUpdatedValues(queryWithSubstitutions, queryJSON.policyID); + const updatedQuery = canUseLeftHandBar ? getQueryWithUpdatedValuesWithoutPolicy(queryWithSubstitutions) : getQueryWithUpdatedValues(queryWithSubstitutions, queryJSON.policyID); if (!updatedQuery) { return; @@ -182,7 +183,7 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo setAutocompleteQueryValue(''); } }, - [autocompleteSubstitutions, hideSearchRouterList, originalInputQuery, queryJSON.policyID], + [autocompleteSubstitutions, hideSearchRouterList, originalInputQuery, queryJSON.policyID, canUseLeftHandBar], ); const onListItemPress = useCallback( diff --git a/src/components/Search/SearchRouter/SearchRouter.tsx b/src/components/Search/SearchRouter/SearchRouter.tsx index bed0431bce18..9e1fc8c3074d 100644 --- a/src/components/Search/SearchRouter/SearchRouter.tsx +++ b/src/components/Search/SearchRouter/SearchRouter.tsx @@ -19,13 +19,14 @@ import useActiveWorkspace from '@hooks/useActiveWorkspace'; import useDebouncedState from '@hooks/useDebouncedState'; import useKeyboardShortcut from '@hooks/useKeyboardShortcut'; import useLocalize from '@hooks/useLocalize'; +import usePermissions from '@hooks/usePermissions'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import {scrollToRight} from '@libs/InputUtils'; import type {SearchOption} from '@libs/OptionsListUtils'; import type {OptionData} from '@libs/ReportUtils'; import {getAutocompleteQueryWithComma, getQueryWithoutAutocompletedPart} from '@libs/SearchAutocompleteUtils'; -import {getQueryWithUpdatedValues, sanitizeSearchValue} from '@libs/SearchQueryUtils'; +import {getQueryWithUpdatedValues, getQueryWithUpdatedValuesWithoutPolicy, sanitizeSearchValue} from '@libs/SearchQueryUtils'; import StringUtils from '@libs/StringUtils'; import Navigation from '@navigation/Navigation'; import type {ReportsSplitNavigatorParamList} from '@navigation/types'; @@ -79,9 +80,10 @@ type SearchRouterProps = { function SearchRouter({onRouterClose, shouldHideInputCaret, isSearchRouterDisplayed}: SearchRouterProps, ref: React.Ref) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [, recentSearchesMetadata] = useOnyx(ONYXKEYS.RECENT_SEARCHES); - const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false}); + const [, recentSearchesMetadata] = useOnyx(ONYXKEYS.RECENT_SEARCHES, {canBeMissing: true}); + const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false, canBeMissing: true}); const {activeWorkspaceID} = useActiveWorkspace(); + const {canUseLeftHandBar} = usePermissions(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const listRef = useRef(null); @@ -215,7 +217,7 @@ function SearchRouter({onRouterClose, shouldHideInputCaret, isSearchRouterDispla const submitSearch = useCallback( (queryString: SearchQueryString) => { const queryWithSubstitutions = getQueryWithSubstitutions(queryString, autocompleteSubstitutions); - const updatedQuery = getQueryWithUpdatedValues(queryWithSubstitutions, activeWorkspaceID); + const updatedQuery = canUseLeftHandBar ? getQueryWithUpdatedValuesWithoutPolicy(queryWithSubstitutions) : getQueryWithUpdatedValues(queryWithSubstitutions, activeWorkspaceID); if (!updatedQuery) { return; } @@ -226,7 +228,7 @@ function SearchRouter({onRouterClose, shouldHideInputCaret, isSearchRouterDispla setTextInputValue(''); setAutocompleteQueryValue(''); }, - [autocompleteSubstitutions, onRouterClose, setTextInputValue, activeWorkspaceID], + [autocompleteSubstitutions, onRouterClose, setTextInputValue, activeWorkspaceID, canUseLeftHandBar], ); const setTextAndUpdateSelection = useCallback( diff --git a/src/components/Search/SearchRouter/buildSubstitutionsMap.ts b/src/components/Search/SearchRouter/buildSubstitutionsMap.ts index a085446bf9f2..77a1c37e949b 100644 --- a/src/components/Search/SearchRouter/buildSubstitutionsMap.ts +++ b/src/components/Search/SearchRouter/buildSubstitutionsMap.ts @@ -2,9 +2,9 @@ import type {OnyxCollection} from 'react-native-onyx'; import type {SearchAutocompleteQueryRange, SearchFilterKey} from '@components/Search/types'; import type {CardFeedNamesWithType} from '@libs/CardFeedUtils'; import {parse} from '@libs/SearchParser/autocompleteParser'; -import {getFilterDisplayValue} from '@libs/SearchQueryUtils'; +import {getFilterDisplayValue, getFilterDisplayValueWithPolicyID} from '@libs/SearchQueryUtils'; import CONST from '@src/CONST'; -import type {CardList, PersonalDetailsList, Report} from '@src/types/onyx'; +import type {CardList, PersonalDetailsList, Policy, Report} from '@src/types/onyx'; import type {SubstitutionMap} from './getQueryWithSubstitutions'; const getSubstitutionsKey = (filterKey: SearchFilterKey, value: string) => `${filterKey}:${value}`; @@ -32,6 +32,8 @@ function buildSubstitutionsMap( allTaxRates: Record, cardList: CardList, cardFeedNamesWithType: CardFeedNamesWithType, + policies: OnyxCollection, + canUseLeftHandBar?: boolean, ): SubstitutionMap { const parsedQuery = parse(query) as {ranges: SearchAutocompleteQueryRange[]}; @@ -63,9 +65,12 @@ function buildSubstitutionsMap( filterKey === CONST.SEARCH.SYNTAX_FILTER_KEYS.IN || filterKey === CONST.SEARCH.SYNTAX_FILTER_KEYS.CARD_ID || filterKey === CONST.SEARCH.SYNTAX_FILTER_KEYS.TAG || - filterKey === CONST.SEARCH.SYNTAX_FILTER_KEYS.FEED + filterKey === CONST.SEARCH.SYNTAX_FILTER_KEYS.FEED || + filterKey === CONST.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID ) { - const displayValue = getFilterDisplayValue(filterKey, filterValue, personalDetails, reports, cardList, cardFeedNamesWithType); + const displayValue = canUseLeftHandBar + ? getFilterDisplayValueWithPolicyID(filterKey, filterValue, personalDetails, reports, cardList, cardFeedNamesWithType, policies) + : getFilterDisplayValue(filterKey, filterValue, personalDetails, reports, cardList, cardFeedNamesWithType); // If displayValue === filterValue, then it means there is nothing to substitute, so we don't add any key to map if (displayValue !== filterValue) { diff --git a/src/libs/SearchAutocompleteUtils.ts b/src/libs/SearchAutocompleteUtils.ts index 978d6b03bd31..2f3a1945df83 100644 --- a/src/libs/SearchAutocompleteUtils.ts +++ b/src/libs/SearchAutocompleteUtils.ts @@ -159,6 +159,7 @@ function filterOutRangesWithCorrectValue( case CONST.SEARCH.SYNTAX_FILTER_KEYS.TAX_RATE: case CONST.SEARCH.SYNTAX_FILTER_KEYS.FEED: case CONST.SEARCH.SYNTAX_FILTER_KEYS.CARD_ID: + case CONST.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID: return substitutionMap[`${range.key}:${range.value}`] !== undefined; case CONST.SEARCH.SYNTAX_FILTER_KEYS.TO: diff --git a/src/libs/SearchParser/autocompleteParser.js b/src/libs/SearchParser/autocompleteParser.js index a80c8d370c47..c613805ec67f 100644 --- a/src/libs/SearchParser/autocompleteParser.js +++ b/src/libs/SearchParser/autocompleteParser.js @@ -718,6 +718,9 @@ function peg$parse(input, options) { s1 = peg$parsereimbursable(); if (s1 === peg$FAILED) { s1 = peg$parsebillable(); + if (s1 === peg$FAILED) { + s1 = peg$parsepolicyID(); + } } } } diff --git a/src/libs/SearchParser/autocompleteParser.peggy b/src/libs/SearchParser/autocompleteParser.peggy index 3ea24232ce32..26baa274c697 100644 --- a/src/libs/SearchParser/autocompleteParser.peggy +++ b/src/libs/SearchParser/autocompleteParser.peggy @@ -72,6 +72,7 @@ autocompleteKey "key" / groupBy / reimbursable / billable + / policyID ) filterKey diff --git a/src/libs/SearchQueryUtils.ts b/src/libs/SearchQueryUtils.ts index bf7310522657..8028b122ede7 100644 --- a/src/libs/SearchQueryUtils.ts +++ b/src/libs/SearchQueryUtils.ts @@ -561,6 +561,63 @@ function getPolicyIDFromSearchQuery(queryJSON: SearchQueryJSON) { return policyID; } +/** + * A copy of `getFilterDisplayValue` handling the policy ID, used if you have access to the leftHandBar beta. + * When this beta is no longer needed, this method will be renamed to `getFilterDisplayValue` and will replace the old method. + * + * Returns the human-readable "pretty" string for a specified filter value. + */ +function getFilterDisplayValueWithPolicyID( + filterName: string, + filterValue: string, + personalDetails: OnyxTypes.PersonalDetailsList | undefined, + reports: OnyxCollection, + cardList: OnyxTypes.CardList, + cardFeedNamesWithType: CardFeedNamesWithType, + policies: OnyxCollection, +) { + if (filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.FROM || filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.TO) { + // login can be an empty string + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + return personalDetails?.[filterValue]?.displayName || filterValue; + } + if (filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.CARD_ID) { + const cardID = parseInt(filterValue, 10); + if (Number.isNaN(cardID)) { + return filterValue; + } + return getCardDescription(cardID, cardList) || filterValue; + } + if (filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.IN) { + return getReportName(reports?.[`${ONYXKEYS.COLLECTION.REPORT}${filterValue}`]) || filterValue; + } + if (filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.AMOUNT) { + const frontendAmount = convertToFrontendAmountAsInteger(Number(filterValue)); + return Number.isNaN(frontendAmount) ? filterValue : frontendAmount.toString(); + } + if (filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.TAG) { + return getCleanedTagName(filterValue); + } + if (filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.FEED) { + const workspaceFeedKey = getWorkspaceCardFeedKey(filterValue); + + const workspaceValue = cardFeedNamesWithType[workspaceFeedKey]; + const domainValue = cardFeedNamesWithType[filterValue]; + + if (workspaceValue && workspaceValue.type === 'workspace') { + return workspaceValue.name; + } + + if (domainValue && domainValue.type === 'domain') { + return domainValue.name; + } + } + if (filterName === CONST.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID) { + return policies?.[`${ONYXKEYS.COLLECTION.POLICY}${filterValue}`]?.name ?? filterValue; + } + return filterValue; +} + /** * Returns the human-readable "pretty" string for a specified filter value. */ @@ -667,7 +724,7 @@ function buildUserReadableQueryStringWithPolicyID( } else { displayQueryFilters = queryFilter.map((filter) => ({ operator: filter.operator, - value: getFilterDisplayValue(key, filter.value.toString(), PersonalDetails, reports, cardList, cardFeedNamesWithType), + value: getFilterDisplayValueWithPolicyID(key, filter.value.toString(), PersonalDetails, reports, cardList, cardFeedNamesWithType, policies), })); } title += buildFilterValuesString(getUserFriendlyKey(key), displayQueryFilters); @@ -836,6 +893,25 @@ function traverseAndUpdatedQuery(queryJSON: SearchQueryJSON, computeNodeValue: ( return standardQuery; } +/** + * A copy of `getQueryWithUpdatedValues` handling the policy ID, used if you have access to the leftHandBar beta. + * When this beta is no longer needed, this method will be renamed to `getQueryWithUpdatedValues` and will replace the old method. + * + * Returns new string query, after parsing it and traversing to update some filter values. + * If there are any personal emails, it will try to substitute them with accountIDs + */ +function getQueryWithUpdatedValuesWithoutPolicy(query: string) { + const queryJSON = buildSearchQueryJSON(query); + + if (!queryJSON) { + Log.alert(`${CONST.ERROR.ENSURE_BUGBOT} user query failed to parse`, {}, false); + return; + } + + const standardizedQuery = traverseAndUpdatedQuery(queryJSON, getUpdatedFilterValue); + return buildSearchQueryString(standardizedQuery); +} + /** * Returns new string query, after parsing it and traversing to update some filter values. * If there are any personal emails, it will try to substitute them with accountIDs @@ -913,6 +989,7 @@ export { buildUserReadableQueryString, buildUserReadableQueryStringWithPolicyID, getFilterDisplayValue, + getFilterDisplayValueWithPolicyID, buildQueryStringFromFilterFormValues, buildFilterFormValuesFromQuery, getPolicyIDFromSearchQuery, @@ -921,6 +998,7 @@ export { isCannedSearchQueryWithPolicyIDCheck, sanitizeSearchValue, getQueryWithUpdatedValues, + getQueryWithUpdatedValuesWithoutPolicy, getCurrentSearchQueryJSON, getUserFriendlyKey, isDefaultExpensesQuery, diff --git a/tests/unit/Search/buildSubstitutionsMapTest.ts b/tests/unit/Search/buildSubstitutionsMapTest.ts index 2761d62ca282..f07a9de00cc6 100644 --- a/tests/unit/Search/buildSubstitutionsMapTest.ts +++ b/tests/unit/Search/buildSubstitutionsMapTest.ts @@ -69,14 +69,14 @@ describe('buildSubstitutionsMap should return correct substitutions map', () => test('when there were no substitutions', () => { const userQuery = 'foo bar'; - const result = buildSubstitutionsMap(userQuery, personalDetailsMock, reportsMock, taxRatesMock, {}, cardFeedNamesWithTypeMock); + const result = buildSubstitutionsMap(userQuery, personalDetailsMock, reportsMock, taxRatesMock, {}, cardFeedNamesWithTypeMock, {}); expect(result).toStrictEqual({}); }); test('when query has a single substitution', () => { const userQuery = 'foo from:12345'; - const result = buildSubstitutionsMap(userQuery, personalDetailsMock, reportsMock, taxRatesMock, {}, cardFeedNamesWithTypeMock); + const result = buildSubstitutionsMap(userQuery, personalDetailsMock, reportsMock, taxRatesMock, {}, cardFeedNamesWithTypeMock, {}); expect(result).toStrictEqual({ 'from:John Doe': '12345', @@ -86,7 +86,7 @@ describe('buildSubstitutionsMap should return correct substitutions map', () => test('when query has multiple substitutions of different types', () => { const userQuery = 'from:78901,12345 to:nonExistingGuy@mail.com cardID:11223344 in:rep123 taxRate:id_TAX_1 feed:"11111111_Expensify Card"'; - const result = buildSubstitutionsMap(userQuery, personalDetailsMock, reportsMock, taxRatesMock, cardListMock, cardFeedNamesWithTypeMock); + const result = buildSubstitutionsMap(userQuery, personalDetailsMock, reportsMock, taxRatesMock, cardListMock, cardFeedNamesWithTypeMock, {}); expect(result).toStrictEqual({ 'from:Jane Doe': '78901',