Skip to content

Report details - Not found page opened when clicking admin report header - #96888

Open
lorretheboy wants to merge 7 commits into
Expensify:mainfrom
lorretheboy:fix/94977
Open

Report details - Not found page opened when clicking admin report header#96888
lorretheboy wants to merge 7 commits into
Expensify:mainfrom
lorretheboy:fix/94977

Conversation

@lorretheboy

@lorretheboy lorretheboy commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Explanation of Change

Fixed Issues

$ #94977
PROPOSAL: #94977 (comment)

Tests

  1. Open ND (desktop web)
  2. Login with new account without + iteration
  3. In onboarding steps, choose "Manage my team's expenses" > "1-4 employees" > "QuickBooks Online" > set the NVP in the console Onyx.merge('nvp_onboardingRHPVariant') > Click "Continue"
  4. Click on dropdown icon on admin room header
  5. Verify that Admin room details should open
  • Verify that no errors appear in the JS console

Offline tests

QA Steps

  1. Open ND (desktop web)
  2. Login with new account without + iteration
  3. In onboarding steps, choose "Manage my team's expenses" > "1-4 employees" > "QuickBooks Online" > set the NVP in the console Onyx.merge('nvp_onboardingRHPVariant') > Click "Continue"
  4. Click on dropdown icon on admin room header
  5. Verify that Admin room details should open
  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Screen.Recording.2026-07-27.at.22.05.50.mov
Android: mWeb Chrome
Screen.Recording.2026-07-24.at.17.57.52.mov
iOS: Native
Screen.Recording.2026-07-24.at.17.54.39.mov
iOS: mWeb Safari
Screen.Recording.2026-07-24.at.17.56.17.mov
MacOS: Chrome / Safari
96888.mov

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.

Files with missing lines Coverage Δ
src/components/AvatarWithDisplayName.tsx 80.61% <100.00%> (+0.19%) ⬆️
src/libs/ReportUtils.ts 86.91% <100.00%> (+0.77%) ⬆️
src/pages/inbox/HeaderView.tsx 96.93% <ø> (-0.04%) ⬇️
src/pages/inbox/report/ReportActionItemCreated.tsx 97.72% <100.00%> (+0.05%) ⬆️
.../components/MoneyRequestHeaderSecondaryActions.tsx 0.50% <0.00%> (-0.01%) ⬇️
...eaderActions/MoneyReportHeaderSecondaryActions.tsx 0.65% <0.00%> (-0.01%) ⬇️
... and 691 files with indirect coverage changes

@marufsharifi

Copy link
Copy Markdown
Contributor

@lorretheboy any estimation?

@lorretheboy

lorretheboy commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

As I said earlier in the issue #94977 (comment), I will try to open it for review today @marufsharifi

@marufsharifi

Copy link
Copy Markdown
Contributor

@lorretheboy, do you need any help here?

@lorretheboy

Copy link
Copy Markdown
Contributor Author

@marufsharifi No need helps here, I will open for review in 1 hour

@lorretheboy
lorretheboy marked this pull request as ready for review July 24, 2026 11:05
@lorretheboy
lorretheboy requested review from a team as code owners July 24, 2026 11:05
@melvin-bot
melvin-bot Bot requested review from joekaufmanexpensify and marufsharifi and removed request for a team July 24, 2026 11:05
@melvin-bot

melvin-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

@marufsharifi Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@melvin-bot
melvin-bot Bot removed request for a team and joekaufmanexpensify July 24, 2026 11:05
@lorretheboy

Copy link
Copy Markdown
Contributor Author

Hey @marufsharifi, for android app recording, I will upload later as now I am having android build issue

@marufsharifi

