Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new SearchButton to all pages and tweak SearchRouter #49379

Merged
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 />}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, This caused this issue: #51077

</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
Loading