Onboarding - RHP Opens Multiple Concierge Pages Instead of Existing Tab
If you havenβt already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!
Version Number: v9.2.87-0 Reproducible in staging?: Yes Reproducible in production?: No If this was caught during regression testing, add the test name, ID and link from BrowserStack: https://github.com/Expensify/App/pull/78352 Email or phone of affected tester (no customers): [email protected] Issue reported by: Applause Internal Team Bug source: Exploratory - Critical User Impact Device used: Windows 10 /Chrome App Component: Other
Action Performed:
- Navigate to http://staging.new.expensify.com/r/6177391126570771
- Click Concierge.
- Sign in.
- Click Concierge in header again.
- Click RHP Sign in again.
- Click RHP back arrow 2 times.
Expected Result:
When RHP is clicked, it should open the first existing Concierge tab/page.
Actual Result:
When RHP is clicked, multiple Concierge pages open repeatedly instead of returning to the first open Concierge page.
Workaround:
Unknown
Platforms:
- [ ] Android: App
- [ ] Android: mWeb Chrome
- [ ] iOS: App
- [ ] iOS: mWeb Safari
- [ ] iOS: mWeb Chrome
- [x] Windows: Chrome
- [ ] MacOS: Chrome / Safari
Screenshots/Videos
https://github.com/user-attachments/assets/4a2fc1df-2375-4e09-bdb1-4c05e224a253
You have been assigned to this deploy blocker because you recently merged this PR: https://github.com/Expensify/App/pull/78352
π¬ A slack conversation has been started in #expensify-open-source
:wave: Friendly reminder that deploy blockers are time-sensitive β± issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:
- Identify the pull request that introduced this issue and revert it.
- Find someone who can quickly fix the issue.
- Fix the issue yourself.
Everybody was OOO, so I assigned 10 random eligible people.
Proposal
Please re-state the problem that we are trying to solve in this issue.
In the Help/Concierge right-hand panel, alternating between different entry points (e.g., Concierge profile area β Sign In β Concierge profile area β Sign In) causes the right-hand panel history to grow unnecessarily. Users then need to press Back many times to return to the prior panel(s).
What is the root cause of that problem?
Each click navigates to a new right-hand panel destination by adding a new entry to the panel stack, even if that destination is already present in the current panel history. Alternating between two destinations therefore creates repeated duplicates (A β B β A β B).
What changes do you think we should make in order to solve the problem?
- Add a navigation helper in
src/libs/Navigation/Navigation.ts(e.g.,navigateOrPopToExisting(route)) that:- checks whether the destination route already exists in the currently active nested navigator state (the right-hand panel stack),
- if it exists, pops back to that existing instance,
- otherwise navigates normally (so Back still works within the right-hand panel flow).
For example:
/**
* Navigate to a route, but if that route already exists in the currently active nested navigator state,
* pop back to the existing instance instead of pushing a duplicate.
*
* This is primarily useful for RHP flows (e.g. Search β Sign In β Profile) to keep back navigation intact
* while avoiding stacked duplicates when users tap entry points repeatedly.
*/
function navigateOrPopToExisting(route: Route, options?: GoBackOptions) {
if (!canNavigate('navigateOrPopToExisting', {route}) || !navigationRef.current) {
return;
}
const compareParams = options?.compareParams ?? defaultGoBackOptions.compareParams;
const rootState = navigationRef.current.getRootState();
const stateFromPath = getStateFromPath(route);
const action = getActionFromState(stateFromPath, linkingConfig.config);
if (!action) {
navigate(route);
return;
}
const {action: minimalAction, targetState} = getMinimalAction(action, rootState);
// If we can't identify a nested target state, fall back to normal navigation.
// In particular, we never want to pop within the root navigator to avoid removing full-screen routes.
if (minimalAction.type !== CONST.NAVIGATION.ACTION_TYPE.NAVIGATE || !targetState || isRootNavigatorState(targetState)) {
navigate(route);
return;
}
const indexOfTargetRoute = targetState.routes.findLastIndex((r) => doesRouteMatchToMinimalActionPayload(r, minimalAction, compareParams));
if (indexOfTargetRoute === -1) {
navigate(route);
return;
}
const distanceToPop = targetState.routes.length - indexOfTargetRoute - 1;
if (distanceToPop <= 0) {
return;
}
if (!compareParams) {
navigationRef.current.dispatch({...minimalAction, type: CONST.NAVIGATION.ACTION_TYPE.POP_TO});
return;
}
navigationRef.current.dispatch({...StackActions.pop(distanceToPop), target: targetState.key});
}
- Update the following entry points to use that helper:
- Anonymous Sign In button path:
signOutAndRedirectToSignIn()insrc/libs/actions/Session/index.ts(routeROUTES.SIGN_IN_MODAL)- https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/libs/actions/Session/index.ts#L299
- Concierge profile/details path:
navigateToDetailsPage()insrc/libs/ReportUtils.ts(routesROUTES.PROFILE.../ROUTES.REPORT_WITH_ID_DETAILS...)- https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/libs/ReportUtils.ts#L6344
- https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/libs/ReportUtils.ts#L6349
- Anonymous Sign In button path:
What alternative solutions did you explore? (Optional)
N/A
π£ @ubaidsk! π£ Hey, it seems we donβt have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork. Please follow these steps:
- Make sure you've read and understood the contributing guidelines.
- Get the email address used to login to your Expensify account. If you don't already have an Expensify account, create one here. If you have multiple accounts (e.g. one for testing), please use your main account email.
- Get the link to your Upwork profile. It's necessary because we only pay via Upwork. You can access it by logging in, and then clicking on your name. It'll look like this. If you don't already have an account, sign up for one here.
- Copy the format below and paste it in a comment on this issue. Replace the placeholder text with your actual details.
Format:
Contributor details
Your Expensify account email: <REPLACE EMAIL HERE>
Upwork Profile Link: <REPLACE LINK HERE>
Contributor details Your Expensify account email: [email protected] Upwork Profile Link: https://www.upwork.com/freelancers/~01eb90b457e55ca9a4
β Contributor details stored successfully. Thank you for contributing to Expensify!
ah, I think this is not a deploy blocker because it should not appear on production yet, right @marcochavezf ?
Yup, exactly not a blocker because it's hidden in production