marufsharifi commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified that the composer does not automatically focus or open the keyboard on mobile unless explicitly intended. This includes checking that returning the app from the background does not unexpectedly open the keyboard.
  • I verified tests pass on all platforms & I tested again on:
    • Android: HybridApp
    • Android: mWeb Chrome
    • iOS: HybridApp
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • For any bug fix or new feature in this PR, I verified that sufficient unit tests are included to prevent regressions in this flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp
Screen_Recording_20260725_104451_Expensify.Dev.mp4
Android: mWeb Chrome
Screen_Recording_20260725_104658_Chrome.mp4
iOS: HybridApp
Screen.Recording.2026-07-25.at.11.26.05.AM.mov
iOS: mWeb Safari
Screen.Recording.2026-07-25.at.11.29.36.AM.mov
MacOS: Chrome / Safari
Screen.Recording.2026-07-25.at.10.31.02.AM.mov

@marufsharifi

Copy link
Copy Markdown
Contributor

@lorretheboy, could you please merge the main, and upload android app record. thanks.

@marufsharifi

Copy link
Copy Markdown
Contributor

@lorretheboy, Gentle bump. thanks.

@lorretheboy

Copy link
Copy Markdown
Contributor Author

Will do it today

@lorretheboy

Copy link
Copy Markdown
Contributor Author

@marufsharifi I merged latest main & added android app recording

Comment thread src/libs/ReportUtils.ts
* rooms, …) rather than jumping to the report — see https://github.com/Expensify/App/pull/90113.
*/
function navigateToDetailsPage(report: OnyxEntry<Report>) {
function navigateToDetailsPage(report: OnyxEntry<Report>, isInSidePanel = false) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The new isInSidePanel flag is only applied to the REPORT_DETAILS branch, but the early PROFILE branch a few lines below still falls back to getActiveRoute():

if (isSelfDMReport || isOneOnOneChatReport) {
    Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.PROFILE.getRoute(participantAccountID.at(0))));
    return;
}

The Side Panel shows either the admins room (a chat room → hits the fixed branch ✅) or the concierge report (SidePanelContextProvider.tsx:94). Concierge is a chat report with no chat type and a single other participant, so isOneOnOneChat can return true for it — meaning clicking the concierge header from the Side Panel takes this PROFILE branch and can reproduce the same Not-found symptom this PR fixes (e.g. building /workspaces/<policyID>/overview/<profile-suffix>).

Since concierge is the default Side Panel content for non-admins / forceConcierge, this isn't an exotic path. Suggest threading the same flag here:

if (isSelfDMReport || isOneOnOneChatReport) {
    const basePath = isInSidePanel ? ROUTES.REPORT_WITH_ID.getRoute(report?.reportID) : undefined;
    Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.PROFILE.getRoute(participantAccountID.at(0)), basePath));
    return;
}

Could you verify how concierge details opens from the Side Panel? If it Not-founds, the above is the fix (plus a matching test case). If it opens cleanly today, a short test documenting that is enough.

Comment thread tests/unit/ReportUtilsNavigateToDetailsPageTest.ts
@marufsharifi

Copy link
Copy Markdown
Contributor

@MelvinBot review

@MelvinBot

Copy link
Copy Markdown
Contributor

Review — looks correct and well-scoped ✅

