Skip to content

Commit

Permalink
Merge pull request #49379 from software-mansion-labs/kicu/search-rout…
Browse files Browse the repository at this point in the history
…er-query

Add new SearchButton to all pages and tweak SearchRouter
  • Loading branch information
luacmartins authored Sep 24, 2024
2 parents a7a408f + 0f58dd9 commit 2ea2b15
Show file tree
Hide file tree
Showing 29 changed files with 170 additions and 175 deletions.
3 changes: 3 additions & 0 deletions src/components/HeaderWithBackButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import PinButton from '@components/PinButton';
import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback';
import SearchButton from '@components/Search/SearchRouter/SearchButton';
import ThreeDotsMenu from '@components/ThreeDotsMenu';
import Tooltip from '@components/Tooltip';
import useKeyboardState from '@hooks/useKeyboardState';
Expand Down Expand Up @@ -60,6 +61,7 @@ function HeaderWithBackButton({
shouldOverlayDots = false,
shouldOverlay = false,
shouldNavigateToTopMostReport = false,
shouldDisplaySearchRouter = false,
progressBarPercentage,
style,
}: HeaderWithBackButtonProps) {
Expand Down Expand Up @@ -261,6 +263,7 @@ function HeaderWithBackButton({
</PressableWithoutFeedback>
</Tooltip>
)}
{shouldDisplaySearchRouter && <SearchButton />}
</View>
</View>
</View>
Expand Down
3 changes: 3 additions & 0 deletions src/components/HeaderWithBackButton/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ type HeaderWithBackButtonProps = Partial<ChildrenProps> & {
/** Whether we should overlay the 3 dots menu */
shouldOverlayDots?: boolean;

/** Whether we should display the button that opens new SearchRouter */
shouldDisplaySearchRouter?: boolean;

/** 0 - 100 number indicating current progress of the progress bar */
progressBarPercentage?: number;

Expand Down
1 change: 1 addition & 0 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
report={moneyRequestReport}
policy={policy}
shouldShowBackButton={shouldUseNarrowLayout}
shouldDisplaySearchRouter
onBackButtonPress={onBackButtonPress}
// Shows border if no buttons or banners are showing below the header
shouldShowBorderBottom={!isMoreContentShown}
Expand Down
1 change: 1 addition & 0 deletions src/components/MoneyRequestHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, shouldUseNarrow
}}
policy={policy}
shouldShowBackButton={shouldUseNarrowLayout}
shouldDisplaySearchRouter
onBackButtonPress={onBackButtonPress}
>
{hasAllPendingRTERViolations && !shouldUseNarrowLayout && (
Expand Down
44 changes: 25 additions & 19 deletions src/components/Search/SearchPageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type {SearchDataTypes, SearchReport} from '@src/types/onyx/SearchResults'
import type DeepValueOf from '@src/types/utils/DeepValueOf';
import type IconAsset from '@src/types/utils/IconAsset';
import {useSearchContext} from './SearchContext';
import SearchButton from './SearchRouter/SearchButton';
import type {SearchQueryJSON} from './types';

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

const onPress = () => {
const values = SearchUtils.getFiltersFormValues(queryJSON);
const values = SearchUtils.buildFilterFormValuesFromQuery(queryJSON);
SearchActions.updateAdvancedFilters(values);
Navigation.navigate(ROUTES.SEARCH_ADVANCED_FILTERS);
};

const displaySearchRouter = SearchUtils.isCannedSearchQuery(queryJSON);

return (
<HeaderWrapper
title={headerTitle}
subtitle={headerSubtitle}
icon={headerIcon}
subtitleStyles={subtitleStyles}
>
{headerButtonsOptions.length > 0 ? (
<ButtonWithDropdownMenu
onPress={() => null}
shouldAlwaysShowDropdownMenu
pressOnEnter
buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM}
customText={translate('workspace.common.selected', {selectedNumber: selectedTransactionsKeys.length})}
options={headerButtonsOptions}
isSplitButton={false}
shouldUseStyleUtilityForAnchorPosition
/>
) : (
<Button
text={translate('search.filtersHeader')}
icon={Expensicons.Filters}
onPress={onPress}
/>
)}
<>
{headerButtonsOptions.length > 0 ? (
<ButtonWithDropdownMenu
onPress={() => null}
shouldAlwaysShowDropdownMenu
pressOnEnter
buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM}
customText={translate('workspace.common.selected', {selectedNumber: selectedTransactionsKeys.length})}
options={headerButtonsOptions}
isSplitButton={false}
shouldUseStyleUtilityForAnchorPosition
/>
) : (
<Button
text={translate('search.filtersHeader')}
icon={Expensicons.Filters}
onPress={onPress}
/>
)}
{displaySearchRouter && <SearchButton />}
</>
</HeaderWrapper>
);
}
Expand Down
6 changes: 4 additions & 2 deletions src/components/Search/SearchRouter/SearchButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import {PressableWithoutFeedback} from '@components/Pressable';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import Permissions from '@libs/Permissions';
Expand All @@ -10,6 +11,7 @@ import {useSearchRouterContext} from './SearchRouterContext';
function SearchButton() {
const styles = useThemeStyles();
const theme = useTheme();
const {translate} = useLocalize();
const {openSearchRouter} = useSearchRouterContext();

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

return (
<PressableWithoutFeedback
accessibilityLabel=""
style={[styles.flexRow, styles.mr2, styles.touchableButtonImage]}
accessibilityLabel={translate('common.search')}
style={[styles.flexRow, styles.touchableButtonImage]}
onPress={() => {
openSearchRouter();
}}
Expand Down
18 changes: 12 additions & 6 deletions src/components/Search/SearchRouter/SearchRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@ import ROUTES from '@src/ROUTES';
import {useSearchRouterContext} from './SearchRouterContext';
import SearchRouterInput from './SearchRouterInput';

const SEARCH_DEBOUNCE_DELAY = 200;
const SEARCH_DEBOUNCE_DELAY = 150;

function SearchRouter() {
const styles = useThemeStyles();

const {isSmallScreenWidth} = useResponsiveLayout();
const {isSearchRouterDisplayed, closeSearchRouter} = useSearchRouterContext();
const [currentQuery, setCurrentQuery] = useState<SearchQueryJSON | undefined>(undefined);

const [userSearchQuery, setUserSearchQuery] = useState<SearchQueryJSON | undefined>(undefined);

const clearUserQuery = () => {
setCurrentQuery(undefined);
setUserSearchQuery(undefined);
};

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

setCurrentQuery(queryJSON);
setUserSearchQuery(queryJSON);
} else {
// Handle query parsing error
}
}, SEARCH_DEBOUNCE_DELAY);

