Migrate money request merchant, description and date steps to dynamic - #98393
Migrate money request merchant, description and date steps to dynamic#98393suneox wants to merge 2 commits into
Conversation
… routes
Replaces the legacy `backTo` param on MONEY_REQUEST_STEP_MERCHANT,
MONEY_REQUEST_STEP_DESCRIPTION and MONEY_REQUEST_STEP_DATE with dynamic routes,
following the MONEY_REQUEST_STEP_TAX_RATE query-param template.
- add `expense-merchant`, `expense-description` and `expense-date` entries to
DYNAMIC_ROUTES and drop the static route definitions
- rename the pages to Dynamic* and resolve the back path with useDynamicBackPath
- register the new DYNAMIC_STEP_* screens in the linking config, navigation types,
modal stack navigator and the step HOC unions
- update every call site (confirmation list fields, MoneyRequestView,
SplitExpenseEditPage) to createDynamicRoute
- add OldRoutes redirects (with the optional reportActionID variants) and unit tests
Part 1 of Expensify#83852.
9cc060c to
42ab058
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9cc060c0cd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| }, | ||
| MONEY_REQUEST_STEP_MERCHANT: { | ||
| path: 'expense-merchant', | ||
| entryScreens: [ |
There was a problem hiding this comment.
Include split bill details in the dynamic entry screens
When the original actor can still edit an incomplete split bill, DynamicSplitBillDetailsPage renders MoneyRequestConfirmationList with editable Merchant/Description/Date rows; these rows now navigate by appending expense-* to the current /r/:reportID/split/:reportActionID URL. The dynamic route parser only accepts that suffix if the base focused screen is in entryScreens, but these new allow-lists omit SCREENS.SPLIT_DETAILS.DYNAMIC_ROOT, so those taps from split bill details fall through to the normal parser/not-found instead of opening the edit step. Please add the split details screen to the new merchant/description/date dynamic route entry screens.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Issue can not reproduce and behavior still the same latest staging
CleanShot.2026-08-12.at.12.19.23.1.mp4
There was a problem hiding this comment.
Issue found while editing split expense.
CleanShot.2026-08-12.at.13.00.53.1.mp4
And fixed
CleanShot.2026-08-12.at.13.15.35.1.mp4
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
… and date steps An incomplete split bill still renders `MoneyRequestConfirmationList` with editable Merchant/Description/Date rows for its original actor, so those taps append the `expense-*` suffix to `/r/:reportID/split/:reportActionID`. Without the split details screen in `entryScreens`, `getStateFromPath` rejects the suffix and the app falls through to `/not-found`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / Safari |
Explanation of Change
Part 1 of #83852 migrates three money request steps off the legacy
backToparam and onto dynamic routes:MONEY_REQUEST_STEP_MERCHANT(expense-merchant),MONEY_REQUEST_STEP_DESCRIPTION(expense-description) andMONEY_REQUEST_STEP_DATE(expense-date). Each one follows the query-param template already used byMONEY_REQUEST_STEP_TAX_RATE/MONEY_REQUEST_STEP_TAGonmain: the params that used to live in the path (action,iouType,transactionID,reportID, optionalreportActionID) become query params of the dynamic suffix, the page is renamed toDynamic*and resolves its back destination withuseDynamicBackPathinstead of readingroute.params.backTo.Every call site (the confirmation list merchant/description/date fields,
MoneyRequestViewandSplitExpenseEditPage) now navigates withcreateDynamicRoute, and every screen those taps come from is listed inentryScreensso no entry point is silently blocked. The suffixes are namespacedexpense-*because dynamic route paths must be globally unique and baredescription/date-selectare already taken.OldRoutes.tskeeps the legacy URLs working (with a dedicated longer pattern for the optionalreportActionIDsegment), covered by new unit tests intests/navigation/getMatchingNewRouteTest.ts.Fixed Issues
$ #83852
PROPOSAL:
Tests
DYNAMIC_ROUTES.MONEY_REQUEST_STEP_MERCHANT— edit the merchant of an expenseCase 1.1 — Confirmation page → Merchant → save → back
Target:
src/components/MoneyRequestConfirmationList/sections/MerchantField.tsx:138Precondition: you are on the Confirmation step of a new expense sent to a workspace chat.
<confirmation-url>/expense-merchant?action=create&iouType=submit&transactionID=…&reportID=…and the Merchant page opens.Case 1.2 — Expense report view (RHP) → Merchant → save → back
Target:
src/components/ReportActionItem/MoneyRequestView.tsx:1280/expense-merchant?action=edit&iouType=…&transactionID=…&reportID=…appended.Case 1.3 — Header back button (no save)
Target:
src/pages/iou/request/step/DynamicIOURequestStepMerchant.tsx/not-foundpage appears.Case 1.4 — Refresh / deep link
Case 1.5 — Legacy URL redirect
Target:
src/libs/Navigation/linkingConfig/OldRoutes.tstransactionIDandreportIDof an expense./edit/submit/merchant/<transactionID>/<reportID>./r/<reportID>/expense-merchant?action=edit&iouType=submit&transactionID=<transactionID>&reportID=<reportID>and renders the Merchant page (no/not-found)./edit/submit/merchant/<transactionID>/<reportID>/<reportActionID>and verify the new URL also carries&reportActionID=….Case 1.6 — Save while offline
DYNAMIC_ROUTES.MONEY_REQUEST_STEP_DESCRIPTION— edit the description of an expenseCase 2.1 — Confirmation page → Description → save → back
Target:
src/components/MoneyRequestConfirmationList/sections/DescriptionField.tsx:151/expense-description?action=create&iouType=submit&transactionID=…&reportID=…appended.Case 2.2 — Expense report view (RHP) → Description → save → back
Target:
src/components/ReportActionItem/MoneyRequestView.tsx:1254/expense-description?action=edit&…appended and the Description page opens.Case 2.3 — Split expense edit → Description → back
Target:
src/pages/iou/SplitExpenseEditPage.tsx:332Precondition: an expense in the Split expense flow.
/expense-description?action=edit&iouType=split-expense&transactionID=<OPTIMISTIC_TRANSACTION_ID>&reportID=…appended.Case 2.4 — Refresh / deep link
Case 2.5 — Legacy URL redirect
/edit/submit/description/<transactionID>/<reportID>./r/<reportID>/expense-description?action=edit&iouType=submit&transactionID=…&reportID=…and renders the Description page./r/<reportID>/description(report description) and verify it still opens the report description page, unaffected by the new mapping.DYNAMIC_ROUTES.MONEY_REQUEST_STEP_DATE— edit the date of an expenseCase 3.1 — Confirmation page → Date → pick a date → back
Target:
src/components/MoneyRequestConfirmationList/sections/DateField.tsx:154/expense-date?action=create&iouType=submit&transactionID=…&reportID=…appended.Case 3.2 — Expense report view (RHP) → Date → back
Target:
src/components/ReportActionItem/MoneyRequestView.tsx:1305/expense-date?action=edit&…appended.Case 3.3 — Split expense edit → Date → back
Target:
src/pages/iou/SplitExpenseEditPage.tsx:435/expense-date?action=edit&iouType=split-expense&…appended.Case 3.4 — Refresh / deep link
Case 3.5 — Legacy URL redirect
/edit/submit/date/<transactionID>/<reportID>./r/<reportID>/expense-date?action=edit&iouType=submit&transactionID=…&reportID=…and renders the Date page.Cross-cutting — entry allow-list and no regression on similarly named routes
Case 4.1 — Entry from Search / expense report view
Target:
src/ROUTES.ts(entryScreensof the three new dynamic routes)/not-found), which provesentryScreensis complete.Case 4.2 — No regression on similarly named routes
/r/<reportID>/descriptionis unchanged.Case 4.3 — Automated tests
tests/navigationsuite is 42 suites / 488 tests passing).Offline tests
QA Steps
Test case 1: Edit the merchant of an expense from the confirmation page
/expense-merchant?action=create&iouType=submit&transactionID=...&reportID=....expense-merchant, and the merchant row shows the new value.Test case 2: Edit the description of an expense from the expense detail
/expense-description?action=edit&iouType=...&transactionID=...&reportID=....Test case 3: Edit the date of an expense from the expense detail
/expense-date?action=edit&iouType=...&transactionID=...&reportID=....Test case 4: Open merchant, description and date from an expense report
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
CleanShot.2026-08-12.at.12.11.20.1.mp4
Case 1.1 — Confirmation page → Merchant → save → back
Case 1.2 — Expense report view (RHP) → Merchant → save → back
Case 1.3 — Header back button (no save)
Case 1.4 — Refresh / deep link
Case 1.5 — Legacy URL redirect
Case 1.6 — Save while offline
Case 2.1 — Confirmation page → Description → save → back
Case 2.2 — Expense report view (RHP) → Description → save → back
Case 2.3 — Split expense edit → Description → back
Case 2.4 — Refresh / deep link
Case 2.5 — Legacy URL redirect
Case 3.1 — Confirmation page → Date → pick a date → back
Case 3.2 — Expense report view (RHP) → Date → back
Case 3.3 — Split expense edit → Date → back
Case 3.4 — Refresh / deep link
Case 3.5 — Legacy URL redirect
Case 4.1 — Entry from Search / expense report view
Case 4.2 — No regression on similarly named routes