Skip to content

Commit 2ea2b15

Browse files
authored
Merge pull request #49379 from software-mansion-labs/kicu/search-router-query
Add new SearchButton to all pages and tweak SearchRouter
2 parents a7a408f + 0f58dd9 commit 2ea2b15

29 files changed

+170
-175
lines changed

src/components/HeaderWithBackButton/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Icon from '@components/Icon';
77
import * as Expensicons from '@components/Icon/Expensicons';
88
import PinButton from '@components/PinButton';
99
import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback';
10+
import SearchButton from '@components/Search/SearchRouter/SearchButton';
1011
import ThreeDotsMenu from '@components/ThreeDotsMenu';
1112
import Tooltip from '@components/Tooltip';
1213
import useKeyboardState from '@hooks/useKeyboardState';
@@ -60,6 +61,7 @@ function HeaderWithBackButton({
6061
shouldOverlayDots = false,
6162
shouldOverlay = false,
6263
shouldNavigateToTopMostReport = false,
64+
shouldDisplaySearchRouter = false,
6365
progressBarPercentage,
6466
style,
6567
}: HeaderWithBackButtonProps) {
@@ -261,6 +263,7 @@ function HeaderWithBackButton({
261263
</PressableWithoutFeedback>
262264
</Tooltip>
263265
)}
266+
{shouldDisplaySearchRouter && <SearchButton />}
264267
</View>
265268
</View>
266269
</View>

src/components/HeaderWithBackButton/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ type HeaderWithBackButtonProps = Partial<ChildrenProps> & {
128128
/** Whether we should overlay the 3 dots menu */
129129
shouldOverlayDots?: boolean;
130130

131+
/** Whether we should display the button that opens new SearchRouter */
132+
shouldDisplaySearchRouter?: boolean;
133+
131134
/** 0 - 100 number indicating current progress of the progress bar */
132135
progressBarPercentage?: number;
133136

src/components/MoneyReportHeader.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
285285
report={moneyRequestReport}
286286
policy={policy}
287287
shouldShowBackButton={shouldUseNarrowLayout}
288+
shouldDisplaySearchRouter
288289
onBackButtonPress={onBackButtonPress}
289290
// Shows border if no buttons or banners are showing below the header
290291
shouldShowBorderBottom={!isMoreContentShown}

src/components/MoneyRequestHeader.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, shouldUseNarrow
133133
}}
134134
policy={policy}
135135
shouldShowBackButton={shouldUseNarrowLayout}
136+
shouldDisplaySearchRouter
136137
onBackButtonPress={onBackButtonPress}
137138
>
138139
{hasAllPendingRTERViolations && !shouldUseNarrowLayout && (

src/components/Search/SearchPageHeader.tsx

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type {SearchDataTypes, SearchReport} from '@src/types/onyx/SearchResults'
3333
import type DeepValueOf from '@src/types/utils/DeepValueOf';
3434
import type IconAsset from '@src/types/utils/IconAsset';
3535
import {useSearchContext} from './SearchContext';
36+
import SearchButton from './SearchRouter/SearchButton';
3637
import type {SearchQueryJSON} from './types';
3738

3839
type HeaderWrapperProps = Pick<HeaderWithBackButtonProps, 'title' | 'subtitle' | 'icon' | 'children'> & {
@@ -295,36 +296,41 @@ function SearchPageHeader({queryJSON, hash, onSelectDeleteOption, setOfflineModa
295296
}
296297

297298
const onPress = () => {
298-
const values = SearchUtils.getFiltersFormValues(queryJSON);
299+
const values = SearchUtils.buildFilterFormValuesFromQuery(queryJSON);
299300
SearchActions.updateAdvancedFilters(values);
300301
Navigation.navigate(ROUTES.SEARCH_ADVANCED_FILTERS);
301302
};
302303

304+
const displaySearchRouter = SearchUtils.isCannedSearchQuery(queryJSON);
305+
303306
return (
304307
<HeaderWrapper
305308
title={headerTitle}
306309
subtitle={headerSubtitle}
307310
icon={headerIcon}
308311
subtitleStyles={subtitleStyles}
309312
>
310-
{headerButtonsOptions.length > 0 ? (
311-
<ButtonWithDropdownMenu
312-
onPress={() => null}
313-
shouldAlwaysShowDropdownMenu
314-
pressOnEnter
315-
buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM}
316-
customText={translate('workspace.common.selected', {selectedNumber: selectedTransactionsKeys.length})}
317-
options={headerButtonsOptions}
318-
isSplitButton={false}
319-
shouldUseStyleUtilityForAnchorPosition
320-
/>
321-
) : (
322-
<Button
323-
text={translate('search.filtersHeader')}
324-
icon={Expensicons.Filters}
325-
onPress={onPress}
326-
/>
327-
)}
313+
<>
314+
{headerButtonsOptions.length > 0 ? (
315+
<ButtonWithDropdownMenu
316+
onPress={() => null}
317+
shouldAlwaysShowDropdownMenu
318+
pressOnEnter
319+
buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM}
320+
customText={translate('workspace.common.selected', {selectedNumber: selectedTransactionsKeys.length})}
321+
options={headerButtonsOptions}
322+
isSplitButton={false}
323+
shouldUseStyleUtilityForAnchorPosition
324+
/>
325+
) : (
326+
<Button
327+
text={translate('search.filtersHeader')}
328+
icon={Expensicons.Filters}
329+
onPress={onPress}
330+
/>
331+
)}
332+
{displaySearchRouter && <SearchButton />}
333+
</>
328334
</HeaderWrapper>
329335
);
330336
}

src/components/Search/SearchRouter/SearchButton.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import Icon from '@components/Icon';
33
import * as Expensicons from '@components/Icon/Expensicons';
44
import {PressableWithoutFeedback} from '@components/Pressable';
5+
import useLocalize from '@hooks/useLocalize';
56
import useTheme from '@hooks/useTheme';
67
import useThemeStyles from '@hooks/useThemeStyles';
78
import Permissions from '@libs/Permissions';
@@ -10,6 +11,7 @@ import {useSearchRouterContext} from './SearchRouterContext';
1011
function SearchButton() {
1112
const styles = useThemeStyles();
1213
const theme = useTheme();
14+
const {translate} = useLocalize();
1315
const {openSearchRouter} = useSearchRouterContext();
1416

1517
if (!Permissions.canUseNewSearchRouter()) {
@@ -18,8 +20,8 @@ function SearchButton() {
1820

1921
return (
2022
<PressableWithoutFeedback
21-
accessibilityLabel=""
22-
style={[styles.flexRow, styles.mr2, styles.touchableButtonImage]}
23+
accessibilityLabel={translate('common.search')}
24+
style={[styles.flexRow, styles.touchableButtonImage]}
2325
onPress={() => {
2426
openSearchRouter();
2527
}}

src/components/Search/SearchRouter/SearchRouter.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ import ROUTES from '@src/ROUTES';
1414
import {useSearchRouterContext} from './SearchRouterContext';
1515
import SearchRouterInput from './SearchRouterInput';
1616

17-
const SEARCH_DEBOUNCE_DELAY = 200;
17+
const SEARCH_DEBOUNCE_DELAY = 150;
1818

1919
function SearchRouter() {
2020
const styles = useThemeStyles();
2121

2222
const {isSmallScreenWidth} = useResponsiveLayout();
2323
const {isSearchRouterDisplayed, closeSearchRouter} = useSearchRouterContext();
24-
const [currentQuery, setCurrentQuery] = useState<SearchQueryJSON | undefined>(undefined);
24+
25+
const [userSearchQuery, setUserSearchQuery] = useState<SearchQueryJSON | undefined>(undefined);
2526

2627
const clearUserQuery = () => {
27-
setCurrentQuery(undefined);
28+
setUserSearchQuery(undefined);
2829
};
2930

3031
const onSearchChange = debounce((userQuery: string) => {
@@ -39,19 +40,24 @@ function SearchRouter() {
3940
// eslint-disable-next-line
4041
console.log('parsedQuery', queryJSON);
4142

42-
setCurrentQuery(queryJSON);
43+
setUserSearchQuery(queryJSON);
4344
} else {
4445
// Handle query parsing error
4546
}
4647
}, SEARCH_DEBOUNCE_DELAY);
4748

4849
const onSearchSubmit = useCallback(() => {
50+
if (!userSearchQuery) {
51+
return;
52+
}
53+
4954
closeSearchRouter();
5055

51-
const query = SearchUtils.buildSearchQueryString(currentQuery);
56+
const query = SearchUtils.buildSearchQueryString(userSearchQuery);
5257
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query}));
58+
5359
clearUserQuery();
54-
}, [currentQuery, closeSearchRouter]);
60+
}, [closeSearchRouter, userSearchQuery]);
5561

5662
useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ESCAPE, () => {
5763
closeSearchRouter();

src/components/Search/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ function Search({queryJSON}: SearchProps) {
389389
getItemHeight={getItemHeightMemoized}
390390
shouldSingleExecuteRowSelect
391391
shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()}
392+
shouldPreventDefault={false}
392393
listHeaderWrapperStyle={[styles.ph8, styles.pv3, styles.pb5]}
393394
containerStyle={[styles.pv0]}
394395
showScrollIndicator={false}

src/components/SelectionList/BaseSelectionList.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ function BaseSelectionList<TItem extends ListItem>(
7171
disableKeyboardShortcuts = false,
7272
children,
7373
shouldStopPropagation = false,
74+
shouldPreventDefault = true,
7475
shouldShowTooltips = true,
7576
shouldUseDynamicMaxToRenderPerBatch = false,
7677
rightHandSideComponent,
@@ -623,6 +624,7 @@ function BaseSelectionList<TItem extends ListItem>(
623624
captureOnInputs: true,
624625
shouldBubble: !flattenedSections.allOptions[focusedIndex],
625626
shouldStopPropagation,
627+
shouldPreventDefault,
626628
isActive: !disableKeyboardShortcuts && !disableEnterShortcut && isFocused,
627629
});
628630

src/components/SelectionList/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,12 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
436436
/** Whether tooltips should be shown */
437437
shouldShowTooltips?: boolean;
438438

439-
/** Whether to stop automatic form submission on pressing enter key or not */
439+
/** Whether to stop automatic propagation on pressing enter key or not */
440440
shouldStopPropagation?: boolean;
441441

442+
/** Whether to call preventDefault() on pressing enter key or not */
443+
shouldPreventDefault?: boolean;
444+
442445
/** Whether to prevent default focusing of options and focus the textinput when selecting an option */
443446
shouldPreventDefaultFocusOnSelectRow?: boolean;
444447

src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ import useThemeStyles from '@hooks/useThemeStyles';
1414
import * as Session from '@libs/actions/Session';
1515
import interceptAnonymousUser from '@libs/interceptAnonymousUser';
1616
import Navigation from '@libs/Navigation/Navigation';
17-
import type {RootStackParamList, State} from '@libs/Navigation/types';
17+
import type {AuthScreensParamList, RootStackParamList, State} from '@libs/Navigation/types';
1818
import {isCentralPaneName} from '@libs/NavigationUtils';
1919
import * as PolicyUtils from '@libs/PolicyUtils';
2020
import * as SearchUtils from '@libs/SearchUtils';
2121
import type {BrickRoad} from '@libs/WorkspacesSettingsUtils';
2222
import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils';
23+
import navigationRef from '@navigation/navigationRef';
2324
import BottomTabAvatar from '@pages/home/sidebar/BottomTabAvatar';
2425
import BottomTabBarFloatingActionButton from '@pages/home/sidebar/BottomTabBarFloatingActionButton';
2526
import variables from '@styles/variables';
@@ -113,9 +114,11 @@ function BottomTabBar({selectedTab}: BottomTabBarProps) {
113114
return;
114115
}
115116
interceptAnonymousUser(() => {
116-
const currentSearchParams = SearchUtils.getCurrentSearchParams();
117-
if (currentSearchParams) {
118-
const {q, ...rest} = currentSearchParams;
117+
const rootState = navigationRef.getRootState() as State<RootStackParamList>;
118+
const lastSearchRoute = rootState.routes.filter((route) => route.name === SCREENS.SEARCH.CENTRAL_PANE).at(-1);
119+
120+
if (lastSearchRoute) {
121+
const {q, ...rest} = lastSearchRoute.params as AuthScreensParamList[typeof SCREENS.SEARCH.CENTRAL_PANE];
119122
const cleanedQuery = handleQueryWithPolicyID(q, activeWorkspaceID);
120123

121124
Navigation.navigate(

src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ import CONST from '@src/CONST';
2323
import ONYXKEYS from '@src/ONYXKEYS';
2424
import ROUTES from '@src/ROUTES';
2525

26-
type TopBarProps = {breadcrumbLabel: string; activeWorkspaceID?: string; shouldDisplaySearch?: boolean; isCustomSearchQuery?: boolean};
26+
type TopBarProps = {breadcrumbLabel: string; activeWorkspaceID?: string; shouldDisplaySearch?: boolean; isCustomSearchQuery?: boolean; shouldDisplaySearchRouter?: boolean};
2727

28-
function TopBar({breadcrumbLabel, activeWorkspaceID, shouldDisplaySearch = true, isCustomSearchQuery = false}: TopBarProps) {
28+
function TopBar({breadcrumbLabel, activeWorkspaceID, shouldDisplaySearch = true, isCustomSearchQuery = false, shouldDisplaySearchRouter = false}: TopBarProps) {
2929
const styles = useThemeStyles();
3030
const theme = useTheme();
3131
const {translate} = useLocalize();
@@ -74,8 +74,7 @@ function TopBar({breadcrumbLabel, activeWorkspaceID, shouldDisplaySearch = true,
7474
<Text style={[styles.textBlue]}>{translate('common.cancel')}</Text>
7575
</PressableWithoutFeedback>
7676
)}
77-
{/* This is only temporary for development and will be cleaned up in: https://github.com/Expensify/App/issues/49122 */}
78-
<SearchButton />
77+
{shouldDisplaySearchRouter && <SearchButton />}
7978
{displaySearch && (
8079
<Tooltip text={translate('common.find')}>
8180
<PressableWithoutFeedback

0 commit comments

Comments
 (0)