From dfc5d1d8d86c3fe481ca5b8ab54d8cd5b5da8a0a Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Wed, 31 Jul 2024 10:23:15 +0200 Subject: [PATCH 01/11] Add template of SearchFiltersCurrencyPage --- src/ROUTES.ts | 2 ++ src/SCREENS.ts | 1 + src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../ModalStackNavigators/index.tsx | 1 + .../CENTRAL_PANE_TO_RHP_MAPPING.ts | 10 +++++- src/libs/Navigation/linkingConfig/config.ts | 1 + src/pages/Search/AdvancedSearchFilters.tsx | 5 +++ .../Search/SearchFiltersCurrencyPage.tsx | 33 +++++++++++++++++++ 9 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/pages/Search/SearchFiltersCurrencyPage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 0811ea02e9d6..682dc954245c 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -47,6 +47,8 @@ const ROUTES = { SEARCH_ADVANCED_FILTERS_STATUS: 'search/filters/status', + SEARCH_ADVANCED_FILTERS_CURRENCY: 'search/filters/currency', + SEARCH_REPORT: { route: 'search/view/:reportID', getRoute: (reportID: string) => `search/view/${reportID}` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 4047b0a851bc..2424a684d998 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -35,6 +35,7 @@ const SCREENS = { ADVANCED_FILTERS_DATE_RHP: 'Search_Advanced_Filters_Date_RHP', ADVANCED_FILTERS_TYPE_RHP: 'Search_Advanced_Filters_Type_RHP', ADVANCED_FILTERS_STATUS_RHP: 'Search_Advanced_Filters_Status_RHP', + ADVANCED_FILTERS_CURRENCY_RHP: 'Search_Advanced_Filters_Currency_RHP', TRANSACTION_HOLD_REASON_RHP: 'Search_Transaction_Hold_Reason_RHP', BOTTOM_TAB: 'Search_Bottom_Tab', }, diff --git a/src/languages/en.ts b/src/languages/en.ts index 67354e7ea30a..3812aae21bf6 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3610,6 +3610,7 @@ export default { after: (date?: string) => `After ${date ?? ''}`, }, status: 'Status', + currency: 'Currency', }, }, genericErrorPage: { diff --git a/src/languages/es.ts b/src/languages/es.ts index 7a92d4d1217d..b94758a0a4f9 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3667,6 +3667,7 @@ export default { after: (date?: string) => `Después de ${date ?? ''}`, }, status: 'Estado', + currency: 'Divisa', }, }, genericErrorPage: { diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index f3fc8accb83f..3183c7fccd91 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -514,6 +514,7 @@ const SearchAdvancedFiltersModalStackNavigator = createModalStackNavigator require('../../../../pages/Search/SearchFiltersDatePage').default, [SCREENS.SEARCH.ADVANCED_FILTERS_TYPE_RHP]: () => require('../../../../pages/Search/SearchFiltersTypePage').default, [SCREENS.SEARCH.ADVANCED_FILTERS_STATUS_RHP]: () => require('../../../../pages/Search/SearchFiltersStatusPage').default, + [SCREENS.SEARCH.ADVANCED_FILTERS_CURRENCY_RHP]: () => require('../../../../pages/Search/SearchFiltersCurrencyPage').default, }); const RestrictedActionModalStackNavigator = createModalStackNavigator({ diff --git a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts index 8aa259b769b0..ec783def25e8 100755 --- a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts @@ -38,7 +38,15 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial> = [SCREENS.SETTINGS.ABOUT]: [SCREENS.SETTINGS.APP_DOWNLOAD_LINKS], [SCREENS.SETTINGS.SAVE_THE_WORLD]: [SCREENS.I_KNOW_A_TEACHER, SCREENS.INTRO_SCHOOL_PRINCIPAL, SCREENS.I_AM_A_TEACHER], [SCREENS.SETTINGS.TROUBLESHOOT]: [SCREENS.SETTINGS.CONSOLE], - [SCREENS.SEARCH.CENTRAL_PANE]: [SCREENS.SEARCH.REPORT_RHP, SCREENS.SEARCH.TRANSACTION_HOLD_REASON_RHP, SCREENS.SEARCH.ADVANCED_FILTERS_RHP], + [SCREENS.SEARCH.CENTRAL_PANE]: [ + SCREENS.SEARCH.REPORT_RHP, + SCREENS.SEARCH.TRANSACTION_HOLD_REASON_RHP, + SCREENS.SEARCH.ADVANCED_FILTERS_RHP, + SCREENS.SEARCH.ADVANCED_FILTERS_CURRENCY_RHP, + SCREENS.SEARCH.ADVANCED_FILTERS_DATE_RHP, + SCREENS.SEARCH.ADVANCED_FILTERS_STATUS_RHP, + SCREENS.SEARCH.ADVANCED_FILTERS_TYPE_RHP, + ], [SCREENS.SETTINGS.SUBSCRIPTION.ROOT]: [ SCREENS.SETTINGS.SUBSCRIPTION.ADD_PAYMENT_CARD, SCREENS.SETTINGS.SUBSCRIPTION.SIZE, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index f2d1bfb36d7e..548065ee4370 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1017,6 +1017,7 @@ const config: LinkingOptions['config'] = { [SCREENS.SEARCH.ADVANCED_FILTERS_DATE_RHP]: ROUTES.SEARCH_ADVANCED_FILTERS_DATE, [SCREENS.SEARCH.ADVANCED_FILTERS_TYPE_RHP]: ROUTES.SEARCH_ADVANCED_FILTERS_TYPE, [SCREENS.SEARCH.ADVANCED_FILTERS_STATUS_RHP]: ROUTES.SEARCH_ADVANCED_FILTERS_STATUS, + [SCREENS.SEARCH.ADVANCED_FILTERS_CURRENCY_RHP]: ROUTES.SEARCH_ADVANCED_FILTERS_CURRENCY, }, }, [SCREENS.RIGHT_MODAL.RESTRICTED_ACTION]: { diff --git a/src/pages/Search/AdvancedSearchFilters.tsx b/src/pages/Search/AdvancedSearchFilters.tsx index eff58f140aa1..dd8f722a3341 100644 --- a/src/pages/Search/AdvancedSearchFilters.tsx +++ b/src/pages/Search/AdvancedSearchFilters.tsx @@ -68,6 +68,11 @@ function AdvancedSearchFilters() { description: 'common.date' as const, route: ROUTES.SEARCH_ADVANCED_FILTERS_DATE, }, + { + title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY, translate), + description: 'common.currency' as const, + route: ROUTES.SEARCH_ADVANCED_FILTERS_CURRENCY, + }, ], [searchAdvancedFilters, translate], ); diff --git a/src/pages/Search/SearchFiltersCurrencyPage.tsx b/src/pages/Search/SearchFiltersCurrencyPage.tsx new file mode 100644 index 000000000000..3abe4dc515cb --- /dev/null +++ b/src/pages/Search/SearchFiltersCurrencyPage.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import {useOnyx} from 'react-native-onyx'; +import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ScreenWrapper from '@components/ScreenWrapper'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import ONYXKEYS from '@src/ONYXKEYS'; + +function SearchFiltersCurrencyPage() { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + const [searchAdvancedFiltersForm] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM); + + return ( + + {({didScreenTransitionEnd}) => ( + + + + )} + + ); +} + +SearchFiltersCurrencyPage.displayName = 'SearchFiltersCurrencyPage'; + +export default SearchFiltersCurrencyPage; From df6ac241c6c311aae037a6bd6d089a1ce8bf3574 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Wed, 31 Jul 2024 12:15:02 +0200 Subject: [PATCH 02/11] Handle selecting multiple currencies --- .../CurrencySelectionList/index.tsx | 10 ++- src/components/CurrencySelectionList/types.ts | 6 ++ .../SelectionList/SelectableListItem.tsx | 86 +++++++++++++++++++ src/libs/SearchUtils.ts | 4 + src/pages/Search/AdvancedSearchFilters.tsx | 4 + .../Search/SearchFiltersCurrencyPage.tsx | 41 ++++++++- src/types/form/SearchAdvancedFiltersForm.ts | 2 + 7 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 src/components/SelectionList/SelectableListItem.tsx diff --git a/src/components/CurrencySelectionList/index.tsx b/src/components/CurrencySelectionList/index.tsx index bfe4578afd0f..20308eba41e9 100644 --- a/src/components/CurrencySelectionList/index.tsx +++ b/src/components/CurrencySelectionList/index.tsx @@ -3,18 +3,19 @@ import React, {useMemo, useState} from 'react'; import {withOnyx} from 'react-native-onyx'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; +import SelectableListItem from '@components/SelectionList/SelectableListItem'; import useLocalize from '@hooks/useLocalize'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import ONYXKEYS from '@src/ONYXKEYS'; import type {CurrencyListItem, CurrencySelectionListOnyxProps, CurrencySelectionListProps} from './types'; -function CurrencySelectionList({searchInputLabel, initiallySelectedCurrencyCode, onSelect, currencyList}: CurrencySelectionListProps) { +function CurrencySelectionList({searchInputLabel, initiallySelectedCurrencyCode, onSelect, currencyList, selectedCurrencies = [], canSelectMultiple = false}: CurrencySelectionListProps) { const [searchValue, setSearchValue] = useState(''); const {translate} = useLocalize(); const {sections, headerMessage} = useMemo(() => { const currencyOptions: CurrencyListItem[] = Object.entries(currencyList ?? {}).map(([currencyCode, currencyInfo]) => { - const isSelectedCurrency = currencyCode === initiallySelectedCurrencyCode; + const isSelectedCurrency = currencyCode === initiallySelectedCurrencyCode || selectedCurrencies.includes(currencyCode); return { currencyName: currencyInfo?.name ?? '', text: `${currencyCode} - ${CurrencyUtils.getCurrencySymbol(currencyCode)}`, @@ -38,12 +39,12 @@ function CurrencySelectionList({searchInputLabel, initiallySelectedCurrencyCode, ], headerMessage: isEmpty ? translate('common.noResultsFound') : '', }; - }, [currencyList, searchValue, translate, initiallySelectedCurrencyCode]); + }, [currencyList, searchValue, translate, initiallySelectedCurrencyCode, selectedCurrencies]); return ( ); } diff --git a/src/components/CurrencySelectionList/types.ts b/src/components/CurrencySelectionList/types.ts index eb7cf72d4e1e..9bfc31e10886 100644 --- a/src/components/CurrencySelectionList/types.ts +++ b/src/components/CurrencySelectionList/types.ts @@ -21,6 +21,12 @@ type CurrencySelectionListProps = CurrencySelectionListOnyxProps & { /** Callback to fire when a currency is selected */ onSelect: (item: CurrencyListItem) => void; + + /** The array of selected currencies. This prop should be used when multiple currencies can be selected */ + selectedCurrencies?: string[]; + + /** Whether this is a multi-select list */ + canSelectMultiple?: boolean; }; export type {CurrencyListItem, CurrencySelectionListProps, CurrencySelectionListOnyxProps}; diff --git a/src/components/SelectionList/SelectableListItem.tsx b/src/components/SelectionList/SelectableListItem.tsx new file mode 100644 index 000000000000..1370a6887a7a --- /dev/null +++ b/src/components/SelectionList/SelectableListItem.tsx @@ -0,0 +1,86 @@ +import React, {useCallback} from 'react'; +import {View} from 'react-native'; +import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; +import SelectCircle from '@components/SelectCircle'; +import TextWithTooltip from '@components/TextWithTooltip'; +import useThemeStyles from '@hooks/useThemeStyles'; +import CONST from '@src/CONST'; +import BaseListItem from './BaseListItem'; +import type {InviteMemberListItemProps, ListItem} from './types'; + +function SelectableListItem({ + item, + isFocused, + showTooltip, + isDisabled, + canSelectMultiple, + onSelectRow, + onCheckboxPress, + onDismissError, + onFocus, + shouldSyncFocus, +}: InviteMemberListItemProps) { + const styles = useThemeStyles(); + const handleCheckboxPress = useCallback(() => { + if (onCheckboxPress) { + onCheckboxPress(item); + } else { + onSelectRow(item); + } + }, [item, onCheckboxPress, onSelectRow]); + + return ( + + <> + + + + + + {!!item.rightElement && item.rightElement} + {canSelectMultiple && !item.isDisabled && ( + + + + )} + + + ); +} + +SelectableListItem.displayName = 'SelectableListItem'; + +export default SelectableListItem; diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts index 367f414eb53d..6c447e64a28f 100644 --- a/src/libs/SearchUtils.ts +++ b/src/libs/SearchUtils.ts @@ -402,6 +402,10 @@ function buildQueryStringFromFilters(filterValues: Partial 0) { + return `${CONST.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY}:${filterValue.join(',')}`; + } + return undefined; }) .filter(Boolean) diff --git a/src/pages/Search/AdvancedSearchFilters.tsx b/src/pages/Search/AdvancedSearchFilters.tsx index dd8f722a3341..8ff01fb6440a 100644 --- a/src/pages/Search/AdvancedSearchFilters.tsx +++ b/src/pages/Search/AdvancedSearchFilters.tsx @@ -36,6 +36,10 @@ function getFilterDisplayTitle(filters: Partial, fiel return dateValue; } + if (fieldName === CONST.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY) { + return filters.currency?.join(','); + } + // Todo Once all Advanced filters are implemented this line can be cleaned up. See: https://github.com/Expensify/App/issues/45026 // @ts-expect-error this property access is temporarily an error, because not every SYNTAX_FILTER_KEYS is handled by form. // When all filters are updated here: src/types/form/SearchAdvancedFiltersForm.ts this line comment + type cast can be removed. diff --git a/src/pages/Search/SearchFiltersCurrencyPage.tsx b/src/pages/Search/SearchFiltersCurrencyPage.tsx index 3abe4dc515cb..81782b2d2969 100644 --- a/src/pages/Search/SearchFiltersCurrencyPage.tsx +++ b/src/pages/Search/SearchFiltersCurrencyPage.tsx @@ -1,17 +1,37 @@ -import React from 'react'; +import React, {useState} from 'react'; import {useOnyx} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; +import CurrencySelectionList from '@components/CurrencySelectionList'; +import type {CurrencyListItem} from '@components/CurrencySelectionList/types'; +import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import {updateAdvancedFilters} from '@libs/actions/Search'; +import Navigation from '@libs/Navigation/Navigation'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; function SearchFiltersCurrencyPage() { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [searchAdvancedFiltersForm] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM); + const [selectedCurrencies, setSelectedCurrencies] = useState(searchAdvancedFiltersForm?.currency ?? []); + + const handleOnSelectOption = (option: CurrencyListItem) => { + if (selectedCurrencies.includes(option.currencyCode)) { + setSelectedCurrencies(selectedCurrencies.filter((currency) => currency !== option.currencyCode)); + return; + } + + setSelectedCurrencies([option.currencyCode, ...selectedCurrencies]); + }; + + const handleOnSubmit = () => { + updateAdvancedFilters({...searchAdvancedFiltersForm, currency: selectedCurrencies}); + Navigation.goBack(ROUTES.SEARCH_ADVANCED_FILTERS); + }; return ( ( + { + if (!didScreenTransitionEnd) { + return; + } + handleOnSelectOption(option); + }} + /> + )} diff --git a/src/types/form/SearchAdvancedFiltersForm.ts b/src/types/form/SearchAdvancedFiltersForm.ts index 3c9a64a06976..7fbc39427cd2 100644 --- a/src/types/form/SearchAdvancedFiltersForm.ts +++ b/src/types/form/SearchAdvancedFiltersForm.ts @@ -6,6 +6,7 @@ const INPUT_IDS = { STATUS: 'status', DATE_AFTER: 'dateAfter', DATE_BEFORE: 'dateBefore', + CURRENCY: 'currency', } as const; type InputID = ValueOf; @@ -17,6 +18,7 @@ type SearchAdvancedFiltersForm = Form< [INPUT_IDS.DATE_AFTER]: string; [INPUT_IDS.DATE_BEFORE]: string; [INPUT_IDS.STATUS]: string; + [INPUT_IDS.CURRENCY]: string[]; } >; From afc24aa7a888026efad01b95ba378ab21202a229 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Wed, 31 Jul 2024 12:23:10 +0200 Subject: [PATCH 03/11] Handle sorting currencies by isSelected --- src/components/CurrencySelectionList/index.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/CurrencySelectionList/index.tsx b/src/components/CurrencySelectionList/index.tsx index 20308eba41e9..63949d01b378 100644 --- a/src/components/CurrencySelectionList/index.tsx +++ b/src/components/CurrencySelectionList/index.tsx @@ -29,6 +29,16 @@ function CurrencySelectionList({searchInputLabel, initiallySelectedCurrencyCode, const filteredCurrencies = currencyOptions.filter((currencyOption) => searchRegex.test(currencyOption.text ?? '') || searchRegex.test(currencyOption.currencyName)); const isEmpty = searchValue.trim() && !filteredCurrencies.length; + if (canSelectMultiple) { + filteredCurrencies.sort(function (currencyA, currencyB) { + if (currencyA.isSelected === currencyB.isSelected) { + return 0; + } + + return currencyA.isSelected ? -1 : 1; + }); + } + return { sections: isEmpty ? [] @@ -39,7 +49,7 @@ function CurrencySelectionList({searchInputLabel, initiallySelectedCurrencyCode, ], headerMessage: isEmpty ? translate('common.noResultsFound') : '', }; - }, [currencyList, searchValue, translate, initiallySelectedCurrencyCode, selectedCurrencies]); + }, [currencyList, searchValue, canSelectMultiple, translate, initiallySelectedCurrencyCode, selectedCurrencies]); return ( Date: Fri, 2 Aug 2024 09:31:43 +0200 Subject: [PATCH 04/11] Cleanup selecting currencies --- src/components/CurrencySelectionList/index.tsx | 2 +- src/pages/Search/SearchFiltersCurrencyPage.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/CurrencySelectionList/index.tsx b/src/components/CurrencySelectionList/index.tsx index 63949d01b378..01a27ff5951a 100644 --- a/src/components/CurrencySelectionList/index.tsx +++ b/src/components/CurrencySelectionList/index.tsx @@ -30,7 +30,7 @@ function CurrencySelectionList({searchInputLabel, initiallySelectedCurrencyCode, const isEmpty = searchValue.trim() && !filteredCurrencies.length; if (canSelectMultiple) { - filteredCurrencies.sort(function (currencyA, currencyB) { + filteredCurrencies.sort((currencyA, currencyB) => { if (currencyA.isSelected === currencyB.isSelected) { return 0; } diff --git a/src/pages/Search/SearchFiltersCurrencyPage.tsx b/src/pages/Search/SearchFiltersCurrencyPage.tsx index 81782b2d2969..54d52b62df0f 100644 --- a/src/pages/Search/SearchFiltersCurrencyPage.tsx +++ b/src/pages/Search/SearchFiltersCurrencyPage.tsx @@ -8,7 +8,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import {updateAdvancedFilters} from '@libs/actions/Search'; +import * as SearchActions from '@libs/actions/Search'; import Navigation from '@libs/Navigation/Navigation'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -29,7 +29,7 @@ function SearchFiltersCurrencyPage() { }; const handleOnSubmit = () => { - updateAdvancedFilters({...searchAdvancedFiltersForm, currency: selectedCurrencies}); + SearchActions.updateAdvancedFilters({...searchAdvancedFiltersForm, currency: selectedCurrencies}); Navigation.goBack(ROUTES.SEARCH_ADVANCED_FILTERS); }; From 6685bd75483010ded60b399b64e9c4c68f470273 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Fri, 2 Aug 2024 10:00:18 +0200 Subject: [PATCH 05/11] Refactor getFilterDisplayTitle --- src/pages/Search/AdvancedSearchFilters.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pages/Search/AdvancedSearchFilters.tsx b/src/pages/Search/AdvancedSearchFilters.tsx index 6ad8400057e2..a8e54603d993 100644 --- a/src/pages/Search/AdvancedSearchFilters.tsx +++ b/src/pages/Search/AdvancedSearchFilters.tsx @@ -36,13 +36,9 @@ function getFilterDisplayTitle(filters: Partial, fiel return dateValue; } - if (fieldName === CONST.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY) { - return filters.currency?.join(','); - } - - if (fieldName === CONST.SEARCH.SYNTAX_FILTER_KEYS.CATEGORY && filters[fieldName]) { - const categories = filters[fieldName] ?? []; - return categories.join(', '); + if ((fieldName === CONST.SEARCH.SYNTAX_FILTER_KEYS.CATEGORY || fieldName === CONST.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY) && filters[fieldName]) { + const filterArray = filters[fieldName] ?? []; + return filterArray.join(', '); } // Todo Once all Advanced filters are implemented this line can be cleaned up. See: https://github.com/Expensify/App/issues/45026 From aab3fe48ff13e6e38a25e0809e076c474311098c Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Fri, 2 Aug 2024 13:13:14 +0200 Subject: [PATCH 06/11] Fix lint in ROUTES.ts --- src/ROUTES.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 796c60b7782b..7d4840ae707b 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -48,7 +48,7 @@ const ROUTES = { SEARCH_ADVANCED_FILTERS_STATUS: 'search/filters/status', SEARCH_ADVANCED_FILTERS_CURRENCY: 'search/filters/currency', - + SEARCH_ADVANCED_FILTERS_MERCHANT: 'search/filters/merchant', SEARCH_ADVANCED_FILTERS_DESCRIPTION: 'search/filters/description', From 72f97f20b145256bc6eeaf7ede7fd4a999455d03 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Fri, 2 Aug 2024 14:31:18 +0200 Subject: [PATCH 07/11] Fix displaying SearchStatusMenuNarrow title --- src/pages/Search/SearchStatusMenuNarrow.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Search/SearchStatusMenuNarrow.tsx b/src/pages/Search/SearchStatusMenuNarrow.tsx index 1d10dc1dd431..0192b45bcc8d 100644 --- a/src/pages/Search/SearchStatusMenuNarrow.tsx +++ b/src/pages/Search/SearchStatusMenuNarrow.tsx @@ -74,14 +74,14 @@ function SearchStatusMenuNarrow({statusMenuItems, activeItemIndex, title}: Searc > {({hovered}) => ( - + {menuTitle} From cd1be9625b3fd97c4f65077a54ed4029de0a06ac Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Fri, 2 Aug 2024 14:44:04 +0200 Subject: [PATCH 08/11] Fix margin of View results button --- src/pages/Search/AdvancedSearchFilters.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Search/AdvancedSearchFilters.tsx b/src/pages/Search/AdvancedSearchFilters.tsx index a8e54603d993..6e2a4746ff7d 100644 --- a/src/pages/Search/AdvancedSearchFilters.tsx +++ b/src/pages/Search/AdvancedSearchFilters.tsx @@ -132,7 +132,7 @@ function AdvancedSearchFilters() { From 6122ce8c637fdc162a462b04a78da3b02227f117 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Fri, 2 Aug 2024 16:10:23 +0200 Subject: [PATCH 09/11] Fix paddings on advanced filters screens --- src/pages/Search/AdvancedSearchFilters.tsx | 7 ++++--- src/pages/Search/SearchAdvancedFiltersPage.tsx | 1 + src/pages/Search/SearchFiltersCategoryPage.tsx | 3 ++- src/pages/Search/SearchFiltersCurrencyPage.tsx | 3 ++- src/pages/Search/SearchFiltersDatePage.tsx | 1 + src/pages/Search/SearchFiltersDescriptionPage.tsx | 3 ++- src/pages/Search/SearchFiltersMerchantPage.tsx | 3 ++- src/pages/Search/SearchFiltersReportIDPage.tsx | 3 ++- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/pages/Search/AdvancedSearchFilters.tsx b/src/pages/Search/AdvancedSearchFilters.tsx index 6e2a4746ff7d..740a144deb4a 100644 --- a/src/pages/Search/AdvancedSearchFilters.tsx +++ b/src/pages/Search/AdvancedSearchFilters.tsx @@ -5,6 +5,7 @@ import {useOnyx} from 'react-native-onyx'; import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; import type {LocaleContextProps} from '@components/LocaleContextProvider'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import ScrollView from '@components/ScrollView'; import type {AdvancedFiltersKeys} from '@components/Search/types'; import useLocalize from '@hooks/useLocalize'; import useSingleExecution from '@hooks/useSingleExecution'; @@ -114,7 +115,7 @@ function AdvancedSearchFilters() { }; return ( - + {advancedFilters.map((item) => { const onPress = singleExecution(waitForNavigate(() => Navigation.navigate(item.route))); @@ -132,11 +133,11 @@ function AdvancedSearchFilters() { - + ); } diff --git a/src/pages/Search/SearchAdvancedFiltersPage.tsx b/src/pages/Search/SearchAdvancedFiltersPage.tsx index 9d4864bce8eb..e24d2411226b 100644 --- a/src/pages/Search/SearchAdvancedFiltersPage.tsx +++ b/src/pages/Search/SearchAdvancedFiltersPage.tsx @@ -15,6 +15,7 @@ function SearchAdvancedFiltersPage() { testID={SearchAdvancedFiltersPage.displayName} shouldShowOfflineIndicatorInWideScreen offlineIndicatorStyle={styles.mtAuto} + includeSafeAreaPaddingBottom={false} > diff --git a/src/pages/Search/SearchFiltersCategoryPage.tsx b/src/pages/Search/SearchFiltersCategoryPage.tsx index 29a149482c81..8105bde2745c 100644 --- a/src/pages/Search/SearchFiltersCategoryPage.tsx +++ b/src/pages/Search/SearchFiltersCategoryPage.tsx @@ -126,6 +126,7 @@ function SearchFiltersCategoryPage() { testID={SearchFiltersCategoryPage.displayName} shouldShowOfflineIndicatorInWideScreen offlineIndicatorStyle={styles.mtAuto} + includeSafeAreaPaddingBottom={false} > - + {({didScreenTransitionEnd}) => ( @@ -55,7 +56,7 @@ function SearchFiltersCurrencyPage() { /> diff --git a/src/pages/Search/SearchFiltersDatePage.tsx b/src/pages/Search/SearchFiltersDatePage.tsx index 3cc19a501198..4bc95aa21351 100644 --- a/src/pages/Search/SearchFiltersDatePage.tsx +++ b/src/pages/Search/SearchFiltersDatePage.tsx @@ -34,6 +34,7 @@ function SearchFiltersDatePage() { testID={SearchFiltersDatePage.displayName} shouldShowOfflineIndicatorInWideScreen offlineIndicatorStyle={styles.mtAuto} + includeSafeAreaPaddingBottom={false} > - + - + - + Date: Mon, 5 Aug 2024 15:49:26 +0200 Subject: [PATCH 10/11] Fix displaying search header title --- src/libs/SearchUtils.ts | 2 +- src/pages/Search/SearchStatusMenuNarrow.tsx | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts index e7db1d9a636f..ae2393941ac9 100644 --- a/src/libs/SearchUtils.ts +++ b/src/libs/SearchUtils.ts @@ -500,7 +500,7 @@ function buildFilterString(filterName: string, queryFilters: QueryFilter[]) { queryFilters.forEach((queryFilter, index) => { // If the previous queryFilter has the same operator (this rule applies only to eq and neq operators) then append the current value if ((queryFilter.operator === 'eq' && queryFilters[index - 1]?.operator === 'eq') || (queryFilter.operator === 'neq' && queryFilters[index - 1]?.operator === 'neq')) { - filterValueString += `,${filterName}:${queryFilter.value}`; + filterValueString += `,${sanitizeString(queryFilter.value.toString())}`; } else { filterValueString += ` ${filterName}${operatorToSignMap[queryFilter.operator]}${queryFilter.value}`; } diff --git a/src/pages/Search/SearchStatusMenuNarrow.tsx b/src/pages/Search/SearchStatusMenuNarrow.tsx index cde92de052dd..8850b0fb2b0f 100644 --- a/src/pages/Search/SearchStatusMenuNarrow.tsx +++ b/src/pages/Search/SearchStatusMenuNarrow.tsx @@ -79,14 +79,12 @@ function SearchStatusMenuNarrow({statusMenuItems, activeItemIndex, title}: Searc src={menuIcon} fill={theme.icon} /> - - - {menuTitle} - - + + {menuTitle} + Date: Mon, 5 Aug 2024 15:50:18 +0200 Subject: [PATCH 11/11] Fix displaying description in getFilterDisplayTitle --- src/pages/Search/AdvancedSearchFilters.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/Search/AdvancedSearchFilters.tsx b/src/pages/Search/AdvancedSearchFilters.tsx index 740a144deb4a..1ff77776d5ca 100644 --- a/src/pages/Search/AdvancedSearchFilters.tsx +++ b/src/pages/Search/AdvancedSearchFilters.tsx @@ -42,6 +42,10 @@ function getFilterDisplayTitle(filters: Partial, fiel return filterArray.join(', '); } + if (fieldName === CONST.SEARCH.SYNTAX_FILTER_KEYS.DESCRIPTION) { + return filters[fieldName]; + } + // Todo Once all Advanced filters are implemented this line can be cleaned up. See: https://github.com/Expensify/App/issues/45026 // @ts-expect-error this property access is temporarily an error, because not every SYNTAX_FILTER_KEYS is handled by form. // When all filters are updated here: src/types/form/SearchAdvancedFiltersForm.ts this line comment + type cast can be removed.