Skip to content

[Search Router] Surface Book Travel in Create suggestions - #99516

Merged
carlosmiceli merged 6 commits into
Expensify:mainfrom
nabi-ebrahimi:92752-search-router-travel-booking-action
Sep 1, 2026
Merged

carlosmiceli merged 6 commits into
Expensify:mainfrom
nabi-ebrahimi:92752-search-router-travel-booking-action

Conversation

@nabi-ebrahimi

@nabi-ebrahimi nabi-ebrahimi commented Aug 26, 2026 •

Copy link
Copy Markdown

Explanation of Change

Adds Book travel to the Search Router’s existing Create suggestions.

The action follows the same eligibility and navigation rules as the existing FAB travel item:

  • Uses only the active workspace.
  • Appears only when Travel is enabled for that workspace.
  • Opens TravelDot when the account and workspace are ready.
  • Otherwise opens the existing Travel/My Trips flow.
  • Uses the localized Book travel label and Suitcase icon.
  • Replaces an existing RHP instead of stacking another modal.
  • Keeps anonymous-user interception.
  • Leaves Quick Action excluded.

This reuses the existing Travel eligibility utilities and does not introduce new routes, translations, ranking rules, or navigation item types.

Fixed Issues

$ #92752
PROPOSAL: #92752 (comment)

Book Travel search matching

  1. Sign in with an active workspace that has Travel enabled.
  2. Open Search Router.
  3. Search for book travel.
  4. Repeat with BOOK TRAVEL, go to book travel, and go to book travel.
  5. Verify the Book travel action appears for every query.
  6. Verify the label does not have a Go to prefix.
  7. Verify the Suitcase icon is displayed.

Active workspace eligibility

  1. Have two workspaces, with Travel enabled in only one.
  2. Make the workspace without Travel active.
  3. Search for book travel.
  4. Verify Book travel is not shown.
  5. Make the Travel-enabled workspace active.
  6. Repeat the search.
  7. Verify Book travel is shown.

RHP replacement

  1. Open an existing RHP.
  2. Open Search Router and select Book travel.
  3. Verify the existing RHP closes before the Travel flow opens.
  4. Verify the RHPs do not stack.
  • Verify that no errors appear in the JS console

Offline tests

  1. Load a Travel-enabled workspace while online.
  2. Enable forced offline mode.
  3. Open Search Router and search for book travel.
  4. Verify the result uses the cached active workspace eligibility.
  5. Select the result.
  6. Verify it follows the existing offline Travel behavior without crashing or stacking RHPs.

QA Steps

Same as the Tests and Offline tests above.

// TODO: These must be filled out, or the issue title must include "[No QA]."

  • 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-08-26.at.2.29.14.PM.mov
Screen.Recording.2026-08-26.at.2.31.26.PM.mov
Android: mWeb Chrome
Screen_Recording_20260826_135540_Chrome.mp4
Screen_Recording_20260826_135717_Chrome.mp4
iOS: Native
Screen.Recording.2026-08-26.at.3.27.44.PM.mov
Screen.Recording.2026-08-26.at.3.29.25.PM.mov
iOS: mWeb Safari
Screen.Recording.2026-08-26.at.3.32.43.PM.mov
Screen.Recording.2026-08-26.at.3.34.08.PM.mov
MacOS: Chrome / Safari
Screen.Recording.2026-08-26.at.11.54.07.AM.mov
Screen.Recording.2026-08-26.at.12.03.59.PM.mov
Screen.Recording.2026-08-26.at.11.59.45.AM.mov

@melvin-bot
melvin-bot Bot requested review from flaviadefaria and marufsharifi and removed request for a team August 26, 2026 07:27
@melvin-bot

melvin-bot Bot commented Aug 26, 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 the request for review from a team August 26, 2026 07:27
@marufsharifi

Copy link
Copy Markdown

@nabi-ebrahimi, could you please check the above ai feedback. thanks.

@nabi-ebrahimi

Copy link
Copy Markdown
Author

@nabi-ebrahimi, could you please check the above ai feedback. thanks.

Done, thanks!

@marufsharifi marufsharifi left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good, just tow minor suggestions.

@nabi-ebrahimi

Copy link
Copy Markdown
Author

@marufsharifi I addressed all the comments can you please review again, Thanks.

@nabi-ebrahimi

Copy link
Copy Markdown
Author

@marufsharifi thanks for the detailed review. All applicable comments have been addressed, and I added the missing focused coverage. The remaining non-blocking suggestions were clarified with the current scope and existing Travel behavior in mind. Could you please take another look?

@nabi-ebrahimi

Copy link
Copy Markdown
Author

@marufsharifi kindly bump, thanks.

@marufsharifi

marufsharifi commented Aug 31, 2026 •

Copy link
Copy Markdown

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.2026-08-31.at.10.52.31.PM.mov
Android: mWeb Chrome
Screen.Recording.2026-08-31.at.11.53.42.PM.mov
iOS: HybridApp
Screen.Recording.2026-08-31.at.11.21.16.PM.mov
iOS: mWeb Safari
Screen.Recording.2026-08-31.at.11.27.35.PM.mov
MacOS: Chrome / Safari
Screen.Recording.2026-08-31.at.5.12.21.PM.mov
Screen.Recording.2026-08-31.at.5.13.53.PM.mov
Screen.Recording.2026-08-31.at.5.15.03.PM.mov

@marufsharifi marufsharifi left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM

