Add personal track goal onboarding screen#89466
Conversation
When a user selects "Track and budget expenses" (personal spend) during onboarding, they now see an additional screen asking what they want to track: Investment tracking, Household tracking, Side project tracking, or Something else (with a free text input). The selection is stored as personalTrackGoal and sent with the CompleteGuidedSetup API call. Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
…onary Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Fixed the failing spellcheck: added |
…step counter tests Remove the unused `autoCreateTrackWorkspace` variable in BaseOnboardingPurpose (ESLint no-unused-vars). Update getOnboardingStepCounterTest to account for the new PERSONAL_TRACK_GOAL screen in PERSONAL_SPEND onboarding flows. Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Fixed the failing checks:
Note: The |
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.
|
|
@MelvinBot, now that this PR is merged, we have two tracking options: "Track expenses for my business" and "Organize my personal spending". merge the latest main and apply the related changes for option "Organize my personal spending". |
…ckGoalOnboarding Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com> # Conflicts: # src/hooks/useAutoCreateTrackWorkspace.ts # src/libs/getOnboardingStepCounter.ts # src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx
|
Merged latest
All 74 step counter tests pass and typecheck is clean. |
This comment has been minimized.
This comment has been minimized.
The downgrade from 3.0.71 to 3.0.69 with a patch caused a render count regression in the ReportActionCompose perf test. Version 3.0.71 already contains the hasMountedRef fix with shouldGetCachedValueRef correctly placed outside the guard, so the downgrade and patch are unnecessary. Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Fixed the failing The patch applied to 3.0.69 put |
|
MelvinBot has made 5 consecutive commits trying to fix CI failures. Automatic CI fix dispatches are now paused for this PR. Next steps: A human should review the recent commits and resolve the conflicting CI errors manually. |
📲 Install BuildsAndroid
|
|
@MelvinBot merge main and resolve conflicts |
Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Merged |
This comment has been minimized.
This comment has been minimized.
|
Sure, gimme a minute. |
|
Here you go: Illustrations.zip |
|
@MelvinBot, please use these #89466 (comment) icons on the |
- Add RealEstate, HouseMoney, and TargetWithArrow illustration SVGs - Switch from SelectionList to MenuItemList with icon support - Update strings to match design: title, option labels, and placeholder - Update all language files with new string values Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Updated the Icons added:
Strings updated to match the screenshot:
Component changes:
|
This comment has been minimized.
This comment has been minimized.
|
@MelvinBot Let’s use the three compressed SVGs below to fix the failing check. |
|
@MelvinBot, right now when we select the Can we follow the existing pattern used elsewhere in the app and instead show a |
When the Something else option is selected but no text is entered, show 'This field is required' below the input instead of the misleading 'Select an option to move forward' at the bottom. Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Good catch! Pushed a fix — when "Something else" is selected but the input is empty, it now shows |
|
@MelvinBot please merge main and resolve conflicts |
…ell.json conflict Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Merged main and resolved the conflict in |
🦜 Polyglot Parrot! 🦜Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues: View the translation diffdiff --git a/src/languages/de.ts b/src/languages/de.ts
index 21554fba6d0..e02c9f17fe8 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -2991,7 +2991,7 @@ ${amount} für ${merchant} – ${date}`,
},
personalTrackGoal: {
title: 'Was möchten Sie nachverfolgen?',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Kosten für eine Investitionsimmobilie',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Kosten für eine Anlageimmobilie',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: 'Haushaltsausgaben',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Ausgaben für Nebenprojekte',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'Etwas anderes',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 11a682a5a8d..2b91ccf7e1c 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2867,8 +2867,8 @@ ${amount} para ${merchant} - ${date}`,
title: '¿Qué quieres organizar?',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Costes de una propiedad de inversión',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: 'Gastos del hogar',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Gastos de proyecto paralelo',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'Algo más',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Gastos de proyectos paralelos',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'Otra cosa',
somethingElsePlaceholder: '¿Qué estás organizando?',
},
employees: {
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 383dce7973a..c380060cca0 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -2998,12 +2998,12 @@ ${amount} pour ${merchant} - ${date}`,
[CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: 'Autre chose',
},
personalTrackGoal: {
- title: 'Que souhaitez-vous suivre ?',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Coûts pour un bien immobilier locatif',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: 'Dépenses ménagères',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Dépenses de projet annexe',
+ title: 'Qu’est-ce que vous cherchez à suivre ?',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Coûts pour un bien locatif',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: 'Dépenses du ménage',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Dépenses de projet parallèle',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'Autre chose',
- somethingElsePlaceholder: 'Que suivez-vous ?',
+ somethingElsePlaceholder: 'Que suivez-vous ?',
},
employees: {
title: 'Combien d’employés avez-vous ?',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 1af408cf171..467e3b50d61 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -2984,8 +2984,8 @@ ${amount} per ${merchant} - ${date}`,
[CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: 'Altro',
},
personalTrackGoal: {
- title: 'Cosa vuoi tenere traccia?',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: "Costi per un immobile d'investimento",
+ title: 'Che cosa vuoi tenere traccia?',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Costi per un immobile a scopo d’investimento',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: 'Spese domestiche',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Spese per progetti paralleli',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'Altro',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 64bca51a323..7685c3f3fc7 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -2962,7 +2962,7 @@ ${date} の ${merchant} への ${amount}`,
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: '家計費',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'サイドプロジェクト経費',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'その他',
- somethingElsePlaceholder: '何を記録しますか?',
+ somethingElsePlaceholder: '何を記録していますか?',
},
employees: {
title: '従業員は何人いますか?',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index de2b359cc7c..bfb48ef7e86 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -2982,11 +2982,11 @@ ${amount} voor ${merchant} - ${date}`,
},
personalTrackGoal: {
title: 'Wat wil je bijhouden?',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Kosten voor een investeringspand',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Kosten voor een beleggingspand',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: 'Huishoudelijke uitgaven',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Kosten voor nevenproject',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Uitgaven voor nevenproject',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'Iets anders',
- somethingElsePlaceholder: 'Wat ben je aan het bijhouden?',
+ somethingElsePlaceholder: 'Wat houd je bij?',
},
employees: {
title: 'Hoeveel medewerkers heb je?',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index bbad3ae045c..b73d56c6e84 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -2975,9 +2975,9 @@ ${amount} dla ${merchant} - ${date}`,
},
personalTrackGoal: {
title: 'Co chcesz śledzić?',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Koszty dotyczące nieruchomości inwestycyjnej',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Koszty związane z nieruchomością inwestycyjną',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: 'Wydatki domowe',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Wydatki na projekty poboczne',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Wydatki na projekt poboczny',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'Coś innego',
somethingElsePlaceholder: 'Co śledzisz?',
},
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 5ee1dc26882..f7f61f85cbd 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -2975,7 +2975,7 @@ ${amount} para ${merchant} - ${date}`,
},
personalTrackGoal: {
title: 'O que você quer controlar?',
- [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Custos de um imóvel de investimento',
+ [CONST.ONBOARDING_PERSONAL_TRACK_GOALS.INVESTMENT_TRACKING]: 'Custos de um imóvel para investimento',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: 'Despesas domésticas',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: 'Despesas de projeto paralelo',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: 'Outra coisa',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 22051d7f8a4..b8966cd8b6c 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -2904,7 +2904,7 @@ ${amount},商户:${merchant} - 日期:${date}`,
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.HOUSEHOLD_TRACKING]: '家庭支出',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SIDEPROJECT_TRACKING]: '副业报销',
[CONST.ONBOARDING_PERSONAL_TRACK_GOALS.SOMETHING_ELSE]: '其他原因',
- somethingElsePlaceholder: '你正在跟踪什么?',
+ somethingElsePlaceholder: '你在记录什么?',
},
employees: {
title: '您有多少名员工?',
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
|
@MelvinBot merge main and please fix typescript checks |
…ckGoalOnboarding Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Merged |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 22b293dd7b
ℹ️ 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".
| adminsChatReportID: newAdminsChatReportID, | ||
| onboardingPolicyID: newPolicyID, | ||
| shouldWaitForRHPVariantInitialization: isSidePanelReportSupported, | ||
| personalTrackGoal: onboardingPersonalTrackGoal ?? undefined, |
There was a problem hiding this comment.
Don’t reuse stale personal track goals
When a user first selects Track personal and reaches this screen, then goes back to Purpose and chooses Track business/legacy personal spend, ONBOARDING_PERSONAL_TRACK_GOAL is never cleared, but useAutoCreateTrackWorkspace sends the cached value for every track onboarding completion. That means non-Track-personal completions can be submitted with an unrelated personalTrackGoal, corrupting the onboarding data sent to CompleteGuidedSetup; either clear this key when leaving the Track personal path or only pass it when onboardingPurposeSelected === TRACK_PERSONAL.
Useful? React with 👍 / 👎.
|
@MelvinBot please update these translations #89466 (comment) and check this comment #89466 (comment) |
Apply improved translations for de, es, fr, it, ja, nl, pl, pt-BR, zh-hans. Only pass personalTrackGoal to CompleteGuidedSetup when onboarding purpose is TRACK_PERSONAL to prevent stale data from leaking into other paths. Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Applied the Polyglot Parrot translations and also addressed the review comment about stale Changes pushed:
|
|
Thanks for the mock. Sorry, I overlooked this screenshot in the issue description. |
|
@MelvinBot , please update the selection styling for the selected |
|
No worries! |
Show a green circle checkmark on the right side of selected menu items on the personaltrackcase onboarding screen, matching the design mock. Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Added |
|
@MelvinBot Please revert the last change. We don’t want to show a radio button or a green outline for the selected choice. We want to:
|
|
|
|
@MelvinBot Please revert the last change. We don’t want to show a radio button or a green outline for the selected choice. We want to:
|
Replaces the radio button and green outline indicator with a right-aligned checkmark icon and an active background color on the selected menu item. Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Done — pushed Removed the radio button and green outline. The selected option now shows a checkmark on the right and uses |
|
@MelvinBot, please make the following changes:
|
- Navigate immediately on non-SOMETHING_ELSE options (no Continue button) - Use green color for the right check icon via success prop - Match hover color to selection color using Hoverable wrapper Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
|
Pushed the changes:
|












Explanation of Change
Adds a new onboarding screen (
onboarding/personaltrackcase) that appears when users select "Track and budget expenses" (personal spend) during onboarding. This screen asks what they want to track with four options:The selection is stored locally in Onyx during onboarding and sent as
personalTrackGoalwith theCompleteGuidedSetupAPI call, which stores it in theintroSelectedNVP under thepersonaltrackgoalkey.Fixed Issues
$ #88221
Tests
Skip work email./onboarding/purposemodal, selectOrganize my personal spending./onboarding/personaltrackcasemodal.Something else.tracking valueis displayed.Offline tests
Skip work email./onboarding/purposemodal, selectOrganize my personal spending./onboarding/personaltrackcasemodal.Something else.tracking valueis displayed.QA Steps
Skip work email./onboarding/purposemodal, selectOrganize my personal spending./onboarding/personaltrackcasemodal.Something else.tracking valueis displayed.PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps./** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari