Skip to content

feat: seed default My expenses saved search for dual-role users and remove obsolete rename tooltip - #93541

Merged
Valforte merged 32 commits into
Expensify:mainfrom
aswin-s:fix/issue-92780
Jul 24, 2026
Merged

feat: seed default My expenses saved search for dual-role users and remove obsolete rename tooltip#93541
Valforte merged 32 commits into
Expensify:mainfrom
aswin-s:fix/issue-92780

Conversation

@aswin-s

@aswin-s aswin-s commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Explanation of Change

Automatically creates a "My expenses" saved search (filtered to type:expense from:<currentUserAccountID>) for users who both submit and approve expenses. Seeding is gated by the nvp_hasSeededMyExpensesSearch NVP so it only fires once per account. This NVP is set server-side by SaveSearch and returned by OpenApp (backend support deployed via a separate Auth PR), so a deleted seed is not recreated — even after a fresh install, a full reconnect, or on another device. Also removes the now-obsolete Rename your saved searches here product training tooltip that would otherwise show to users with the new seeded search.

Fixed Issues

$ #92780
PROPOSAL: #92780 (comment)

Tests

  1. Log in with an account that is a member of at least one group workspace (submit-eligible) AND an approver on at least one paid workspace.
  2. Navigate to Search.
  3. Verify a "My expenses" entry appears in the Saved section of the left-hand nav, filtered to from:<your account ID>.
  4. Delete the "My expenses" saved search.
  5. Sign out, clear site storage (or use a second device / fresh install), and sign back in. Navigate to Search — verify "My expenses" does NOT reappear (the server-persisted nvp_hasSeededMyExpensesSearch returned by OpenApp prevents re-seeding).
  6. Log in with a submit-only or approve-only account — verify no "My expenses" saved search is seeded.
  7. Verify the "Rename your saved searches here" tooltip no longer appears anywhere in the Search section.
  • Verify that no errors appear in the JS console

Offline tests

The seed uses the existing saveSearch API write path which has optimistic data + failure rollback. Offline behavior is identical to manually saving a search offline — the entry appears optimistically and syncs when back online.

QA Steps

Same as tests

  • 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 any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • 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 shown in the product is localized by adding it to src/languages/* files and using the translation method
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • 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)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • 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)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • 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.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • 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
android.mp4
Android: mWeb Chrome
android-web.mp4
iOS: Native
ios.mp4
iOS: mWeb Safari
ios-web.mp4
MacOS: Chrome / Safari
Mac.web.mp4

@melvin-bot

melvin-bot Bot commented Jun 14, 2026

Copy link
Copy Markdown

Hey, I noticed you changed src/languages/en.ts in a PR from a fork. For security reasons, translations are not generated automatically for PRs from forks.

If you want to automatically generate translations for other locales, an Expensify employee will have to:

  1. Look at the code and make sure there are no malicious changes.
  2. Run the Generate static translations GitHub workflow. If you have write access and the K2 extension, you can simply click: [this button]

Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running:

npx ts-node ./scripts/generateTranslations.ts --help

Typically, you'd want to translate only what you changed by running npx ts-node ./scripts/generateTranslations.ts --compare-ref main

aswin-s added 4 commits June 14, 2026 10:46
…acking plumbing

- Replace isGroupPolicy with isPolicyUser for submitter check so admins are not
  incorrectly counted as submitters in seedMyExpensesSearch eligibility logic
- Remove areAllSectionsExpanded prop from SavedSearchList and the entire
  collapsedSectionCount/onCollapsed chain from SearchTypeMenuWide, which existed
  solely to gate the now-removed RENAME_SAVED_SEARCH tooltip
- Remove unused buildCannedSearchQuery import from Search.ts
- Eliminate redundant saveSearchName variable in seedMyExpensesSearch
- Fix OnyxUpdate missing type argument on optimistic/failure/success arrays
- Remove stray blank line in CONST after RENAME_SAVED_SEARCH removal
- Extract eligibility logic from SavedSearchList useEffect into
  isDualRoleUser(policies, email) in PolicyUtils so it is testable
  and reusable
- Remove savedSearches from useEffect dep array — it was only used as
  a load guard but caused an infinite retry loop when failureData nulled
  the hash key and reset the NVP, re-triggering the effect
- Replace the load guard with allPolicies === undefined which is the
  only collection needed for eligibility
- Add 11 unit tests in seedMyExpensesSearchTest.ts covering:
  - isDualRoleUser: submit+approve, submit-only, approve-only, admin
    role, optional approval mode, null/empty inputs
  - seedMyExpensesSearch: Onyx write, query format (type/from), NVP gate
- Reformat DismissedProductTraining.ts (Prettier: double→single quotes, 4-space indent)
- Replace removed RENAME_SAVED_SEARCH tooltip with GPS_TOOLTIP in ProductTrainingContextProvider tests
- Remove the wide-layout-specific test case since RENAME_SAVED_SEARCH was the only wide-layout-only tooltip
@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ Changes either increased or maintained existing code coverage, great job!

Files with missing lines Coverage Δ
src/CONST/index.ts 94.81% <ø> (ø)
src/ONYXKEYS.ts 100.00% <ø> (ø)
src/components/ProductTrainingContext/TOOLTIPS.ts 31.25% <ø> (+3.47%) ⬆️
src/hooks/useSeedMyExpensesSearch.ts 100.00% <100.00%> (ø)
src/libs/ExportOnyxState/common.ts 80.35% <ø> (ø)
src/pages/Search/SearchPage.tsx 87.75% <ø> (ø)
src/libs/PolicyUtils.ts 77.26% <93.33%> (+0.20%) ⬆️
src/libs/actions/Search.ts 44.17% <91.66%> (+1.07%) ⬆️
src/pages/Search/SavedSearchItemThreeDotMenu.tsx 0.00% <0.00%> (ø)
src/types/onyx/DismissedProductTraining.ts 0.00% <0.00%> (ø)
... and 2 more
... and 24 files with indirect coverage changes

aswin-s added 7 commits June 17, 2026 09:48
- Remove unused eslint-disable directive on no-restricted-imports in SavedSearchList.tsx
- Fix naming-convention violations in test: snake_case policy IDs → camelCase, email key → PEER_EMAIL constant
- Fix no-unsafe-type-assertion in test factory functions with targeted eslint-disable
- Fix prefer-at violations: [0] → .at(0)
… when savedSearches is empty

SavedSearchList only mounts when savedSearches is non-empty, so the seeding
effect never fired after a user deleted their saved searches and the NVP was
reset. Moving the effect to SearchTypeMenuWide, which always mounts when the
Search left panel is visible, ensures seeding runs regardless of whether any
saved searches exist.
@aswin-s
aswin-s marked this pull request as ready for review June 17, 2026 14:14
@aswin-s
aswin-s requested review from a team as code owners June 17, 2026 14:14
@melvin-bot
melvin-bot Bot requested review from flaviadefaria and parasharrajat and removed request for a team June 17, 2026 14:14
@melvin-bot

melvin-bot Bot commented Jun 17, 2026

Copy link
Copy Markdown

@parasharrajat 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]

Comment thread src/pages/Search/SearchPage.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 29ba6de554

ℹ️ 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".

Comment thread src/libs/actions/Search.ts Outdated
},
];

API.write(WRITE_COMMANDS.SAVE_SEARCH, {jsonQuery, newName: searchName}, {optimisticData, failureData, successData});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Persist the seeded-search gate through the NVP API

Because the only request sent here is SaveSearch with jsonQuery/newName, nvp_hasSeededMyExpensesSearch is never written to the server; the SET is only an optimistic Onyx update. In any fresh Onyx state, full reconnect, or other device after the user deletes the seeded search, OpenApp will not return this flag, so the SearchPage effect can recreate the deleted search. Persist the flag with the NVP write path or have the backend return it with the save.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The flag intentionally lives only as an optimistic Onyx update for now . Persisting it server-side would require a backend change

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we should request backend change.

Comment thread src/libs/actions/Search.ts
aswin-s added 5 commits June 17, 2026 21:01
…rch calls

The Onyx NVP guard (hasSeededMyExpensesSearch) is set optimistically and
asynchronously, so the effect could re-run before it propagates back,
producing duplicate SAVE_SEARCH API calls. Add a useRef guard that is
checked and set synchronously in the same tick.
If the user already has a saved search with the same query hash (e.g.
under a custom name), seedMyExpensesSearch would overwrite their name
with "My expenses". Now bail early if the hash is already present in
savedSearches, preserving any existing custom name.
Moves the My Expenses seeding concern out of SearchPage into a focused
custom hook. Also narrows the policy subscription to a boolean selector
so SearchPage only re-renders when the dual-role status changes, not on
every policy field update.
Covers: seeds for dual-role user, skips for non-dual-role, skips when
NVP already true, skips when accountID not yet loaded, seeds only once
on re-render.
Comment thread src/libs/PolicyUtils.ts Outdated
if (!policy) {
continue;
}
isSubmitter = isSubmitter || isPolicyUser(policy, currentUserEmail);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be any member of a policy not just user.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed. isPolicyUser matched only members whose role is literally 'user', which excluded admins or owners who also submit. Switched the submitter check to isGroupPolicy, matching the role-agnostic Submit-suggestion gate.

Comment thread src/libs/PolicyUtils.ts Outdated
}
isSubmitter = isSubmitter || isPolicyUser(policy, currentUserEmail);
if (!isApprover) {
const hasApprovalFlow = isPaidGroupPolicy(policy) && !!policy?.approvalMode && policy.approvalMode !== CONST.POLICY.APPROVAL_MODE.OPTIONAL;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why are we checking only for paid group policy?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Switched the check to isGroupPolicy so it lines up with the Approve surface.

Comment thread src/libs/PolicyUtils.ts Outdated
isSubmitter = isSubmitter || isPolicyUser(policy, currentUserEmail);
if (!isApprover) {
const hasApprovalFlow = isPaidGroupPolicy(policy) && !!policy?.approvalMode && policy.approvalMode !== CONST.POLICY.APPROVAL_MODE.OPTIONAL;
const isSubmittedTo = Object.values(policy.employeeList ?? {}).some((employee) => employee.submitsTo === currentUserEmail || employee.forwardsTo === currentUserEmail);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why are we checking isSubmittedTo?

Issue say user who submits and approves.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

isSubmittedTo was the "approves" signal. A user others submit/forward reports to is a de-facto approver. But it's redundant here: isPolicyApprover already covers submitsTo/forwardsTo (plus overLimitForwardsTo) internally, and the inline check even omitted overLimitForwardsTo. Removed it in and now relys on isPolicyApprover alone which is simpler and slightly more correct.

Comment thread src/libs/PolicyUtils.ts Outdated
return policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO;
}

/** Returns true when the user is both a submitter (role "user") in at least one policy and an approver on at least one paid policy with a non-optional approval flow. */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why specifically have you taken this criteria?