The fix correctly addresses the root cause. When a report is rendered in the Side Panel, SidePanelReport mounts ReportScreen with a synthetic route, so the report is never in the navigation state. During the RHP onboarding variant the active route is the workspace overview, and navigateToDetailsPage was building /workspaces/<policyID>/overview/details — which fails the REPORT_DETAILS.entryScreens check (it doesn't allow the workspace overview screen) → Not found. Anchoring the base path to r/<reportID> fixes it because SCREENS.REPORT is a valid entry screen.

Both the code and the test read well, and it's a nicely minimal change. A few things I checked and one thing worth a quick sanity-check:

Verification details
  • All call sites covered. navigateToDetailsPage has exactly 5 callers and all 5 now thread isInSidePanel: AvatarWithDisplayName, HeaderView, ReportActionItemCreated, MoneyRequestHeaderSecondaryActions, and MoneyReportHeaderSecondaryActions. All of these render under ReportScreen, which is wrapped by the IsInSidePanelContext.Provider value in SidePanelReport, so the hook returns true there. Good.
  • Backward compatible. isInSidePanel = false default means every non-side-panel caller keeps the exact old behavior (active-route anchoring), preserving the PR BT Migrate Report Core 1 #90113 intent for Search / workspace-room contexts.
  • createDynamicRoute short-circuit. When basePath is provided, basePath ?? Navigation.getActiveRoute() skips getActiveRoute(), so the test's expect(mockGetActiveRoute).not.toHaveBeenCalled() assertion is a valid guard. Nice touch.
  • Test coverage is solid: active-route context, Search-context regression guard, side-panel anchoring, and the no-reportID no-op.

One thing worth a quick check (not a blocker): the Side Panel report can also be the Concierge report (SidePanelContextProvider), which is a 1:1 chat. That hits the earlier isSelfDMReport || isOneOnOneChatReport branch in navigateToDetailsPage, which navigates to PROFILE without a base path, so it still falls back to the screen behind the panel. This won't Not-found because PROFILE has entryScreens: ['*'], but the resulting URL is still anchored to the workspace-overview route rather than the report/profile — worth confirming that opening Concierge details from the Side Panel behaves as expected (and, if desired, the same isInSidePanel base-path could be applied to the profile branch for consistency).

Everything else looks good and all CI checks are green.

@marufsharifi

Copy link
Copy Markdown
Contributor

@lorretheboy, could you please check the above comments

@lorretheboy

Copy link
Copy Markdown
Contributor Author

@marufsharifi Please check again

@marufsharifi

Copy link
Copy Markdown
Contributor

the changes works, i am reviewing the code changes.

@melvin-bot
melvin-bot Bot requested a review from inimaga August 1, 2026 18:58
inimaga
inimaga previously approved these changes Aug 3, 2026
@inimaga

inimaga commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@lorretheboy Could you cleanup the comments in the added test. They are too verbose and make references to issues and PRs that will be out of place for someone reading this codebase in the future.

@lorretheboy

Copy link
Copy Markdown
Contributor Author

@inimaga I removed those comments. Kindly check again

Comment thread src/libs/ReportUtils.ts
Comment on lines +6404 to +6409
* @param isInSidePanel - Whether the report is rendered inside the Side Panel. A Side Panel report is not part of the
* navigation state (`SidePanelReport` renders `ReportScreen` with a synthetic route), so the active route belongs to
* whichever screen sits behind the panel. In that case the destination (details or profile, since the Side Panel shows
* either the admins room or the 1:1 Concierge chat) has to be anchored to the report itself.
* Everywhere else the active route is used on purpose, so details opens within the current context (Search, workspace
* rooms, …) rather than jumping to the report — see https://github.com/Expensify/App/pull/90113.

@inimaga inimaga Aug 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lorretheboy One more suggested improvement to this doc section as it still references an external PR, which you can apply and we're good to merge.

Suggested change
* @param isInSidePanel - Whether the report is rendered inside the Side Panel. A Side Panel report is not part of the
* navigation state (`SidePanelReport` renders `ReportScreen` with a synthetic route), so the active route belongs to
* whichever screen sits behind the panel. In that case the destination (details or profile, since the Side Panel shows
* either the admins room or the 1:1 Concierge chat) has to be anchored to the report itself.
* Everywhere else the active route is used on purpose, so details opens within the current context (Search, workspace
* rooms, ) rather than jumping to the report see https://github.com/Expensify/App/pull/90113.
* Side Panel reports use a synthetic route that is not part of the navigation state, so navigation must be anchored to the report.
* Otherwise, the active route is preserved to keep the details page within its originating context.
*
* @param isInSidePanel - Whether the report is rendered inside the Side Panel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants