Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
162 commits
Select commit Hold shift + click to select a range
cab0ba1
change clear to reset
bernhardoj Jul 15, 2026
6ed5a0a
keyed the saved search with an ID
bernhardoj Jul 15, 2026
40c63f0
highlight the menu based on the search key
bernhardoj Jul 16, 2026
c85e5ca
fallback the initial highlight from the search filters or saved searc…
bernhardoj Jul 17, 2026
a4590af
open the last query for each search key
bernhardoj Jul 17, 2026
df11952
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 18, 2026
9bec142
fix type
bernhardoj Jul 18, 2026
ee33d22
set back with the correct value when being invalidated
bernhardoj Jul 18, 2026
a1d3ec2
don't show close filter button for default filter
bernhardoj Jul 18, 2026
977c959
show the default filters first
bernhardoj Jul 18, 2026
a139245
only show reset filters when there is non-default filters
bernhardoj Jul 19, 2026
c2096ac
remove unused import
bernhardoj Jul 19, 2026
f921aaf
fix reset filter doesn't show
bernhardoj Jul 19, 2026
473f8c6
reset only the non default filters
bernhardoj Jul 19, 2026
e91679e
improve invalidating the search key
bernhardoj Jul 20, 2026
e3644d1
reset search key when invalid
bernhardoj Jul 20, 2026
1680c3c
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 20, 2026
5c0945a
remove removed key
bernhardoj Jul 20, 2026
56ee784
lint
bernhardoj Jul 20, 2026
59c8490
fix test
bernhardoj Jul 20, 2026
e4169f9
mssing default
bernhardoj Jul 20, 2026
3f55e76
invalidate search key when applying the filters
bernhardoj Jul 20, 2026
186d27e
keep the latest default filter key value
bernhardoj Jul 20, 2026
60e4f39
remove checking type because it's already covered by isRootFilterKey
bernhardoj Jul 20, 2026
d0b5f81
update test
bernhardoj Jul 20, 2026
2b4af90
allow the component to reset the search key directly
bernhardoj Jul 20, 2026
948de5f
remove unused value
bernhardoj Jul 20, 2026
e3f2300
show reset filters when it's different from the default filters
bernhardoj Jul 20, 2026
fc58333
handle the reset logic for filter without default values
bernhardoj Jul 21, 2026
e1237d3
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 21, 2026
71095b7
replace isSupersetOf
bernhardoj Jul 21, 2026
ed52822
fix typing error
bernhardoj Jul 21, 2026
ae21074
remove unintended comments
bernhardoj Jul 21, 2026
91984f8
compare the hash
bernhardoj Jul 21, 2026
56b7e59
lint
bernhardoj Jul 21, 2026
54b3365
fix test
bernhardoj Jul 21, 2026
df45c7c
sort alphabetically
bernhardoj Jul 21, 2026
3e48ce7
fix test
bernhardoj Jul 21, 2026
65c8fc4
reset key when type changes too
bernhardoj Jul 21, 2026
7671150
don't trigger search when the search key changes
bernhardoj Jul 21, 2026
e720ed6
lint to reduce rerender
bernhardoj Jul 21, 2026
40f4132
rename back
bernhardoj Jul 21, 2026
c7f8ec3
pass id as param
bernhardoj Jul 21, 2026
43e679d
fix initial current search key ignores the default query when there i…
bernhardoj Jul 21, 2026
839821b
add tests
bernhardoj Jul 21, 2026
b64350b
change current search key when saving search
bernhardoj Jul 21, 2026
b82469a
lint
bernhardoj Jul 21, 2026
58cf492
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 22, 2026
a095652
fix invalid query is applied for selected search
bernhardoj Jul 22, 2026
ad10a12
show reset filter only when the flat filters is different (ignore key…
bernhardoj Jul 22, 2026
b9cba35
rename
bernhardoj Jul 22, 2026
0056061
fix mismatch beween search key and search query
bernhardoj Jul 22, 2026
b365358
remove unused function
bernhardoj Jul 22, 2026
4dc2449
fix type
bernhardoj Jul 22, 2026
131f089
update test
bernhardoj Jul 22, 2026
4abc231
remove unused var
bernhardoj Jul 22, 2026
e01cfc8
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 23, 2026
4cbd2df
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 23, 2026
86d5539
add test
bernhardoj Jul 23, 2026
dc345f6
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 24, 2026
08da6e0
lint
bernhardoj Jul 24, 2026
69ab4c5
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 25, 2026
b816864
fix renaming saved search create a new saved search entry
bernhardoj Jul 25, 2026
0ee0699
delete last filter query when deleting the saved search
bernhardoj Jul 25, 2026
528f537
show not found when saved search doesn't exist
bernhardoj Jul 25, 2026
b331428
lint
bernhardoj Jul 25, 2026
f375596
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 28, 2026
66130b1
use the last query
bernhardoj Jul 28, 2026
a8fcfed
use hash as the id
bernhardoj Jul 28, 2026
9352fa9
don't reset search key when hash stays the same
bernhardoj Jul 28, 2026
0729882
lint
bernhardoj Jul 28, 2026
2705e36
add and fix test
bernhardoj Jul 28, 2026
87fbac8
fix type
bernhardoj Jul 28, 2026
33d4cb7
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 29, 2026
84e444b
lint
bernhardoj Jul 29, 2026
31281ea
remove extra param
bernhardoj Jul 29, 2026
546142c
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 30, 2026
46a742f
fix after conflict
bernhardoj Jul 30, 2026
a8e4d2d
simplify
bernhardoj Jul 30, 2026
a56e12c
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Jul 31, 2026
20042c9
fix test
bernhardoj Jul 31, 2026
ef4d3c3
lint
bernhardoj Jul 31, 2026
92b19bf
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 3, 2026
cbbb683
lint
bernhardoj Aug 3, 2026
4fbe594
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 4, 2026
5bb43a0
don't reset display-related and keyword
bernhardoj Aug 4, 2026
af21214
lint
bernhardoj Aug 4, 2026
e6c0b10
hide apply button when all items are selected for default filters
bernhardoj Aug 4, 2026
0a170a9
allow all saved search filters to be removed
bernhardoj Aug 4, 2026
47a0a19
remove unused return and update tests
bernhardoj Aug 4, 2026
94f5fca
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 4, 2026
84adbdb
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 6, 2026
29c78db
lint
bernhardoj Aug 6, 2026
4b6986b
add log
bernhardoj Aug 6, 2026
c6718b0
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 7, 2026
75a14a3
fallback to expensify card id
bernhardoj Aug 7, 2026
beb9149
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 8, 2026
3c7bffc
remove log
bernhardoj Aug 8, 2026
908ceb2
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 19, 2026
362f6d2
fix test
bernhardoj Aug 19, 2026
300c35a
lint
bernhardoj Aug 19, 2026
12fe757
fix type
bernhardoj Aug 19, 2026
37548e1
lint
bernhardoj Aug 19, 2026
1d3bc95
fix test
bernhardoj Aug 19, 2026
c448181
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 19, 2026
5ecc90f
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 21, 2026
1791bd8
add comment
bernhardoj Aug 21, 2026
6e72596
rename and refactor a bit
bernhardoj Aug 21, 2026
eba2d38
add back the pending delete check
bernhardoj Aug 21, 2026
bec4c91
fix type
bernhardoj Aug 21, 2026
f1e1a44
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 21, 2026
e31885d
new searchFilters structure
bernhardoj Aug 21, 2026
eb88cab
lint
bernhardoj Aug 22, 2026
b9ce0be
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 24, 2026
ffc6b72
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Aug 25, 2026
3c18225
fix test
bernhardoj Aug 25, 2026
212f70c
fix type
bernhardoj Aug 25, 2026
0f49d6e
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 1, 2026
79a55e0
rename import
bernhardoj Sep 1, 2026
bb6cf04
fix type
bernhardoj Sep 1, 2026
1b63e23
fix test
bernhardoj Sep 1, 2026
46a2054
lint
bernhardoj Sep 1, 2026
5c9ad9b
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 2, 2026
4f080c2
fix test
bernhardoj Sep 2, 2026
39cde3e
fix test
bernhardoj Sep 2, 2026
f6917b4
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 2, 2026
315cf1d
added back removed code
bernhardoj Sep 2, 2026
bd47800
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 3, 2026
2e74231
fix test
bernhardoj Sep 3, 2026
0fc6030
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 5, 2026
67fa4d4
use full hash to compare saved search query
bernhardoj Sep 5, 2026
b064aba
parse the updated query instead of the raw
bernhardoj Sep 5, 2026
39a7f78
pass shouldShowExpensifyCard
bernhardoj Sep 5, 2026
924d0f4
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 8, 2026
2d25140
show reset filter when filter chip is visible
bernhardoj Sep 8, 2026
7dac527
change searchkey to expense after deleting a saved search
bernhardoj Sep 8, 2026
51f6eb4
check if we should pending in one place
bernhardoj Sep 8, 2026
88a6bb7
fix test
bernhardoj Sep 8, 2026
5efcdf3
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 8, 2026
0103288
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 8, 2026
32ece1b
add search filters fallback for getSearchTabRoute
bernhardoj Sep 8, 2026
0950bbb
remove unnecessary param
bernhardoj Sep 8, 2026
c4de65b
update coment
bernhardoj Sep 8, 2026
72a0677
update prop name
bernhardoj Sep 8, 2026
927cde0
update type
bernhardoj Sep 8, 2026
24f09a5
dupe key
bernhardoj Sep 8, 2026
4c82059
move to outside component
bernhardoj Sep 8, 2026
9feebd8
rename
bernhardoj Sep 8, 2026
f015707
update type
bernhardoj Sep 8, 2026
3dbb380
rename
bernhardoj Sep 8, 2026
be401e9
fix test
bernhardoj Sep 8, 2026
8dee3e0
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 9, 2026
baf4246
lint
bernhardoj Sep 9, 2026
6a17eec
fix mock test
bernhardoj Sep 9, 2026
2c6ebbc
Merge branch 'main' into feat/95976-persist-filters-across-search
bernhardoj Sep 9, 2026
b8c9004
fix pressing Spend tab item doesn't open the last search route
bernhardoj Sep 9, 2026
d637e70
add test
bernhardoj Sep 9, 2026
c0b8ab7
rename
bernhardoj Sep 9, 2026
92eafbd
add null safety
bernhardoj Sep 10, 2026
e073105
make it consistent
bernhardoj Sep 10, 2026
55d3427
open the last expenses query when deleting active saved search
bernhardoj Sep 10, 2026
5f52b8d
update test
bernhardoj Sep 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8910,7 +8910,7 @@ const CONST = {
TYPE_MENU_ITEM: 'Search-TypeMenuItem',
SAVED_SEARCH_MENU_ITEM: 'Search-SavedSearchMenuItem',
SAVE_VIEW_BUTTON: 'Search-SaveViewButton',
CLEAR_FILTERS_BUTTON: 'Search-ClearFiltersButton',
RESET_FILTERS_BUTTON: 'Search-ResetFiltersButton',
ACTION_CELL_VIEW: 'Search-ActionCellView',
ACTION_CELL_PAY: 'Search-ActionCellPay',
ACTION_CELL_ACTION: 'Search-ActionCellAction',
Expand Down Expand Up @@ -9755,18 +9755,6 @@ const SUBMIT_FEATURE_IDS: ReadonlySet<string> = new Set([
CONST.UPGRADE_FEATURE_INTRO_MAPPING.invoicing.id,
]);

type SearchFilterKey = ValueOf<typeof CONST.SEARCH.SYNTAX_FILTER_KEYS> | ValueOf<typeof CONST.SEARCH.SYNTAX_ROOT_KEYS>;

const CONTINUATION_DETECTION_SEARCH_FILTER_KEYS = [
CONST.SEARCH.SYNTAX_FILTER_KEYS.TO,
CONST.SEARCH.SYNTAX_FILTER_KEYS.FROM,
CONST.SEARCH.SYNTAX_FILTER_KEYS.ASSIGNEE,
CONST.SEARCH.SYNTAX_FILTER_KEYS.PAYER,
CONST.SEARCH.SYNTAX_FILTER_KEYS.PAID_BY,
CONST.SEARCH.SYNTAX_FILTER_KEYS.EXPORTER,
CONST.SEARCH.SYNTAX_FILTER_KEYS.ATTENDEE,
] as SearchFilterKey[];

const FRAUD_PROTECTION_EVENT = {
START_SUPPORT_SESSION: 'StartSupportSession',
STOP_SUPPORT_SESSION: 'StopSupportSession',
Expand Down Expand Up @@ -9835,6 +9823,6 @@ export type {
EnablePaymentsSubPageType,
};

export {CONTINUATION_DETECTION_SEARCH_FILTER_KEYS, FRAUD_PROTECTION_EVENT, COUNTRIES_US_BANK_FLOW, SUBMIT_FEATURE_IDS};
export {FRAUD_PROTECTION_EVENT, COUNTRIES_US_BANK_FLOW, SUBMIT_FEATURE_IDS};

export default CONST;
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,9 @@ const ONYXKEYS = {
/** Stores the information about the recent searches */
RECENT_SEARCHES: 'nvp_recentSearches',

/** Stores the last query for each suggested/saved search */
SEARCH_FILTERS: 'nvp_searchFilters',

/** Stores the current search page context (e.g., whether to show the search query) */
SEARCH_CONTEXT: 'searchContext',

Expand Down Expand Up @@ -1581,6 +1584,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.NVP_TRY_NEW_DOT]: OnyxTypes.TryNewDot;
[ONYXKEYS.RECENT_SEARCHES]: Record<string, OnyxTypes.RecentSearchItem>;
[ONYXKEYS.SAVED_SEARCHES]: OnyxTypes.SaveSearch;
[ONYXKEYS.SEARCH_FILTERS]: OnyxTypes.SearchFilters;
[ONYXKEYS.NVP_HAS_SEEDED_MY_EXPENSES_SEARCH]: boolean;
[ONYXKEYS.SEARCH_CONTEXT]: OnyxTypes.SearchContext;
[ONYXKEYS.SEARCH_FOOTER_CONVERSION]: OnyxTypes.SearchFooterConversion;
Expand Down
4 changes: 2 additions & 2 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1958,8 +1958,8 @@ const ROUTES = {
},
SEARCH_SAVE: 'search/save',
SEARCH_SAVED_SEARCH_RENAME: {
route: 'search/saved-search/rename',
getRoute: ({name, jsonQuery}: {name: string; jsonQuery: SearchQueryString}) => `search/saved-search/rename?name=${name}&q=${encodeURIComponent(jsonQuery)}` as const,
route: 'search/saved-search/rename/:id',
getRoute: (id: string) => `search/saved-search/rename/${id}` as const,
},
SEARCH_COLUMNS: 'search/columns',
SEARCH_ADVANCED_FILTERS: 'search/filters',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ function MoneyReportHeaderSecondaryActionsInner({reportID, primaryAction, isRepo
const {showDelegateNoAccessModal} = useDelegateNoAccessActions();
const {currentSearchQueryJSON, currentSearchKey} = useSearchQueryContext();
const {currentSearchResults} = useSearchResultsContext();
const shouldCalculateTotals = useSearchShouldCalculateTotals(currentSearchKey, currentSearchQueryJSON?.hash, true);
const shouldCalculateTotals = useSearchShouldCalculateTotals(currentSearchKey, true);

const isInvoiceReport = isInvoiceReportUtil(moneyRequestReport);
const isAnyTransactionOnHold = hasHeldExpensesReportUtils(allTransactions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function PayPrimaryAction({reportID, chatReportID}: PayPrimaryActionProps) {

const {currentSearchQueryJSON, currentSearchKey} = useSearchQueryContext();
const {currentSearchResults} = useSearchResultsContext();
const shouldCalculateTotals = useSearchShouldCalculateTotals(currentSearchKey, currentSearchQueryJSON?.hash, true);
const shouldCalculateTotals = useSearchShouldCalculateTotals(currentSearchKey, true);

const {openHoldMenu} = useMoneyReportHeaderModals();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function SubmitPrimaryActionContent({reportID}: SubmitPrimaryActionProps) {

const {currentSearchQueryJSON, currentSearchKey} = useSearchQueryContext();
const {currentSearchResults} = useSearchResultsContext();
const shouldCalculateTotals = useSearchShouldCalculateTotals(currentSearchKey, currentSearchQueryJSON?.hash, true);
const shouldCalculateTotals = useSearchShouldCalculateTotals(currentSearchKey, true);

const expensifyIcons = useMemoizedLazyExpensifyIcons(['Send', 'Document']);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import navigationRef from '@navigation/navigationRef';

import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import {lastExpensesSearchQuerySelector} from '@src/selectors/SearchFilters';

import type {ValueOf} from 'type-fest';

Expand All @@ -34,6 +35,7 @@ function SearchTabButton({selectedTab, isWideLayout}: SearchTabButtonProps) {
const {translate} = useLocalize();
const expensifyIcons = useMemoizedLazyExpensifyIcons(['ReceiptMultiple']);
const [lastSearchParams] = useOnyx(ONYXKEYS.REPORT_NAVIGATION_LAST_SEARCH_QUERY);
const [lastExpensesSearchQuery] = useOnyx(ONYXKEYS.SEARCH_FILTERS, {selector: lastExpensesSearchQuerySelector});
const searchAccessibilityState = {selected: selectedTab === NAVIGATION_TABS.SEARCH};

const navigateToSearch = () => {
Expand All @@ -49,7 +51,7 @@ function SearchTabButton({selectedTab, isWideLayout}: SearchTabButtonProps) {
});
startNavigateToReportsSpans();

Navigation.navigate(getSearchTabRoute(navigationRef.getRootState(), lastSearchParams));
Navigation.navigate(getSearchTabRoute(navigationRef.getRootState(), lastSearchParams, lastExpensesSearchQuery));
});
};

Expand Down
4 changes: 2 additions & 2 deletions src/components/Navigation/NavigationTabBar/getLastRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ function getLastRoute(rootState: NavigationState, navigator: ValueOf<typeof NAVI
return false;
}
const tabState = getTabState(route);
return tabState?.routes?.[tabState.index ?? 0]?.name === navigator;
return tabState?.routes?.findLast((tabRoute) => tabRoute.state && tabRoute.name === navigator);
});
if (!rootTabRoute) {
rootTabRoute = rootState.routes.findLast((route) => route.name === NAVIGATORS.TAB_NAVIGATOR);
}
const tabState = getTabState(rootTabRoute);
lastNavigatorKey = tabState?.routes?.findLast((route) => route.name === navigator)?.key;
lastNavigatorKey = tabState?.routes?.findLast((route) => route.state && route.name === navigator)?.key;
}

const lastNavigatorState = lastNavigatorKey ? getPreservedNavigatorState(lastNavigatorKey) : undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Resolves the route used to restore the latest Spend search.
*/
import {buildCannedSearchQuery, buildSearchQueryJSON, buildSearchQueryString, isSearchRootParams} from '@libs/SearchQueryUtils';
import {buildCannedSearchQuery, buildSearchQueryJSON, buildSearchQueryString, getValidLastQuery, isSearchRootParams} from '@libs/SearchQueryUtils';

import CONST from '@src/CONST';
import NAVIGATORS from '@src/NAVIGATORS';
Expand All @@ -14,7 +14,7 @@ import type {OnyxEntry} from 'react-native-onyx';

import getLastRoute from './getLastRoute';

function getSearchTabRoute(rootState: NavigationState, lastSearchParams: OnyxEntry<LastSearchParams>) {
function getSearchTabRoute(rootState: NavigationState, lastSearchParams: OnyxEntry<LastSearchParams>, lastExpensesSearchQuery: string | undefined) {
const lastSearchRoute = getLastRoute(rootState, NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR, SCREENS.SEARCH.ROOT);

if (isSearchRootParams(lastSearchRoute?.params)) {
Expand All @@ -31,7 +31,8 @@ function getSearchTabRoute(rootState: NavigationState, lastSearchParams: OnyxEnt
const lastQueryJSON = lastSearchParams?.queryJSON;
const lastQueryFromOnyx = lastQueryJSON ? buildSearchQueryString(lastQueryJSON) : undefined;
const defaultSearchQuery = buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.EXPENSE});
return ROUTES.SEARCH_ROOT.getRoute({query: lastQueryFromOnyx ?? defaultSearchQuery});
const fallbackSearchQuery = getValidLastQuery(lastExpensesSearchQuery, defaultSearchQuery);
return ROUTES.SEARCH_ROOT.getRoute({query: lastQueryFromOnyx ?? fallbackSearchQuery});
}

export default getSearchTabRoute;
5 changes: 2 additions & 3 deletions src/components/Navigation/SearchSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SidebarRightIcon from '@assets/images/sidebar-right.svg';
import Hoverable from '@components/Hoverable';
import Icon from '@components/Icon';
import {PressableWithoutFeedback} from '@components/Pressable';
import {useSearchQueryContext, useSearchResultsActions, useSearchResultsContext} from '@components/Search/SearchContext';
import {useSearchResultsActions, useSearchResultsContext} from '@components/Search/SearchContext';
import Tooltip from '@components/Tooltip';

import {useLoadingBarVisibility} from '@hooks/useInFlightRequests';
Expand Down Expand Up @@ -57,7 +57,6 @@ function SearchSidebar({state}: SearchSidebarProps) {

const route = state.routes.at(-1);
const {lastSearchType, currentSearchResults} = useSearchResultsContext();
const {currentSearchQueryJSON} = useSearchQueryContext();
const {setLastSearchType} = useSearchResultsActions();

const searchType = currentSearchResults?.search?.type;
Expand Down Expand Up @@ -122,7 +121,7 @@ function SearchSidebar({state}: SearchSidebarProps) {
</TopBar>
<Hoverable onHoverIn={startPeek}>
<View style={styles.flex1}>
<SearchTypeMenuWide queryJSON={currentSearchQueryJSON} />
<SearchTypeMenuWide />
</View>
</Hoverable>
</View>
Expand Down
19 changes: 11 additions & 8 deletions src/components/Search/FilterDropdowns/BasePopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import ActionButtons from './ActionButtons';
type BasePopupProps = React.PropsWithChildren & {
label?: string;
showLabel?: boolean;
shouldShowActionButtons?: boolean;
applySentryLabel: string;
resetSentryLabel?: string;
style?: StyleProp<ViewStyle>;
Expand All @@ -22,7 +23,7 @@ type BasePopupProps = React.PropsWithChildren & {
onBackButtonPress?: () => void;
};

function BasePopup({children, label, applySentryLabel, resetSentryLabel, showLabel, style, onApply, onReset, onBackButtonPress}: BasePopupProps) {
function BasePopup({children, label, applySentryLabel, resetSentryLabel, showLabel, shouldShowActionButtons = true, style, onApply, onReset, onBackButtonPress}: BasePopupProps) {
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {isSmallScreenWidth} = useResponsiveLayout();
const styles = useThemeStyles();
Expand All @@ -42,13 +43,15 @@ function BasePopup({children, label, applySentryLabel, resetSentryLabel, showLab
shouldDisplayLabel && <Text style={[styles.textLabel, styles.textSupporting, styles.ph5, styles.pv1, styles.mb2]}>{label}</Text>
)}
{children}
<ActionButtons
containerStyle={[styles.flexRow, styles.gap2, styles.ph5, styles.mt2]}
onReset={onReset}
onApply={onApply}
applySentryLabel={applySentryLabel}
resetSentryLabel={resetSentryLabel}
/>
{shouldShowActionButtons && (
<ActionButtons
containerStyle={[styles.flexRow, styles.gap2, styles.ph5, styles.mt2]}
onReset={onReset}
onApply={onApply}
applySentryLabel={applySentryLabel}
resetSentryLabel={resetSentryLabel}
/>
)}
</View>
);
}
Expand Down
4 changes: 3 additions & 1 deletion src/components/Search/FilterDropdowns/ListPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import type {PopoverComponentProps} from './FilterPopupButton';
import BasePopup from './BasePopup';

type ListPopupProps = Pick<ListFilterContentProps, 'baseFilterKey'> & {
isDefault: boolean;
values: Partial<SearchAdvancedFiltersForm> | undefined;
label: string;
closeOverlay: PopoverComponentProps['closeOverlay'];
updateFilterForm: (value: Partial<SearchAdvancedFiltersForm>) => void;
};

function ListPopup({baseFilterKey, values, label, updateFilterForm, closeOverlay}: ListPopupProps) {
function ListPopup({baseFilterKey, isDefault, values, label, updateFilterForm, closeOverlay}: ListPopupProps) {
const {isNegated: initialIsNegated, value: initialValue} = getFilterNegatableValue(baseFilterKey, values);
const [value, setValue] = useState(initialValue);
const [isNegated, setIsNegated] = useState(initialIsNegated);
Expand All @@ -34,6 +35,7 @@ function ListPopup({baseFilterKey, values, label, updateFilterForm, closeOverlay
<BasePopup
label={label}
onApply={applyChanges}
shouldShowActionButtons={!isDefault || !!value?.length}
applySentryLabel={`Search-FilterPopupApply-${baseFilterKey}`}
>
<ListFilterContent
Expand Down
5 changes: 5 additions & 0 deletions src/components/Search/SearchContextDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CONST from '@src/CONST';
import React from 'react';

import type {
QueryFilterKey,
SearchQueryActionsValue,
SearchQueryContextValue,
SearchResultsActionsValue,
Expand All @@ -23,12 +24,16 @@ const defaultSearchQueryContext: SearchQueryContextValue = {
currentSimilarSearchHash: -1,
currentSearchKey: undefined,
currentSearchQueryJSON: undefined,
currentDefaultSearchQueryJSON: undefined,
currentDefaultSearchQueryFilterKeys: new Set<QueryFilterKey>(),
suggestedSearches: {} as Record<SearchKey, SearchTypeMenuItem>,
shouldResetSearchQuery: false,
};

const defaultSearchQueryActions: SearchQueryActionsValue = {
setShouldResetSearchQuery: () => {},
setCurrentSearchKey: () => {},
resetSearchKey: () => {},
};

const EMPTY_TRANSACTIONS_BY_REPORT_ID: SearchResultsContextValue['currentSearchTransactionsByReportID'] = new Map();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {FlatList} from 'react-native';
import type {FilterItem} from './useSearchFiltersBar';

import SearchFilterBar from './SearchFilterBar';
import SearchFiltersClearButton from './SearchFiltersClearButton';
import SearchFiltersResetButton from './SearchFiltersResetButton';
import useSearchFiltersBar from './useSearchFiltersBar';

type SearchFiltersBarNarrowProps = {
Expand All @@ -22,7 +22,7 @@ type SearchFiltersBarNarrowProps = {
function SearchFiltersBarNarrow({queryJSON}: SearchFiltersBarNarrowProps) {
const styles = useThemeStyles();
const scrollRef = useRef<FlatList<SearchFilter & FilterItem>>(null);
const {filters, hasErrors, shouldShowFiltersBarLoading, clearFilters} = useSearchFiltersBar(queryJSON);
const {filters, hasErrors, shouldShowFiltersBarLoading, shouldShowResetFilters, resetFilters} = useSearchFiltersBar(queryJSON);

const adjustScroll = (info: {distanceFromEnd: number}) => {
// Workaround for a known React Native bug on Android (https://github.com/facebook/react-native/issues/27504):
Expand Down Expand Up @@ -59,7 +59,7 @@ function SearchFiltersBarNarrow({queryJSON}: SearchFiltersBarNarrowProps) {
renderItem={renderFilterItem}
onEndReached={adjustScroll}
onEndReachedThreshold={0.75}
ListFooterComponent={filters.length > 0 ? <SearchFiltersClearButton onPress={clearFilters} /> : undefined}
ListFooterComponent={shouldShowResetFilters ? <SearchFiltersResetButton onPress={resetFilters} /> : undefined}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import SearchFiltersSkeleton from '@components/Skeletons/SearchFiltersSkeleton';
import React from 'react';

import SearchFilterBar from './SearchFilterBar';
import SearchFiltersClearButton from './SearchFiltersClearButton';
import SearchFiltersResetButton from './SearchFiltersResetButton';
import useSearchFiltersBar from './useSearchFiltersBar';

type SearchFiltersBarWideProps = {
queryJSON: SearchQueryJSON;
};

function SearchFiltersBarWide({queryJSON}: SearchFiltersBarWideProps) {
const {filters, hasErrors, shouldShowFiltersBarLoading, clearFilters} = useSearchFiltersBar(queryJSON);
const {filters, hasErrors, shouldShowFiltersBarLoading, shouldShowResetFilters, resetFilters} = useSearchFiltersBar(queryJSON);

if (hasErrors) {
return null;
Expand All @@ -30,7 +30,7 @@ function SearchFiltersBarWide({queryJSON}: SearchFiltersBarWideProps) {
item={item}
/>
))}
{filters.length > 0 && <SearchFiltersClearButton onPress={clearFilters} />}
{shouldShowResetFilters && <SearchFiltersResetButton onPress={resetFilters} />}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,32 @@ import CONST from '@src/CONST';

import React from 'react';

type SearchFiltersClearButtonProps = {
type SearchFiltersResetButtonProps = {
onPress: () => void;
};

function SearchFiltersClearButton({onPress}: SearchFiltersClearButtonProps) {
function SearchFiltersResetButton({onPress}: SearchFiltersResetButtonProps) {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Close']);
const expensifyIcons = useMemoizedLazyExpensifyIcons(['RotateLeft']);

return (
<PressableWithFeedback
accessibilityLabel={translate('common.clear')}
accessibilityLabel={translate('common.reset')}
onPress={onPress}
style={[styles.searchFiltersClearButton]}
style={[styles.searchFiltersResetButton]}
hoverStyle={styles.hoveredComponentBG}
sentryLabel={CONST.SENTRY_LABEL.SEARCH.CLEAR_FILTERS_BUTTON}
sentryLabel={CONST.SENTRY_LABEL.SEARCH.RESET_FILTERS_BUTTON}
>
<Icon
src={expensifyIcons.Close}
src={expensifyIcons.RotateLeft}
fill={theme.icon}
size={CONST.ICON_SIZE.EXTRA_SMALL}
/>
<Text style={[styles.textMicroBoldSupporting]}>{translate('common.clear')}</Text>
<Text style={[styles.textMicroBoldSupporting]}>{translate('common.reset')}</Text>
</PressableWithFeedback>
);
}

export default SearchFiltersClearButton;
export default SearchFiltersResetButton;
Loading
Loading