@aswin-s aswin-s Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The criteria mirror the existing suggested-search eligibility in getSuggestedSearchesVisibility (SearchUIUtils.ts), per the approved proposal: submitter ↔ the Submit gate (isGroupPolicy), approver ↔ the Approve gate (isEligibleForApproveSuggestion).

@parasharrajat

Copy link
Copy Markdown
Member

I logged in with this account, which has a workspace where he is an approver, but I don't see the search.

22.07.2026_16.25.28_REC.mp4

@parasharrajat

Copy link
Copy Markdown
Member

@aswin-s Check comments.

aswin-s added 3 commits July 24, 2026 11:37
Align isSubmitterAndApprover with getSuggestedSearchesVisibility:
- Submitter is any group-workspace member (isGroupPolicy) instead of role 'user',
  so admins/owners who submit are no longer excluded.
- Approver gate uses isGroupPolicy instead of isPaidGroupPolicy, so Submit-type
  workspaces with an approval flow qualify.
- Drop the redundant isSubmittedTo check; isPolicyApprover already covers
  submitsTo/forwardsTo (and overLimitForwardsTo).

Update and extend the unit tests accordingly.
Gate the seed effect on the SAVED_SEARCHES Onyx load status. The value is
undefined both while loading and when empty, so seeding on value alone could
run before the key hydrates, bypass the duplicate-hash guard in
seedMyExpensesSearch, and overwrite a pre-existing saved search of the same
query on a fresh reconnect. Add regression tests covering the loading gate.
@aswin-s
aswin-s requested a review from parasharrajat July 24, 2026 07:54
@aswin-s