@trjExpensify
trjExpensify removed the request for review from flaviadefaria September 1, 2026 11:52

@trjExpensify trjExpensify left a comment

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.

Core PR for the navigational search rollout. 👍

@carlosmiceli
carlosmiceli merged commit 6c72690 into Expensify:main Sep 1, 2026
36 of 38 checks passed
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

🚧 carlosmiceli has triggered a test Expensify/App build. You can view the workflow run here.

@OSBotify

OSBotify commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify OSBotify mentioned this pull request Sep 2, 2026
82 tasks done
@OSBotify

OSBotify commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/carlosmiceli in version: 9.4.66-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@MelvinBot

Copy link
Copy Markdown
Contributor

Yes — help site changes are required. Draft PR: #100107

Before this PR, the only documented way to reach Book travel was the ➕ Create button. Adding it to the Search Router's Create suggestions creates a second entry point that no help article mentions.

What changed in the docs PR (7 articles)

Article Change
docs/articles/new-expensify/getting-started/Navigating-New-Expensify.md New ## How to start an action using Search section plus 2 FAQ entries. This article already documented Search's navigation suggestions but never its Create suggestions, so Book travel had no home.
docs/articles/travel/booking-travel/ — Book-a-Flight, Book-a-Hotel, Book-a-Rental-Car, Book-Rail-Travel, Arrange-Travel-for-Another-User, Book-Travel-for-a-Guest Each shares an identical ## Where to find Expensify Travel block that listed only the ➕ Create button. Each now also lists the Search path.

I also corrected the "If you don't see Book travel" caveat in those 6 articles. It said Travel must be enabled on "the workspace"; both the FAB item and your new Search item gate on the active workspace (TravelMenuItem.tsx:35, useCreateNavigationSuggestions.ts:115), so the old wording was already imprecise.

How labels were verified, and two things you should check

Label verification. I tried to verify against the live UI on web, but the test session went blank (0 DOM nodes) before it could open Search, and a second attempt could not recover it. So labels come from src/languages/en.ts on main, which is what the UI renders: travel.bookTravel is 'Book travel'; the Create suggestion labels are Create expense, Create report, Track distance, Start chat, Send invoice, Book travel, New workspace. Phrasing for the Search entry point reuses what Navigating-New-Expensify.md already established — "Select Search (the magnifying glass icon)". Please confirm these against the UI when you review.

Intentionally out of scope. About 24 other docs/articles/travel/ articles carry a one-line "Click the + button in the bottom-left corner… then select Book travel" pointer. They're admin/config articles where the pointer is incidental, so I left them to keep the diff reviewable. Tell me if you want them updated too.

Could not assign the PR. nabi-ebrahimi is not assignable on Expensify/App — GitHub returns 404 for the assignees check because the account has read permission, and assignment requires push access. The PR has the HelpDot label, is a draft, and has PullerBear requested as reviewer. Someone with write access will need to add you as assignee.

@nabi-ebrahimi, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR Ready for review


view run

@OSBotify

OSBotify commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/carlosmiceli in version: 9.4.68-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 cancelled 🔪

@MelvinBot

Copy link
Copy Markdown
Contributor

Yes — help site changes are required. Draft PR: #100223

This PR adds a second way to start Book travel, but every travel article on the help site documents only one entry point: the ➕ Create button. It also introduces a rule that was never written down — Book travel only appears when Expensify Travel is enabled on the active workspace.

What the docs PR changes (7 files, docs/articles):

  • new-expensify/getting-started/Navigating-New-Expensify.md — this article already covers jumping to a destination from Search but not starting an action from it. Added a ## How to start an action using Search section plus two FAQ entries (Can I book travel from Search?, Why don't I see Book travel in Search?).
  • The six travel/booking-travel/ articles — each carries the same ## Where to find Expensify Travel block. Added one sentence giving Search as a second entry point, plus the active-workspace rule.

Scope note: the same boilerplate appears in ~25 other travel articles (travel policy, company setup, managing trips, analytics). I limited the PR to the booking articles to keep it reviewable — tell me if you want the sentence rolled out everywhere.

How the copy was verified

Written against docs/HELPSITE_NAMING_CONVENTIONS.md, docs/HELP_AUTHORING_GUIDELINES.md, and docs/TEMPLATE.md.

Labels checked against dev NewDot on web: the entry point's accessible name is exactly Search (magnifying glass icon), and the action rows read Create expense, Create report, Track distance, Start chat, New workspace.

Book travel could not be observed directly — the test account has no Travel-enabled workspace, so it appears in neither Search nor the ➕ Create menu, which is exactly what the eligibility rule predicts. Its label comes from travel.bookTravel in src/languages/en.ts (Book travel), the same string the ➕ Create button item uses.

One thing worth a second look: on main, the Search item gates on activePolicy?.isTravelEnabled while the ➕ Create button item now gates on isWorkspaceProvisionedForTravel(activePolicy?.travelSettings). The docs describe both as "Expensify Travel is enabled on your active workspace", which holds either way — but if those two checks are meant to stay in sync, they have drifted.

The draft PR is labelled HelpDot and has PullerBear requested. I could not assign you — GitHub rejects nabi-ebrahimi as an assignee on Expensify/App (repos/Expensify/App/assignees/nabi-ebrahimi returns 404). Once you comment on the PR you become assignable and it can be set.

@nabi-ebrahimi, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR Ready for review


view run

@OSBotify

OSBotify commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/francoisl in version: 9.4.68-1 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

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.

6 participants