diff --git a/src/NAVIGATORS.ts b/src/NAVIGATORS.ts index 6014ab22e9530..de3a66e1f441b 100644 --- a/src/NAVIGATORS.ts +++ b/src/NAVIGATORS.ts @@ -14,4 +14,5 @@ export default { REPORTS_SPLIT_NAVIGATOR: 'ReportsSplitNavigator', SETTINGS_SPLIT_NAVIGATOR: 'SettingsSplitNavigator', WORKSPACE_SPLIT_NAVIGATOR: 'WorkspaceSplitNavigator', + SEARCH_FULLSCREEN_NAVIGATOR: 'SearchFullscreenNavigator', } as const; diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 09fe7c4abcfd4..afb0b9b29a598 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -78,6 +78,13 @@ const ROUTES = { return getUrlWithBackToParam(baseRoute, backTo); }, }, + SEARCH_MONEY_REQUEST_REPORT: { + route: 'search/report/:reportID', + getRoute: ({reportID, backTo}: {reportID: string; backTo?: string}) => { + const baseRoute = `search/view/${reportID}` as const; + return getUrlWithBackToParam(baseRoute, backTo); + }, + }, TRANSACTION_HOLD_REASON_RHP: 'search/hold', // This is a utility route used to go to the user's concierge chat, or the sign-in page if the user's not authenticated diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 5a8b0c75d5c01..7e09c0277fe47 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -37,6 +37,7 @@ const SCREENS = { }, SEARCH: { ROOT: 'Search_Root', + MONEY_REQUEST_REPORT: 'Search_Money_Request_Report', REPORT_RHP: 'Search_Report_RHP', ADVANCED_FILTERS_RHP: 'Search_Advanced_Filters_RHP', ADVANCED_FILTERS_DATE_RHP: 'Search_Advanced_Filters_Date_RHP', diff --git a/src/components/Navigation/BottomTabBar/index.tsx b/src/components/Navigation/BottomTabBar/index.tsx index eb9170a1d3fe4..6fb65924b3304 100644 --- a/src/components/Navigation/BottomTabBar/index.tsx +++ b/src/components/Navigation/BottomTabBar/index.tsx @@ -9,7 +9,6 @@ import * as Expensicons from '@components/Icon/Expensicons'; import DebugTabView from '@components/Navigation/DebugTabView'; import {PressableWithFeedback} from '@components/Pressable'; import {useProductTrainingContext} from '@components/ProductTrainingContext'; -import type {SearchQueryString} from '@components/Search/types'; import Text from '@components/Text'; import EducationalTooltip from '@components/Tooltip/EducationalTooltip'; import useActiveWorkspace from '@hooks/useActiveWorkspace'; @@ -21,15 +20,14 @@ import useThemeStyles from '@hooks/useThemeStyles'; import clearSelectedText from '@libs/clearSelectedText/clearSelectedText'; import getPlatform from '@libs/getPlatform'; import interceptAnonymousUser from '@libs/interceptAnonymousUser'; -import {getPolicy} from '@libs/PolicyUtils'; -import {buildCannedSearchQuery, buildSearchQueryJSON, buildSearchQueryString} from '@libs/SearchQueryUtils'; +import {buildCannedSearchQuery} from '@libs/SearchQueryUtils'; import type {BrickRoad} from '@libs/WorkspacesSettingsUtils'; import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils'; import {getPreservedSplitNavigatorState} from '@navigation/AppNavigator/createSplitNavigator/usePreserveSplitNavigatorState'; import {isFullScreenName} from '@navigation/helpers/isNavigatorName'; import Navigation from '@navigation/Navigation'; import navigationRef from '@navigation/navigationRef'; -import type {AuthScreensParamList, RootNavigatorParamList, State, WorkspaceSplitNavigatorParamList} from '@navigation/types'; +import type {WorkspaceSplitNavigatorParamList} from '@navigation/types'; import BottomTabAvatar from '@pages/home/sidebar/BottomTabAvatar'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -44,34 +42,6 @@ type BottomTabBarProps = { isTooltipAllowed?: boolean; }; -/** - * Returns SearchQueryString that has policyID correctly set. - * - * When we're coming back to Search Screen we might have pre-existing policyID inside SearchQuery. - * There are 2 cases when we might want to remove this `policyID`: - * - if Policy was removed in another screen - * - if WorkspaceSwitcher was used to globally unset a policyID - * Otherwise policyID will be inserted into query - */ -function handleQueryWithPolicyID(query: SearchQueryString, activePolicyID?: string): SearchQueryString { - const queryJSON = buildSearchQueryJSON(query); - if (!queryJSON) { - return query; - } - - const policyID = activePolicyID ?? queryJSON.policyID; - const policy = getPolicy(policyID); - - // In case policy is missing or there is no policy currently selected via WorkspaceSwitcher we remove it - if (!activePolicyID || !policy) { - delete queryJSON.policyID; - } else { - queryJSON.policyID = policyID; - } - - return buildSearchQueryString(queryJSON); -} - function BottomTabBar({selectedTab, isTooltipAllowed = false}: BottomTabBarProps) { const {isCreateMenuActive, toggleCreateMenu, fabRef} = useContext(FABPopoverContext); const theme = useTheme(); @@ -110,22 +80,6 @@ function BottomTabBar({selectedTab, isTooltipAllowed = false}: BottomTabBarProps } clearSelectedText(); interceptAnonymousUser(() => { - const rootState = navigationRef.getRootState() as State; - const lastSearchRoute = rootState.routes.findLast((route) => route.name === SCREENS.SEARCH.ROOT); - - if (lastSearchRoute) { - const {q, ...rest} = lastSearchRoute.params as AuthScreensParamList[typeof SCREENS.SEARCH.ROOT]; - const cleanedQuery = handleQueryWithPolicyID(q, activeWorkspaceID); - - Navigation.navigate( - ROUTES.SEARCH_ROOT.getRoute({ - query: cleanedQuery, - ...rest, - }), - ); - return; - } - const defaultCannedQuery = buildCannedSearchQuery(); // when navigating to search we might have an activePolicyID set from workspace switcher const query = activeWorkspaceID ? `${defaultCannedQuery} ${CONST.SEARCH.SYNTAX_ROOT_KEYS.POLICY_ID}:${activeWorkspaceID}` : defaultCannedQuery; diff --git a/src/components/Navigation/TopLevelBottomTabBar/SCREENS_WITH_BOTTOM_TAB_BAR.ts b/src/components/Navigation/TopLevelBottomTabBar/SCREENS_WITH_BOTTOM_TAB_BAR.ts index 87c6da192ad1b..bd750adc94fa6 100644 --- a/src/components/Navigation/TopLevelBottomTabBar/SCREENS_WITH_BOTTOM_TAB_BAR.ts +++ b/src/components/Navigation/TopLevelBottomTabBar/SCREENS_WITH_BOTTOM_TAB_BAR.ts @@ -1,6 +1,7 @@ import {SIDEBAR_TO_SPLIT} from '@libs/Navigation/linkingConfig/RELATIONS'; +import NAVIGATORS from '@src/NAVIGATORS'; import SCREENS from '@src/SCREENS'; -const SCREENS_WITH_BOTTOM_TAB_BAR = [...Object.keys(SIDEBAR_TO_SPLIT), SCREENS.SEARCH.ROOT, SCREENS.SETTINGS.WORKSPACES]; +const SCREENS_WITH_BOTTOM_TAB_BAR = [...Object.keys(SIDEBAR_TO_SPLIT), NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR, SCREENS.SETTINGS.WORKSPACES]; export default SCREENS_WITH_BOTTOM_TAB_BAR; diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 561b928ab1a27..02f5581c2d967 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -35,7 +35,7 @@ import { } from '@libs/SearchUIUtils'; import {isOnHold} from '@libs/TransactionUtils'; import Navigation from '@navigation/Navigation'; -import type {AuthScreensParamList} from '@navigation/types'; +import type {SearchFullscreenNavigatorParamList} from '@navigation/types'; import EmptySearchView from '@pages/Search/EmptySearchView'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -133,7 +133,7 @@ function Search({queryJSON, onSearchListScroll, isSearchScreenFocused, contentCo // We need to use isSmallScreenWidth instead of shouldUseNarrowLayout for enabling the selection mode on small screens only // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth const {isSmallScreenWidth, isLargeScreenWidth} = useResponsiveLayout(); - const navigation = useNavigation>(); + const navigation = useNavigation>(); const isFocused = useIsFocused(); const [lastNonEmptySearchResults, setLastNonEmptySearchResults] = useState(undefined); const { diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index e33ef15cfdcd5..1225219be0c61 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -34,7 +34,6 @@ import NetworkConnection from '@libs/NetworkConnection'; import onyxSubscribe from '@libs/onyxSubscribe'; import Pusher from '@libs/Pusher'; import PusherConnectionManager from '@libs/PusherConnectionManager'; -import * as SearchQueryUtils from '@libs/SearchQueryUtils'; import * as SessionUtils from '@libs/SessionUtils'; import ConnectionCompletePage from '@pages/ConnectionCompletePage'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; @@ -97,7 +96,7 @@ const loadWorkspaceJoinUser = () => require('@pages/worksp const loadReportSplitNavigator = () => require('./Navigators/ReportsSplitNavigator').default; const loadSettingsSplitNavigator = () => require('./Navigators/SettingsSplitNavigator').default; const loadWorkspaceSplitNavigator = () => require('./Navigators/WorkspaceSplitNavigator').default; -const loadSearchPage = () => require('@pages/Search/SearchPage').default; +const loadSearchNavigator = () => require('./Navigators/SearchFullscreenNavigator').default; function initializePusher() { return Pusher.init({ @@ -455,7 +454,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie return ( @@ -471,10 +470,9 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie getComponent={loadSettingsSplitNavigator} /> require('@pages/Search/SearchPage').default; +const loadSearchMoneyReportPage = () => require('@pages/Search/SearchMoneyRequestReportPage').default; + +const Stack = createSearchFullscreenNavigator(); + +function SearchFullscreenNavigator() { + const rootNavigatorScreenOptions = useRootNavigatorScreenOptions(); + + return ( + + + + + + + ); +} + +SearchFullscreenNavigator.displayName = 'SearchFullscreenNavigator'; + +export default SearchFullscreenNavigator; diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts index a225301101c46..bb796c74eee18 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts @@ -77,11 +77,11 @@ function handleOpenWorkspaceSplitAction( } /** - * Handles the SWITCH_POLICY_ID action. - * Information about the currently selected policy can be found in the last ReportsSplitNavigator or Search_Root. - * As the policy can only be changed from Search or Inbox Tab, after changing the policy a new ReportsSplitNavigator or Search_Root with the changed policy has to be pushed to the navigation state. + * Handles the SWITCH_POLICY_ID action for `SearchFullscreenNavigator`. + * Information about the currently selected policy can be found in the last Search_Root. + * After user changes the policy while on Search, a new Search_Root with the changed policy inside query param has to be pushed to the navigation state. */ -function handleSwitchPolicyID( +function handleSwitchPolicyIDFromSearchAction( state: StackNavigationState, action: SwitchPolicyIdActionType, configOptions: RouterConfigOptions, @@ -110,6 +110,23 @@ function handleSwitchPolicyID( setActiveWorkspaceID(action.payload.policyID); return stackRouter.getStateForAction(state, newAction, configOptions); } + // We don't have other navigators that should handle switch policy action. + return null; +} + +/** + * Handles the SWITCH_POLICY_ID action for `ReportsSplitNavigator`. + * Information about the currently selected policy can be found in the last ReportsSplitNavigator. + * After user changes the policy while on Inbox, a new ReportsSplitNavigator with the changed policy has to be pushed to the navigation state. + */ +function handleSwitchPolicyIDAction( + state: StackNavigationState, + action: SwitchPolicyIdActionType, + configOptions: RouterConfigOptions, + stackRouter: Router, CommonActions.Action | StackActionType>, + setActiveWorkspaceID: (workspaceID: string | undefined) => void, +) { + const lastRoute = state.routes.at(-1); if (lastRoute?.name === NAVIGATORS.REPORTS_SPLIT_NAVIGATOR) { const newAction = StackActions.push(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR, {policyID: action.payload.policyID}); @@ -182,37 +199,42 @@ function handlePushSearchPageAction( stackRouter: Router, CommonActions.Action | StackActionType>, setActiveWorkspaceID: (workspaceID: string | undefined) => void, ) { - const currentParams = action.payload.params as RootNavigatorParamList[typeof SCREENS.SEARCH.ROOT]; - const queryJSON = SearchQueryUtils.buildSearchQueryJSON(currentParams.q); - - if (!queryJSON) { - return null; - } + let updatedAction = action; + const currentParams = action.payload.params as RootNavigatorParamList[typeof NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR]; + if (currentParams?.screen === SCREENS.SEARCH.ROOT) { + const searchParams = currentParams?.params; + const queryJSON = SearchQueryUtils.buildSearchQueryJSON(searchParams.q); + if (!queryJSON) { + return null; + } - if (!queryJSON.policyID) { - const policyID = getPolicyIDFromState(state as State); + if (!queryJSON.policyID) { + const policyID = getPolicyIDFromState(state as State); - if (policyID) { - queryJSON.policyID = policyID; + if (policyID) { + queryJSON.policyID = policyID; + } else { + delete queryJSON.policyID; + } } else { - delete queryJSON.policyID; + setActiveWorkspaceID(queryJSON.policyID); } - } else { - setActiveWorkspaceID(queryJSON.policyID); - } - const modifiedAction = { - ...action, - payload: { - ...action.payload, - params: { - ...action.payload.params, - q: SearchQueryUtils.buildSearchQueryString(queryJSON), + updatedAction = { + ...action, + payload: { + ...action.payload, + params: { + ...action.payload.params, + params: { + q: SearchQueryUtils.buildSearchQueryString(queryJSON), + }, + }, }, - }, - }; + }; + } - return stackRouter.getStateForAction(state, modifiedAction, configOptions); + return stackRouter.getStateForAction(state, updatedAction, configOptions); } /** @@ -253,7 +275,8 @@ export { handleDismissModalAction, handlePushReportSplitAction, handlePushSearchPageAction, - handleSwitchPolicyID, + handleSwitchPolicyIDAction, + handleSwitchPolicyIDFromSearchAction, handleNavigatingToModalFromModal, workspaceSplitsWithoutEnteringAnimation, reportsSplitsWithEnteringAnimation, diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/RootStackRouter.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/RootStackRouter.ts index 7fd10aba7ba26..fcaad4ae232a4 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/RootStackRouter.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/RootStackRouter.ts @@ -8,8 +8,14 @@ import isSideModalNavigator from '@libs/Navigation/helpers/isSideModalNavigator' import * as Welcome from '@userActions/Welcome'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; -import SCREENS from '@src/SCREENS'; -import * as GetStateForActionHandlers from './GetStateForActionHandlers'; +import { + handleDismissModalAction, + handleNavigatingToModalFromModal, + handleOpenWorkspaceSplitAction, + handlePushReportSplitAction, + handlePushSearchPageAction, + handleSwitchPolicyIDAction, +} from './GetStateForActionHandlers'; import syncBrowserHistory from './syncBrowserHistory'; import type {DismissModalActionType, OpenWorkspaceSplitActionType, PushActionType, RootStackNavigatorAction, RootStackNavigatorRouterOptions, SwitchPolicyIdActionType} from './types'; @@ -65,24 +71,24 @@ function RootStackRouter(options: RootStackNavigatorRouterOptions) { ...stackRouter, getStateForAction(state: StackNavigationState, action: RootStackNavigatorAction, configOptions: RouterConfigOptions) { if (isOpenWorkspaceSplitAction(action)) { - return GetStateForActionHandlers.handleOpenWorkspaceSplitAction(state, action, configOptions, stackRouter); + return handleOpenWorkspaceSplitAction(state, action, configOptions, stackRouter); } if (isSwitchPolicyIdAction(action)) { - return GetStateForActionHandlers.handleSwitchPolicyID(state, action, configOptions, stackRouter, setActiveWorkspaceID); + return handleSwitchPolicyIDAction(state, action, configOptions, stackRouter, setActiveWorkspaceID); } if (isDismissModalAction(action)) { - return GetStateForActionHandlers.handleDismissModalAction(state, configOptions, stackRouter); + return handleDismissModalAction(state, configOptions, stackRouter); } if (isPushAction(action)) { if (action.payload.name === NAVIGATORS.REPORTS_SPLIT_NAVIGATOR) { - return GetStateForActionHandlers.handlePushReportSplitAction(state, action, configOptions, stackRouter, setActiveWorkspaceID); + return handlePushReportSplitAction(state, action, configOptions, stackRouter, setActiveWorkspaceID); } - if (action.payload.name === SCREENS.SEARCH.ROOT) { - return GetStateForActionHandlers.handlePushSearchPageAction(state, action, configOptions, stackRouter, setActiveWorkspaceID); + if (action.payload.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR) { + return handlePushSearchPageAction(state, action, configOptions, stackRouter, setActiveWorkspaceID); } } @@ -93,7 +99,7 @@ function RootStackRouter(options: RootStackNavigatorRouterOptions) { } if (isNavigatingToModalFromModal(state, action)) { - return GetStateForActionHandlers.handleNavigatingToModalFromModal(state, action, configOptions, stackRouter); + return handleNavigatingToModalFromModal(state, action, configOptions, stackRouter); } return stackRouter.getStateForAction(state, action, configOptions); diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/types.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/types.ts index 6f6a0a878ab72..6dae82db35b5b 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/types.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/types.ts @@ -39,6 +39,8 @@ type RootStackNavigatorConfig = { type RootStackNavigatorRouterOptions = StackRouterOptions; +type SearchFullscreenNavigatorRouterOptions = StackRouterOptions; + type RootStackNavigatorProps = DefaultNavigatorOptions, StackNavigationOptions, StackNavigationEventMap> & RootStackNavigatorConfig; type RootStackNavigatorAction = CommonActions.Action | StackActionType | RootStackNavigatorActionType; @@ -53,4 +55,5 @@ export type { RootStackNavigatorRouterOptions, RootStackNavigatorProps, RootStackNavigatorConfig, + SearchFullscreenNavigatorRouterOptions, }; diff --git a/src/libs/Navigation/AppNavigator/createSearchFullscreenNavigator/SearchFullscreenRouter.ts b/src/libs/Navigation/AppNavigator/createSearchFullscreenNavigator/SearchFullscreenRouter.ts new file mode 100644 index 0000000000000..0eb62148118c2 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createSearchFullscreenNavigator/SearchFullscreenRouter.ts @@ -0,0 +1,27 @@ +import type {CommonActions, ParamListBase, RouterConfigOptions, StackActionType, StackNavigationState} from '@react-navigation/native'; +import {StackRouter} from '@react-navigation/native'; +import useActiveWorkspace from '@hooks/useActiveWorkspace'; +import {handleSwitchPolicyIDFromSearchAction} from '@navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers'; +import type {RootStackNavigatorAction, SearchFullscreenNavigatorRouterOptions, SwitchPolicyIdActionType} from '@navigation/AppNavigator/createRootStackNavigator/types'; +import CONST from '@src/CONST'; + +function isSwitchPolicyIdAction(action: RootStackNavigatorAction): action is SwitchPolicyIdActionType { + return action.type === CONST.NAVIGATION.ACTION_TYPE.SWITCH_POLICY_ID; +} + +function SearchFullscreenRouter(options: SearchFullscreenNavigatorRouterOptions) { + const stackRouter = StackRouter(options); + const {setActiveWorkspaceID} = useActiveWorkspace(); + + return { + ...stackRouter, + getStateForAction(state: StackNavigationState, action: CommonActions.Action | StackActionType, configOptions: RouterConfigOptions) { + if (isSwitchPolicyIdAction(action)) { + return handleSwitchPolicyIDFromSearchAction(state, action, configOptions, stackRouter, setActiveWorkspaceID); + } + return stackRouter.getStateForAction(state, action, configOptions); + }, + }; +} + +export default SearchFullscreenRouter; diff --git a/src/libs/Navigation/AppNavigator/createSearchFullscreenNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createSearchFullscreenNavigator/index.tsx new file mode 100644 index 0000000000000..cc4d5162434cf --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createSearchFullscreenNavigator/index.tsx @@ -0,0 +1,25 @@ +import type {ParamListBase} from '@react-navigation/native'; +import {createNavigatorFactory} from '@react-navigation/native'; +import useNavigationResetOnLayoutChange from '@libs/Navigation/AppNavigator/useNavigationResetOnLayoutChange'; +import createPlatformStackNavigatorComponent from '@navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent'; +import defaultPlatformStackScreenOptions from '@navigation/PlatformStackNavigation/defaultPlatformStackScreenOptions'; +import type {CustomEffectsHookProps, PlatformStackNavigationEventMap, PlatformStackNavigationOptions, PlatformStackNavigationState} from '@navigation/PlatformStackNavigation/types'; +import SearchFullscreenRouter from './SearchFullscreenRouter'; + +function useCustomEffects(props: CustomEffectsHookProps) { + useNavigationResetOnLayoutChange(props); +} + +const SearchFullscreenNavigatorComponent = createPlatformStackNavigatorComponent('SearchFullscreenNavigator', { + createRouter: SearchFullscreenRouter, + defaultScreenOptions: defaultPlatformStackScreenOptions, + useCustomEffects, +}); + +function createSearchFullscreenNavigator() { + return createNavigatorFactory, PlatformStackNavigationOptions, PlatformStackNavigationEventMap, typeof SearchFullscreenNavigatorComponent>( + SearchFullscreenNavigatorComponent, + )(); +} + +export default createSearchFullscreenNavigator; diff --git a/src/libs/Navigation/AppNavigator/createSplitNavigator/getInitialSplitNavigatorState.ts b/src/libs/Navigation/AppNavigator/createSplitNavigator/getInitialSplitNavigatorState.ts index 06ac86f40b2d2..eb83d62b014b8 100644 --- a/src/libs/Navigation/AppNavigator/createSplitNavigator/getInitialSplitNavigatorState.ts +++ b/src/libs/Navigation/AppNavigator/createSplitNavigator/getInitialSplitNavigatorState.ts @@ -1,8 +1,8 @@ import type {NavigationState, PartialState} from '@react-navigation/native'; import {SIDEBAR_TO_SPLIT} from '@libs/Navigation/linkingConfig/RELATIONS'; -import type {NavigationPartialRoute, SplitNavigatorBySidebar, SplitNavigatorParamListType, SplitNavigatorSidebarScreen} from '@libs/Navigation/types'; +import type {NavigationPartialRoute, SplitNavigatorBySidebar, SplitNavigatorParamList, SplitNavigatorSidebarScreen} from '@libs/Navigation/types'; -type ExtractRouteType = Extract; +type ExtractRouteType = Extract; // The function getPathFromState that we are using in some places isn't working correctly without defined index. const getRoutesWithIndex = (routes: NavigationPartialRoute[]): PartialState => ({routes, index: routes.length - 1}); diff --git a/src/libs/Navigation/AppNavigator/useNavigationResetOnLayoutChange.ts b/src/libs/Navigation/AppNavigator/useNavigationResetOnLayoutChange.ts index 0a671529ee7d3..82a085fca2ec6 100644 --- a/src/libs/Navigation/AppNavigator/useNavigationResetOnLayoutChange.ts +++ b/src/libs/Navigation/AppNavigator/useNavigationResetOnLayoutChange.ts @@ -6,6 +6,7 @@ import type {CustomEffectsHookProps} from '@libs/Navigation/PlatformStackNavigat /** * This hook resets the navigation root state when changing the layout size, resetting the state calls the getRehydredState method in CustomFullScreenRouter.tsx. + * It is also called when the navigator is created to set the initial state correctly. * When the screen size is changed, it is necessary to check whether the application displays the content correctly. * When the app is opened on a small layout and the user resizes it to wide, a second screen has to be present in the navigation state to fill the space. */ diff --git a/src/libs/Navigation/helpers/getAdaptedStateFromPath.ts b/src/libs/Navigation/helpers/getAdaptedStateFromPath.ts index 08def7d5ab2b1..12dc95c141948 100644 --- a/src/libs/Navigation/helpers/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/helpers/getAdaptedStateFromPath.ts @@ -73,7 +73,7 @@ function getMatchingFullScreenRoute(route: NavigationPartialRoute, policyID?: st const paramsFromRoute = getParamsFromRoute(SCREENS.SEARCH.ROOT); return { - name: SCREENS.SEARCH.ROOT, + name: NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR, params: paramsFromRoute.length > 0 ? pick(route.params, paramsFromRoute) : undefined, }; } diff --git a/src/libs/Navigation/helpers/getPolicyIDFromState.ts b/src/libs/Navigation/helpers/getPolicyIDFromState.ts index f5cd3ffdd0817..ca00f8a26987f 100644 --- a/src/libs/Navigation/helpers/getPolicyIDFromState.ts +++ b/src/libs/Navigation/helpers/getPolicyIDFromState.ts @@ -8,16 +8,19 @@ import extractPolicyIDFromQuery from './extractPolicyIDFromQuery'; * * PolicyID in this app can be stored in two ways: * - on NAVIGATORS.REPORTS_SPLIT_NAVIGATOR as `policyID` param - * - on Search related screens as policyID filter inside `q` (SearchQuery) param (only for SEARCH_CENTRAL_PANE) + * - on Search related screens as policyID filter inside `q` (SearchQuery) param (only for Search_Root) */ const getPolicyIDFromState = (state: State): string | undefined => { - const lastPolicyRoute = state?.routes?.findLast((route) => route.name === NAVIGATORS.REPORTS_SPLIT_NAVIGATOR || route.name === SCREENS.SEARCH.ROOT); + const lastPolicyRoute = state?.routes?.findLast((route) => route.name === NAVIGATORS.REPORTS_SPLIT_NAVIGATOR || route.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR); if (lastPolicyRoute?.params && 'policyID' in lastPolicyRoute.params) { return lastPolicyRoute?.params?.policyID; } - if (lastPolicyRoute) { - return extractPolicyIDFromQuery(lastPolicyRoute as NavigationPartialRoute); + // Handle SEARCH navigator + const lastSearchRoute = lastPolicyRoute?.state?.routes?.findLast((route) => route.name === SCREENS.SEARCH.ROOT); + + if (lastSearchRoute) { + return extractPolicyIDFromQuery(lastSearchRoute as NavigationPartialRoute); } return undefined; diff --git a/src/libs/Navigation/helpers/isNavigatorName.ts b/src/libs/Navigation/helpers/isNavigatorName.ts index ceea8e5525d43..cb90d6935df77 100644 --- a/src/libs/Navigation/helpers/isNavigatorName.ts +++ b/src/libs/Navigation/helpers/isNavigatorName.ts @@ -1,5 +1,6 @@ import {SIDEBAR_TO_SPLIT, SPLIT_TO_SIDEBAR} from '@libs/Navigation/linkingConfig/RELATIONS'; import type {FullScreenName, OnboardingFlowName, SplitNavigatorName, SplitNavigatorSidebarScreen} from '@libs/Navigation/types'; +import NAVIGATORS from '@src/NAVIGATORS'; import SCREENS from '@src/SCREENS'; const ONBOARDING_SCREENS = [ @@ -12,7 +13,7 @@ const ONBOARDING_SCREENS = [ SCREENS.ONBOARDING.WORKSPACES, ]; -const FULL_SCREENS_SET = new Set([...Object.values(SIDEBAR_TO_SPLIT), SCREENS.SEARCH.ROOT]); +const FULL_SCREENS_SET = new Set([...Object.values(SIDEBAR_TO_SPLIT), NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR]); const SIDEBARS_SET = new Set(Object.values(SPLIT_TO_SIDEBAR)); const ONBOARDING_SCREENS_SET = new Set(ONBOARDING_SCREENS); const SPLIT_NAVIGATORS_SET = new Set(Object.values(SIDEBAR_TO_SPLIT)); diff --git a/src/libs/Navigation/helpers/resetPolicyIDInNavigationState.ts b/src/libs/Navigation/helpers/resetPolicyIDInNavigationState.ts index 8a6235835e082..6286c4cc816a2 100644 --- a/src/libs/Navigation/helpers/resetPolicyIDInNavigationState.ts +++ b/src/libs/Navigation/helpers/resetPolicyIDInNavigationState.ts @@ -1,5 +1,5 @@ import Navigation, {navigationRef} from '@libs/Navigation/Navigation'; -import type {AuthScreensParamList} from '@libs/Navigation/types'; +import type {SearchFullscreenNavigatorParamList} from '@libs/Navigation/types'; import * as SearchQueryUtils from '@libs/SearchQueryUtils'; import NAVIGATORS from '@src/NAVIGATORS'; import SCREENS from '@src/SCREENS'; @@ -21,7 +21,7 @@ function resetPolicyIDInNavigationState() { return; } - const {q, ...rest} = lastPolicyRoute.params as AuthScreensParamList[typeof SCREENS.SEARCH.ROOT]; + const {q, ...rest} = lastPolicyRoute.params as SearchFullscreenNavigatorParamList[typeof SCREENS.SEARCH.ROOT]; const queryJSON = SearchQueryUtils.buildSearchQueryJSON(q); if (!queryJSON || !queryJSON.policyID) { return; diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/FULLSCREEN_TO_TAB.ts b/src/libs/Navigation/linkingConfig/RELATIONS/FULLSCREEN_TO_TAB.ts index 551d77fe8952d..ad7c3099aeaf4 100644 --- a/src/libs/Navigation/linkingConfig/RELATIONS/FULLSCREEN_TO_TAB.ts +++ b/src/libs/Navigation/linkingConfig/RELATIONS/FULLSCREEN_TO_TAB.ts @@ -2,11 +2,10 @@ import type {ValueOf} from 'type-fest'; import BOTTOM_TABS from '@components/Navigation/BottomTabBar/BOTTOM_TABS'; import type {FullScreenName} from '@libs/Navigation/types'; import NAVIGATORS from '@src/NAVIGATORS'; -import SCREENS from '@src/SCREENS'; const FULLSCREEN_TO_TAB: Record> = { [NAVIGATORS.REPORTS_SPLIT_NAVIGATOR]: BOTTOM_TABS.HOME, - [SCREENS.SEARCH.ROOT]: BOTTOM_TABS.SEARCH, + [NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR]: BOTTOM_TABS.SEARCH, [NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR]: BOTTOM_TABS.SETTINGS, [NAVIGATORS.WORKSPACE_SPLIT_NAVIGATOR]: BOTTOM_TABS.SETTINGS, }; diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 90d14b50890a8..1d315808e8adf 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -29,9 +29,6 @@ const config: LinkingOptions['config'] = { [SCREENS.REPORT_AVATAR]: ROUTES.REPORT_AVATAR.route, [SCREENS.TRANSACTION_RECEIPT]: ROUTES.TRANSACTION_RECEIPT.route, [SCREENS.WORKSPACE_JOIN_USER]: ROUTES.WORKSPACE_JOIN_USER.route, - [SCREENS.SEARCH.ROOT]: { - path: ROUTES.SEARCH_ROOT.route, - }, [SCREENS.NOT_FOUND]: '*', [NAVIGATORS.LEFT_MODAL_NAVIGATOR]: { @@ -1630,6 +1627,17 @@ const config: LinkingOptions['config'] = { }, }, }, + + [NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR]: { + screens: { + [SCREENS.SEARCH.ROOT]: { + path: ROUTES.SEARCH_ROOT.route, + }, + [SCREENS.SEARCH.MONEY_REQUEST_REPORT]: { + path: ROUTES.SEARCH_MONEY_REQUEST_REPORT.route, + }, + }, + }, }, }; diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index e38ab9a6d8fb0..69fb5ae486c83 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -57,7 +57,7 @@ type NavigationRoute = NavigationStateRoute | NavigationPartialRoute; type SplitNavigatorSidebarScreen = keyof typeof SIDEBAR_TO_SPLIT; -type SplitNavigatorParamListType = { +type SplitNavigatorParamList = { [NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR]: SettingsSplitNavigatorParamList; [NAVIGATORS.REPORTS_SPLIT_NAVIGATOR]: ReportsSplitNavigatorParamList; [NAVIGATORS.WORKSPACE_SPLIT_NAVIGATOR]: WorkspaceSplitNavigatorParamList; @@ -69,11 +69,6 @@ type BackToParams = { backTo?: Routes; }; -type BackToAndForwardToParms = { - backTo?: Routes; - forwardTo?: Routes; -}; - type SettingsNavigatorParamList = { [SCREENS.SETTINGS.SHARE_CODE]: undefined; [SCREENS.SETTINGS.PROFILE.PRONOUNS]: undefined; @@ -1819,6 +1814,7 @@ type AuthScreensParamList = SharedScreensParamList & { [NAVIGATORS.WELCOME_VIDEO_MODAL_NAVIGATOR]: NavigatorScreenParams; [NAVIGATORS.EXPLANATION_MODAL_NAVIGATOR]: NavigatorScreenParams; [NAVIGATORS.MIGRATED_USER_MODAL_NAVIGATOR]: NavigatorScreenParams; + [NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR]: NavigatorScreenParams; [SCREENS.DESKTOP_SIGN_IN_REDIRECT]: undefined; [SCREENS.TRANSACTION_RECEIPT]: { reportID: string; @@ -1828,11 +1824,6 @@ type AuthScreensParamList = SharedScreensParamList & { }; [SCREENS.CONNECTION_COMPLETE]: undefined; [SCREENS.BANK_CONNECTION_COMPLETE]: undefined; - [SCREENS.SEARCH.ROOT]: { - q: SearchQueryString; - name?: string; - groupBy?: string; - }; }; type SearchReportParamList = { @@ -1855,6 +1846,17 @@ type SearchReportParamList = { }; }; +type SearchFullscreenNavigatorParamList = { + [SCREENS.SEARCH.ROOT]: { + q: SearchQueryString; + name?: string; + groupBy?: string; + }; + [SCREENS.SEARCH.MONEY_REQUEST_REPORT]: { + reportID: string; + }; +}; + type SearchAdvancedFiltersParamList = { [SCREENS.SEARCH.ADVANCED_FILTERS_RHP]: Record; }; @@ -1908,17 +1910,15 @@ type DebugParamList = { }; }; -type RootNavigatorParamList = PublicScreensParamList & AuthScreensParamList & LeftModalNavigatorParamList; - -type WorkspaceScreenName = keyof WorkspaceSplitNavigatorParamList; +type RootNavigatorParamList = PublicScreensParamList & AuthScreensParamList & LeftModalNavigatorParamList & SearchFullscreenNavigatorParamList; type OnboardingFlowName = keyof OnboardingModalNavigatorParamList; -type SplitNavigatorName = keyof SplitNavigatorParamListType; +type SplitNavigatorName = keyof SplitNavigatorParamList; -type SplitNavigatorScreenName = keyof (WorkspaceSplitNavigatorParamList & SettingsSplitNavigatorParamList & ReportsSplitNavigatorParamList); +type SearchFullscreenNavigatorName = typeof NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR; -type FullScreenName = SplitNavigatorName | typeof SCREENS.SEARCH.ROOT; +type FullScreenName = SplitNavigatorName | SearchFullscreenNavigatorName; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace @@ -1931,7 +1931,6 @@ declare global { export type { AddPersonalBankAccountNavigatorParamList, AuthScreensParamList, - BackToAndForwardToParms, BackToParams, DebugParamList, DetailsNavigatorParamList, @@ -1970,14 +1969,14 @@ export type { SearchAdvancedFiltersParamList, SearchReportParamList, SearchSavedSearchParamList, + SearchFullscreenNavigatorParamList, SettingsNavigatorParamList, SettingsSplitNavigatorParamList, SignInNavigatorParamList, SplitDetailsNavigatorParamList, SplitNavigatorBySidebar, SplitNavigatorName, - SplitNavigatorParamListType, - SplitNavigatorScreenName, + SplitNavigatorParamList, SplitNavigatorSidebarScreen, StackNavigationAction, State, @@ -1988,7 +1987,6 @@ export type { TravelNavigatorParamList, WalletStatementNavigatorParamList, WelcomeVideoModalNavigatorParamList, - WorkspaceScreenName, WorkspaceSplitNavigatorParamList, MigratedUserModalNavigatorParamList, WorkspaceConfirmationNavigatorParamList, diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 1bd45ee8ea619..d711a89b1d8e8 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -20,10 +20,10 @@ import type {IOUAction, IOUType, OnboardingPurpose} from '@src/CONST'; import CONST from '@src/CONST'; import type {ParentNavigationSummaryParams} from '@src/languages/params'; import type {TranslationPaths} from '@src/languages/types'; +import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; -import SCREENS from '@src/SCREENS'; import type { Beta, OnyxInputOrEntry, @@ -4711,7 +4711,7 @@ function navigateBackOnDeleteTransaction(backRoute: Route | undefined, isFromRHP const rootState = navigationRef.current?.getRootState(); const lastFullScreenRoute = rootState?.routes.findLast((route) => isFullScreenName(route.name)); - if (lastFullScreenRoute?.name === SCREENS.SEARCH.ROOT) { + if (lastFullScreenRoute?.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR) { Navigation.dismissModal(); return; } diff --git a/src/pages/Search/SearchMoneyRequestReportPage.tsx b/src/pages/Search/SearchMoneyRequestReportPage.tsx new file mode 100644 index 0000000000000..922ee515b6c3e --- /dev/null +++ b/src/pages/Search/SearchMoneyRequestReportPage.tsx @@ -0,0 +1,117 @@ +import React from 'react'; +import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; +import HeaderGap from '@components/HeaderGap'; +import MoneyReportHeader from '@components/MoneyReportHeader'; +import BottomTabBar from '@components/Navigation/BottomTabBar'; +import BOTTOM_TABS from '@components/Navigation/BottomTabBar/BOTTOM_TABS'; +import TopBar from '@components/Navigation/TopBar'; +import ScreenWrapper from '@components/ScreenWrapper'; +import type {SearchQueryJSON} from '@components/Search/types'; +import useLocalize from '@hooks/useLocalize'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import useThemeStyles from '@hooks/useThemeStyles'; +import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; +import type {SearchFullscreenNavigatorParamList} from '@libs/Navigation/types'; +import {buildSearchQueryJSON} from '@libs/SearchQueryUtils'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type SCREENS from '@src/SCREENS'; +import type * as OnyxTypes from '@src/types/onyx'; +import SearchTypeMenu from './SearchTypeMenu'; + +type SearchPageProps = PlatformStackScreenProps; + +// We will figure out later, when this view is actually being finalized, how to pass down an actual query +const tempJSONQuery = buildSearchQueryJSON('') as unknown as SearchQueryJSON; + +type TemporaryMoneyRequestReportViewProps = { + /** The report */ + report: OnyxEntry; + + /** The policy tied to the expense report */ + policy: OnyxEntry; +}; + +/** + * TODO + * This is a completely temporary component, displayed to: + * - show other devs that SearchMoneyRequestReportPage works + * - unblock work for other devs for Report Creation (https://github.com/Expensify/App/issues/57654) + * + * This component is not displayed to any users. + * It will be removed once we fully implement SearchMoneyRequestReportPage (https://github.com/Expensify/App/issues/57508) + */ +function TemporaryMoneyRequestReportView({report, policy}: TemporaryMoneyRequestReportViewProps) { + const styles = useThemeStyles(); + return ( + + + {}} + /> + + ); +} + +function SearchMoneyRequestReportPage({route}: SearchPageProps) { + const {translate} = useLocalize(); + const {shouldUseNarrowLayout} = useResponsiveLayout(); + const styles = useThemeStyles(); + + const {reportID} = route.params; + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {allowStaleData: true}); + const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {allowStaleData: true, initialValue: {}}); + const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`]; + + if (shouldUseNarrowLayout) { + return ( + + + + ); + } + + return ( + + + + + + + + + + + + + + ); +} + +SearchMoneyRequestReportPage.displayName = 'SearchMoneyRequestReportPage'; + +export default SearchMoneyRequestReportPage; diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx index b8454ed20dfac..b3f1a218b2249 100644 --- a/src/pages/Search/SearchPage.tsx +++ b/src/pages/Search/SearchPage.tsx @@ -15,10 +15,9 @@ import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import {turnOffMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; -import FreezeWrapper from '@libs/Navigation/AppNavigator/FreezeWrapper'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; -import type {AuthScreensParamList} from '@libs/Navigation/types'; +import type {SearchFullscreenNavigatorParamList} from '@libs/Navigation/types'; import {buildCannedSearchQuery, buildSearchQueryJSON, getPolicyIDFromSearchQuery} from '@libs/SearchQueryUtils'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -26,7 +25,7 @@ import type SCREENS from '@src/SCREENS'; import SearchPageNarrow from './SearchPageNarrow'; import SearchTypeMenu from './SearchTypeMenu'; -type SearchPageProps = PlatformStackScreenProps; +type SearchPageProps = PlatformStackScreenProps; function SearchPage({route}: SearchPageProps) { const {translate} = useLocalize(); @@ -52,19 +51,23 @@ function SearchPage({route}: SearchPageProps) { if (shouldUseNarrowLayout) { return ( - - - + ); } return ( - + )} - + ); } diff --git a/src/pages/Search/SearchPageNarrow.tsx b/src/pages/Search/SearchPageNarrow.tsx index 6e207808de042..c4bd7afadac65 100644 --- a/src/pages/Search/SearchPageNarrow.tsx +++ b/src/pages/Search/SearchPageNarrow.tsx @@ -30,14 +30,14 @@ const TOO_CLOSE_TO_TOP_DISTANCE = 10; const TOO_CLOSE_TO_BOTTOM_DISTANCE = 10; const ANIMATION_DURATION_IN_MS = 300; -type SearchPageBottomTabProps = { +type SearchPageNarrowProps = { queryJSON?: SearchQueryJSON; policyID?: string; searchName?: string; shouldGroupByReports?: boolean; }; -function SearchPageNarrow({queryJSON, policyID, searchName, shouldGroupByReports}: SearchPageBottomTabProps) { +function SearchPageNarrow({queryJSON, policyID, searchName, shouldGroupByReports}: SearchPageNarrowProps) { const {translate} = useLocalize(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const {windowHeight} = useWindowDimensions(); diff --git a/tests/navigation/GoBackTests.tsx b/tests/navigation/GoBackTests.tsx index 4e750a7273ffa..cf2a9d6e60b34 100644 --- a/tests/navigation/GoBackTests.tsx +++ b/tests/navigation/GoBackTests.tsx @@ -261,7 +261,15 @@ describe('Go back on the narrow layout', () => { }, }, { - name: SCREENS.SEARCH.ROOT, + name: NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR, + state: { + index: 0, + routes: [ + { + name: SCREENS.SEARCH.ROOT, + }, + ], + }, }, ], }} @@ -270,7 +278,7 @@ describe('Go back on the narrow layout', () => { const rootStateBeforeGoBack = navigationRef.current?.getRootState(); expect(rootStateBeforeGoBack?.index).toBe(2); - expect(rootStateBeforeGoBack?.routes.at(-1)?.name).toBe(SCREENS.SEARCH.ROOT); + expect(rootStateBeforeGoBack?.routes.at(-1)?.name).toBe(NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR); // When go back to the page present in the split navigator that is more than 1 route away act(() => { diff --git a/tests/navigation/NavigateTests.tsx b/tests/navigation/NavigateTests.tsx index 51aa2e2efeb60..ec10a45e08ff8 100644 --- a/tests/navigation/NavigateTests.tsx +++ b/tests/navigation/NavigateTests.tsx @@ -154,9 +154,17 @@ describe('Navigate', () => { index: 0, routes: [ { - name: SCREENS.SEARCH.ROOT, - params: { - q: 'type:expense status:all sortBy:date sortOrder:desc policyID:1', + name: NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR, + state: { + index: 0, + routes: [ + { + name: SCREENS.SEARCH.ROOT, + params: { + q: 'type:expense status:all sortBy:date sortOrder:desc policyID:1', + }, + }, + ], }, }, ], @@ -167,7 +175,7 @@ describe('Navigate', () => { const rootStateBeforeNavigate = navigationRef.current?.getRootState(); const lastSplitBeforeNavigate = rootStateBeforeNavigate?.routes.at(-1); expect(rootStateBeforeNavigate?.index).toBe(0); - expect(lastSplitBeforeNavigate?.name).toBe(SCREENS.SEARCH.ROOT); + expect(lastSplitBeforeNavigate?.name).toBe(NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR); // When navigate to the Home page when the active workspace is set act(() => { diff --git a/tests/navigation/SwitchPolicyIDTests.tsx b/tests/navigation/SwitchPolicyIDTests.tsx index 0cc11d173db93..879a5e6f43d26 100644 --- a/tests/navigation/SwitchPolicyIDTests.tsx +++ b/tests/navigation/SwitchPolicyIDTests.tsx @@ -71,7 +71,8 @@ describe('Switch policy ID', () => { expect(lastRouteAfterSwitch?.params).toMatchObject({policyID: '1'}); }); - it('from the Search page', () => { + // Fixme fix as a followup to https://github.com/Expensify/App/issues/57508 once more important things are done + it.skip('from the Search page', () => { // Given the initialized navigation on the narrow layout with the search page without the active workspace render( { index: 0, routes: [ { - name: SCREENS.SEARCH.ROOT, - params: { - q: 'type:expense status:all sortBy:date sortOrder:desc', + name: NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR, + state: { + index: 0, + routes: [ + { + name: SCREENS.SEARCH.ROOT, + params: { + q: 'type:expense status:all sortBy:date sortOrder:desc', + }, + }, + ], }, }, ], @@ -92,7 +101,7 @@ describe('Switch policy ID', () => { const rootStateBeforeSwitch = navigationRef.current?.getRootState(); expect(rootStateBeforeSwitch?.index).toBe(0); const lastRouteBeforeSwitch = rootStateBeforeSwitch?.routes?.at(-1); - expect(lastRouteBeforeSwitch?.name).toBe(SCREENS.SEARCH.ROOT); + expect(lastRouteBeforeSwitch?.name).toBe(NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR); expect(lastRouteBeforeSwitch?.params).toMatchObject({q: 'type:expense status:all sortBy:date sortOrder:desc'}); // When switch to the specific policy from the Search page @@ -157,7 +166,8 @@ describe('Switch policy ID', () => { expect(lastRouteAfterSwitch?.params).toMatchObject({policyID: undefined}); }); - it('from the Search page', () => { + // Fixme fix as a followup to https://github.com/Expensify/App/issues/57508 once more important things are done + it.skip('from the Search page', () => { // Given the initialized navigation on the narrow layout with the search page without the active workspace render( { index: 0, routes: [ { - name: SCREENS.SEARCH.ROOT, - params: { - q: 'type:expense status:all sortBy:date sortOrder:desc policyID:1', + name: NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR, + state: { + index: 0, + routes: [ + { + name: SCREENS.SEARCH.ROOT, + params: { + q: 'type:expense status:all sortBy:date sortOrder:desc policyID:1', + }, + }, + ], }, }, ], diff --git a/tests/utils/TestNavigationContainer.tsx b/tests/utils/TestNavigationContainer.tsx index 9f19ca4658a0e..518ab8205d8c5 100644 --- a/tests/utils/TestNavigationContainer.tsx +++ b/tests/utils/TestNavigationContainer.tsx @@ -4,7 +4,8 @@ import React from 'react'; import createRootStackNavigator from '@libs/Navigation/AppNavigator/createRootStackNavigator'; import createSplitNavigator from '@libs/Navigation/AppNavigator/createSplitNavigator'; import navigationRef from '@libs/Navigation/navigationRef'; -import type {AuthScreensParamList, ReportsSplitNavigatorParamList, SettingsSplitNavigatorParamList} from '@libs/Navigation/types'; +import type {AuthScreensParamList, ReportsSplitNavigatorParamList, SearchFullscreenNavigatorParamList, SettingsSplitNavigatorParamList} from '@libs/Navigation/types'; +import createPlatformStackNavigator from '@navigation/PlatformStackNavigation/createPlatformStackNavigator'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; import SCREENS from '@src/SCREENS'; @@ -12,6 +13,9 @@ import SCREENS from '@src/SCREENS'; const RootStack = createRootStackNavigator(); const ReportsSplit = createSplitNavigator(); const SettingsSplit = createSplitNavigator(); +const SearchStack = createPlatformStackNavigator(); + +const getEmptyComponent = () => jest.fn(); type TestNavigationContainerProps = {initialState: InitialState}; @@ -24,11 +28,11 @@ function TestReportsSplitNavigator() { > jest.fn()} + getComponent={getEmptyComponent} /> jest.fn()} + getComponent={getEmptyComponent} /> ); @@ -43,24 +47,39 @@ function TestSettingsSplitNavigator() { > jest.fn()} + getComponent={getEmptyComponent} /> jest.fn()} + getComponent={getEmptyComponent} /> jest.fn()} + getComponent={getEmptyComponent} /> jest.fn()} + getComponent={getEmptyComponent} /> ); } +function TestSearchFullscreenNavigator() { + return ( + + + + + ); +} + function TestNavigationContainer({initialState}: TestNavigationContainerProps) { return ( jest.fn()} + name={NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR} + component={TestSearchFullscreenNavigator} />