aswin-s commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@aswin-s Check comments.

Fixed the scenario where user is an approver in another workspace. Please retest

@parasharrajat parasharrajat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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 any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • 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 and each prop has a /** comment above it */
    • The file is named correctly
    • 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
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • 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 any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • 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

🔲 iOS / native

24.07.2026_16.07.47_REC.mp4

🔲 iOS / Safari

24.07.2026_16.10.12_REC.mp4

🔲 MacOS / Chrome

24.07.2026_15.58.03_REC.mp4

🔲 Android / native

24.07.2026_16.15.10_REC.mp4

🎀 👀 🎀 C+ reviewed

@melvin-bot
melvin-bot Bot requested a review from Valforte July 24, 2026 10:45
@Valforte
Valforte merged commit c5c25a2 into Expensify:main Jul 24, 2026
36 of 40 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

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

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/Valforte in version: 9.4.45-0 🚀

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

@MelvinBot

Copy link
Copy Markdown
Contributor

Help site review — docs update required ✅

I reviewed the changes in this PR against the help site articles under docs/articles. One update is warranted.

Why: This PR now auto-seeds a default My expenses saved search (type:expense from:<accountID>) for users who both submit and approve expenses. The article Using Spend in New Expensify previously implied saved searches only appear after a member manually saves one — so dual-role users would now see a My expenses entry in the Saved section they never created, with no explanation on the help site.

I added a short "Why you have a My expenses saved search" section under How to save a search, explaining that it's seeded once and won't reappear if renamed or deleted.

No docs change needed for the tooltip removal — the "Rename your saved searches here" product training tooltip is an in-product tooltip that was never documented on the help site.

Draft help site PR: #97141 (labeled HelpDot)

⚠️ I couldn't assign aswin-s to the docs PR — that account isn't currently an assignable collaborator on Expensify/App (the assignee API returns 404). Please self-assign on #97141, or let me know another handle to use.


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

@jponikarchuk

Copy link
Copy Markdown

This PR failing because of the issue #97213
This issue is reproducible in: All platforms

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/marcaaron in version: 9.4.45-14 🚀

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

Bundle Size Analysis (Sentry):

aswin-s added a commit to aswin-s/App that referenced this pull request Jul 29, 2026
Expensify#93541 removed the only two uses of `index` in `buildSavedSearchMenuItem` (both
were `index === 0 && shouldShowSavedSearchTooltip` gates for the deleted rename
tooltip). The parameter stayed threaded through to createBaseSavedSearchMenuItem,
which never referenced it. Also trim the two eligibility doc comments down to
what they need to say.
@aswin-s

aswin-s commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

This PR failing because of the issue #97213

This issue is reproducible in: All platforms

@jponikarchuk The linked issue doesn't seem like a bug, rather that is the intended behaviour. Could you please check the explanation provided in #97213?

#97213 (comment)

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.

7 participants