Fix report title formula name flash by resolving submitter/manager personal details optimistically - #99229
Fix report title formula name flash by resolving submitter/manager personal details optimistically#99229MelvinBot wants to merge 3 commits into
Conversation
…rsonal details optimistically Co-authored-by: huult <huult@users.noreply.github.com>
|
I looked into the failing checks. No code fix is needed — every code-related check is passing (Bun tests, Jest The only failing check is Next step: get an independent reviewer to approve, and this check will pass. |
✅ Android test — PASSRan the reproduction steps from #99192 on standalone Android NewDot against this PR's branch ( Result: The workspace report title formula Steps performed:
Immediately after creation, the report title already read
|
|
|
||
| const titleReportField = getTitleReportField(getReportFieldsByPolicyID(policy) ?? {}); | ||
| // Resolve submitter/manager personal details so `{report:submit:from:*}` / `{report:submit:to:*}` tokens | ||
| // resolve to real names optimistically, matching what the BE returns and avoiding a name flash on creation. |
There was a problem hiding this comment.
@MelvinBot Could you shorten this comment or remove it? I don't think we need a comment here.
There was a problem hiding this comment.
Shortened it to a single line that keeps the "why" (avoiding the name flash) — pushed in 13fd952:
// Populate submitter/manager details so `{report:submit:from|to:*}` tokens resolve optimistically, avoiding a name flash on creation.See src/libs/ReportUtils.ts:7203. Happy to drop it entirely if you'd still prefer no comment.
|
Still no code fix needed — every code check is green (Bun tests, Jest The two red checks are both human-gated, not code problems:
Both clear once a reviewer approves and fills out their checklist. Pushing a commit can't resolve either. |
|
@MelvinBot Check all items on the author checklist, I will verify them later. |
|
Same situation as before — no code fix is possible here. All code checks pass. The two red checks are both human-review gates, not code failures:
Next step: a reviewer needs to review the PR, complete the reviewer checklist, and approve. Both checks will go green then — pushing a commit can't resolve them. |
✅ Web test — PASSRan the reproduction steps from #99192 on Web against this PR's branch ( Result: The workspace report title formula Steps performed:
Both the chat-preview report card and the opened report header showed
|
|
✅ Done — I've checked off every item in the PR Author Checklist section of the PR body (38 boxes, including all platform sub-items). I left the two As requested, these are checked for the checklist gate; please verify the individual items yourself before marking the PR ready for review. |
|
@MelvinBot ready for review |
|
Re-checked the PR — no code fix is needed. Every code-related check is green (Bun tests, all Jest The only two red checks are human-process gates that no commit can satisfy:
Next step: have a reviewer approve and fill out the reviewer checklist, and both will turn green. |
Co-authored-by: huult <huult@users.noreply.github.com>
|
I re-checked after the latest commit ( The only two red checks are process/review gates that no code change can satisfy:
Both will clear once a reviewer other than the author reviews and approves this PR. There's nothing for me to push. |
✅ Web test — PASSRan the reproduction steps from #99192 on dev NewDot web against this PR's branch ( Result: The workspace report title formula Steps performed:
The report card in the chat rendered directly as
|
|
Same result as before — no code fix is needed. All code checks are green (Bun tests, Jest The two red checks are both process/human checks that a commit can't resolve:
Next step: a reviewer needs to complete the checklist and approve the PR. Nothing to push here. |
| } | ||
|
|
||
| const titleReportField = getTitleReportField(getReportFieldsByPolicyID(policy) ?? {}); | ||
| // Populate submitter/manager details so `{report:submit:from|to:*}` tokens resolve optimistically, avoiding a name flash on creation. |
There was a problem hiding this comment.
Removed the comment entirely — pushed in 9eb550c. The submitterPersonalDetails / managerPersonalDetails lines now stand on their own with no comment above them.
|
Still no code fix needed — all code checks (Bun/Jest tests, typecheck, ESLint, Oxfmt, build, spellcheck, Storybook, React Compiler) are green. The two red checks are both reviewer-side gates, not code problems, so a push can't resolve either:
Next step: have a reviewer approve the PR and complete the reviewer checklist. |
…w feedback Co-authored-by: huult <huult@users.noreply.github.com>
|
@MelvinBot ready for review |
|
I re-checked the checks after the latest commits. No code fix is needed — every code-related check passes (Bun tests, all Jest The two remaining red checks are both non-code gates that no commit can satisfy:
Next step: have a reviewer (other than the author) approve the PR and complete the reviewer checklist — both checks will then go green. |
|
Still no code fix needed — every code check is green (Bun tests, Jest The two red checks are both human-action gates, not code problems, so pushing a commit can't turn them green:
Next step: have a reviewer approve the PR and fill out the reviewer checklist. |
|
@MelvinBot This PR is ready for review. Please mark it as ready for review (remove the draft status). |
✅ Web test — PASSRan the reproduction steps from #99192 on dev NewDot web against this PR's branch ( Result: The workspace report title formula Steps performed:
Read-back confirmed: the report header text was exactly
|
|
✅ Done — this PR is now marked Ready for review (draft status removed). |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9eb550c0bc
ℹ️ 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".
| const submitterPersonalDetails = report.ownerAccountID ? (allPersonalDetails?.[report.ownerAccountID] ?? undefined) : undefined; | ||
| const managerPersonalDetails = report.managerID ? (allPersonalDetails?.[report.managerID] ?? undefined) : undefined; |
There was a problem hiding this comment.
Pass personal details into the formula helper
Pass the personal-details snapshot through computeOptimisticReportNameWithMetadata() instead of reading the module-level Onyx cache here. The helper's output now silently depends on the asynchronous allPersonalDetails connection, so calls made before hydration or during an account-data transition can still commit empty or stale submitter/manager tokens, and callers or tests cannot supply the authoritative snapshot. The repository specifically requires Onyx-backed library logic to remain pure by accepting this data from its callers. CLAUDE.mdL38-L38
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I don't think this is necessary to address because the current implementation is correct, and changing it would add unnecessary complexity without providing much value.
|
I re-checked the failing checks. No code fix is needed — every code-related check passes (Bun tests, Jest The two red checks are both human-review gates, not code problems, and a commit can't resolve either:
Next step: have a reviewer complete the checklist and approve the PR; both checks will then go green. |
|
Still no code fix needed — all code-related checks pass (Bun/Jest tests, typecheck, ESLint, Oxfmt, build, spellcheck, Storybook, React Compiler, etc.). The two red checks are both human-process checks, not code:
Pushing a commit can't satisfy either. Next step: have a reviewer approve and complete the reviewer checklist, and both will go green. |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-08-22.at.23.52.52.movAndroid: mWeb ChromeScreen.Recording.2026-08-22.at.23.51.25.moviOS: HybridAppScreen.Recording.2026-08-22.at.23.55.36.moviOS: mWeb SafariScreen.Recording.2026-08-22.at.23.54.15.movMacOS: Chrome / SafariScreen.Recording.2026-08-22.at.23.48.15.mov |
|
Same as before — no code fix is needed. All 38 code checks pass (Bun tests, Jest The two remaining failures are both human-review gates that no commit can satisfy:
Next step: have a reviewer approve the PR and complete their checklist, and both checks will pass. |
|
Still no code fix needed — every code-related check passes (Bun tests, Jest The two red checks are both process/human checks, not code failures:
Neither can be resolved by a commit. Next step: have a reviewer complete the reviewer checklist and approve the PR, and both will go green. |









Explanation of Change
When a workspace's report title field uses the formula
{report:submit:from:firstName}(or any{report:submit:from:*}/{report:submit:to:*}token), the resolved report name briefly flashed to a different value right after a report was created.Root cause: the title formula is resolved optimistically on the client in
computeOptimisticReportNameWithMetadata(src/libs/ReportUtils.ts), but theFormulaContextit built never populatedsubmitterPersonalDetails/managerPersonalDetails. With those undefined,computePersonalDetailsFieldreturns an empty string, and becausereport:submit:*tokens are special-cased as "submission info" the empty value is not flagged as unresolved — so an empty/partialreportNamewas committed to Onyx. The UI then rendered a placeholder ("… owes $0.00" / "New Report") until the backend response arrived with the fully-resolved name. That placeholder → real-name transition is the flash.This change populates
submitterPersonalDetails(fromreport.ownerAccountID) andmanagerPersonalDetails(fromreport.managerID) in the optimisticFormulaContext, sourcing them from the module-levelallPersonalDetailsalready maintained inReportUtils.ts. Thereport:submit:from:*/report:submit:to:*tokens now resolve to the real names optimistically, matching what the backend returns, so the name no longer changes on the first render — no flash.Fixed Issues
$ #99192
PROPOSAL: #99192 (comment)
Tests
// TODO: The human co-author must fill out the tests you ran before marking this PR as "ready for review". Please describe what tests you performed that validate your change worked.
Offline tests
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
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