const onSearchSubmit = useCallback(() => {
if (!userSearchQuery) {
return;
}

closeSearchRouter();

const query = SearchUtils.buildSearchQueryString(currentQuery);
const query = SearchUtils.buildSearchQueryString(userSearchQuery);
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query}));

clearUserQuery();
}, [currentQuery, closeSearchRouter]);
}, [closeSearchRouter, userSearchQuery]);

useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ESCAPE, () => {
closeSearchRouter();
Expand Down
1 change: 1 addition & 0 deletions src/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ function Search({queryJSON}: SearchProps) {
getItemHeight={getItemHeightMemoized}
shouldSingleExecuteRowSelect
shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()}
shouldPreventDefault={false}
listHeaderWrapperStyle={[styles.ph8, styles.pv3, styles.pb5]}
containerStyle={[styles.pv0]}
showScrollIndicator={false}
Expand Down
2 changes: 2 additions & 0 deletions src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function BaseSelectionList<TItem extends ListItem>(
disableKeyboardShortcuts = false,
children,
shouldStopPropagation = false,
shouldPreventDefault = true,
shouldShowTooltips = true,
shouldUseDynamicMaxToRenderPerBatch = false,
rightHandSideComponent,
Expand Down Expand Up @@ -623,6 +624,7 @@ function BaseSelectionList<TItem extends ListItem>(
captureOnInputs: true,
shouldBubble: !flattenedSections.allOptions[focusedIndex],
shouldStopPropagation,
shouldPreventDefault,
isActive: !disableKeyboardShortcuts && !disableEnterShortcut && isFocused,
});

Expand Down
5 changes: 4 additions & 1 deletion src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,12 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
/** Whether tooltips should be shown */
shouldShowTooltips?: boolean;

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

/** Whether to call preventDefault() on pressing enter key or not */
shouldPreventDefault?: boolean;

/** Whether to prevent default focusing of options and focus the textinput when selecting an option */
shouldPreventDefaultFocusOnSelectRow?: boolean;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import useThemeStyles from '@hooks/useThemeStyles';
import * as Session from '@libs/actions/Session';
import interceptAnonymousUser from '@libs/interceptAnonymousUser';
import Navigation from '@libs/Navigation/Navigation';
import type {RootStackParamList, State} from '@libs/Navigation/types';
import type {AuthScreensParamList, RootStackParamList, State} from '@libs/Navigation/types';
import {isCentralPaneName} from '@libs/NavigationUtils';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as SearchUtils from '@libs/SearchUtils';
import type {BrickRoad} from '@libs/WorkspacesSettingsUtils';
import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils';
import navigationRef from '@navigation/navigationRef';
import BottomTabAvatar from '@pages/home/sidebar/BottomTabAvatar';
import BottomTabBarFloatingActionButton from '@pages/home/sidebar/BottomTabBarFloatingActionButton';
import variables from '@styles/variables';
Expand Down Expand Up @@ -113,9 +114,11 @@ function BottomTabBar({selectedTab}: BottomTabBarProps) {
return;
}
interceptAnonymousUser(() => {
const currentSearchParams = SearchUtils.getCurrentSearchParams();
if (currentSearchParams) {
const {q, ...rest} = currentSearchParams;
const rootState = navigationRef.getRootState() as State<RootStackParamList>;
const lastSearchRoute = rootState.routes.filter((route) => route.name === SCREENS.SEARCH.CENTRAL_PANE).at(-1);

if (lastSearchRoute) {
const {q, ...rest} = lastSearchRoute.params as AuthScreensParamList[typeof SCREENS.SEARCH.CENTRAL_PANE];
const cleanedQuery = handleQueryWithPolicyID(q, activeWorkspaceID);

Navigation.navigate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';

type TopBarProps = {breadcrumbLabel: string; activeWorkspaceID?: string; shouldDisplaySearch?: boolean; isCustomSearchQuery?: boolean};
type TopBarProps = {breadcrumbLabel: string; activeWorkspaceID?: string; shouldDisplaySearch?: boolean; isCustomSearchQuery?: boolean; shouldDisplaySearchRouter?: boolean};

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

0 comments on commit 2ea2b15

Please sign in to comment.