feat: Submit workspace creation + onboarding flow (Wave 2)#87283
feat: Submit workspace creation + onboarding flow (Wave 2)#87283abzokhattab wants to merge 38 commits intoExpensify:mainfrom
Conversation
When a user selects "Get paid back by my employer" with the SUBMIT_2026 beta enabled, create a Submit workspace and complete onboarding, then navigate to Workspace > Categories with the side panel open.
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
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 --helpTypically, you'd want to translate only what you changed by running |
|
@hungvu193 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] |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7a5368cfe5
ℹ️ 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".
The useAutoCreateSubmitWorkspace hook runs a selector that calls translate() for workspace name generation. The test needs IntlStore loaded, matching the pattern in PersonalDetailsOnboarding test.
- PolicyTest: verify createWorkspace with SUBMIT type produces correct defaults (ADVANCED approval, workflows/tags/distance rates enabled, company cards disabled, harvesting disabled) - OnboardingPurpose: verify EMPLOYER + Submit2026 beta navigates to personal details (public domain) or workspaces (private domain) - OnboardingWorkspaces: verify skip with EMPLOYER + Submit2026 beta calls createWorkspace with SUBMIT type and completeOnboarding with EMPLOYER engagement choice
- WorkspaceOnboarding: stop mocking navigateAfterOnboarding, spy on Navigation primitives instead so the real navigation functions execute (covers navigateAfterOnboarding.ts) - PersonalDetailsOnboarding: add EMPLOYER + Submit2026 tests for both private domain (navigate to workspaces) and public domain (creates Submit workspace) branches
The test user signs in as test@user.com but the login list had fake@gmail.com, so isCurrentUserValidated returned false and routed to PRIVATE_DOMAIN instead of WORKSPACES.
…-workspace-onboarding
|
@abzokhattab Is this ready for review? |
|
@hungvu193 its still in progress i am testing the changes and seeing if we have any regressions today |
|
didnt have time to look into it .. i am continuing to work on this today |
|
@MelvinBot Review the PR |
|
@codex review |
PR ReviewOverall this is a well-structured feature with good test coverage. A few issues to address: Issues1. 2. 3. Missing 4. 5. Nits
Next Steps: Reply with |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 98d9e67401
ℹ️ 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".
…-workspace-onboarding # Conflicts: # src/CONST/index.ts
…alidated - Include SUBMIT in isPaidGroupPolicy so WorkspaceCategoriesPage (and other PAID-gated workspace pages) are accessible for Submit workspaces - Add isValidated check in BaseOnboardingPurpose before routing EMPLOYER+Submit users with a saved firstName directly to Workspaces, preventing unvalidated users from bypassing domain verification - Update OnboardingPurpose test to set validated login for the private domain shortcut test
|
@MelvinBot Review the PR again |
|
@abzokhattab you have conflicts |
WorkspaceUpgradePage gated on canModifyPlan (strict admin), so any non-admin who was redirected to /upgrade hit NotFound. Submit editors hit this any time they tap a Control-only toggle in "More features" (e.g. Rules). Expensify#87262 will add isSubmitPolicy redirects from Roles, Approvals, Payments, Accounting, Company Cards, Expensify Card, Travel, and Invoicing to this same page — all of those would dead-end on NotFound for editors without this fix. - Gate the page with canEditWorkspaceSettings (admins on any policy, editors on Submit policies) so editors render the upgrade intro. - Keep canPerformUpgrade (strict admin) controlling the upgrade button via buttonDisabled, so editors can't trigger an upgrade. - onUpgradeToCorporate and confirmUpgrade already guard on canPerformUpgrade, so no new write paths are opened for editors.
…it-workspace-onboarding # Conflicts: # src/pages/workspace/WorkspaceInitialPage.tsx # src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsExpensesFromPage.tsx
|
resolved and fixed the not found issue |
Upstream main renamed newGenerateDefaultWorkspaceName back to generateDefaultWorkspaceName. The Track hook picked up the new name during the merge, but useAutoCreateSubmitWorkspace.ts was missed, breaking CI's tsc typecheck.
|
Will review again today |
|
Bug: Not found page appears ater joining a workspace with private domain:
After that if you try to press back button, onboarding will appears again. Screen.Recording.2026-04-20.at.23.32.52.mov |
|
Bug: Private domain - Nothing happens after clicking `Join now:
Screen.Recording.2026-04-20.at.23.41.14.movLooks at Member pages,
|
|
Bug: Editor is not able to edit workspace settings after:
I think Editors are allowed to change workspace settings? But while testing the latest code, the Editor is now only able to see the Member and Overview page. Screen.Recording.2026-04-20.at.23.49.05.mov |
…-workspace-onboarding
For any workspace type other than 'submit', the behavior hasn't changed, meaning it won't navigate to the categories page. As per the documentation, I configured it to navigate to categories only when joining a 'submit' workspace. Let me know if you think it should behave differently
also when joining a submit wokspace i see that the fields are editable ... no?
i am unabled to reproduce this one ... is there something i am missing Screen.Recording.2026-04-21.at.12.15.12.mov |
|
@abzokhattab I'm still able to reproduce this one: Bug: Private domain - Nothing happens after clicking `Join now: I already joined an actual Submit workspace:
Just to clarify that it only works if you choose the option Screen.Recording.2026-04-22.at.00.27.33.mov |
|
Another thing I noticed that Editor is not able to edit some settings that is only allowed by the admin. For example: Change approver, enable payment, invite member.... Should we prevent Editor from these actions or should we update our BE to allow Editor to do that? Screen.Recording.2026-04-22.at.00.45.38.movAdd additional approver: Screen.Recording.2026-04-22.at.00.46.41.mov |
…it-workspace-onboarding # Conflicts: # src/libs/actions/Policy/Policy.ts
Previously only users who picked "Get paid back by my employer" landed on Workspace > Categories with #admins open after auto-joining a workspace during onboarding. Private-domain signups that reach the Join Workspace screen without selecting a Purpose would fall through to a HOME redirect, which appears as "nothing happens" after clicking Join now (report by @hungvu193 on Expensify#87283). Use the SUBMIT_2026 beta as the gate instead so any auto-join during onboarding by a Submit-era user follows the same Submit navigation as the EMPLOYER flow. Non-beta users are unchanged.
|
Validated against the design doc + Wave issues. The only explicit editor restriction is from #87865:
Mapping the examples:
So three of the four are BE gaps (approvals + invite are editor-capable by design), and the reimbursement/bank-account one is correctly editor-blocked and should stay that way. let me know what u think |
Alright i was able to reproduce it and pushed a fix |
|
Thanks for clarifying 🙏
|
|
🚧 @dylanexpensify has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
@abzokhattab I can see the Screen.Recording.2026-04-22.at.23.13.10.mov |
| sentryLabel: CONST.SENTRY_LABEL.WORKSPACE.INITIAL.REPORTS, | ||
| }); | ||
| if (isGroupPolicy(policy) && shouldShowProtectedItems) { | ||
| if (!isSubmitPolicy(policy)) { |
There was a problem hiding this comment.
According to the docs, we will hide Reports feature when creating submit workspace:
With this change here, there is no way to enable this feature for Submit workspace again, can you confirm if this is expected? @dylanexpensify
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5aaf16e97a
ℹ️ 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".
| // is enabled, including private-domain users who reach this screen without selecting | ||
| // a Purpose. JoinablePolicy doesn't carry policy.type from the backend today, so the | ||
| // beta is our best local signal for Submit-era onboarding. | ||
| const shouldUseSubmitFlow = canUseSubmit2026; |
There was a problem hiding this comment.
Restrict Submit onboarding flow to employer purpose
shouldUseSubmitFlow is derived from canUseSubmit2026 alone, so any user with the beta (including users who selected non-EMPLOYER purposes like Manage team) is forced through the Submit path when joining a workspace. In this branch we pass true to joinAccessiblePolicy, overwrite engagementChoice to EMPLOYER, and navigate to Submit-specific post-onboarding behavior, which misclassifies onboarding state and sends users to the wrong destination/tasks for their selected purpose. This should be gated by onboarding purpose (or a narrowly defined fallback) rather than beta presence alone.
Useful? React with 👍 / 👎.
|
@abzokhattab After recent changes, the Screen.Recording.2026-04-24.at.14.23.25.movAlso Workflows page always shows loading after visiting it: Screen.Recording.2026-04-24.at.14.35.39.mov |
|
reviewing |

Explanation of Change
submit2026type) when user selects "Get paid back by my employer" during onboardingisPolicyEditor()andcanEditWorkspaceSettings()helpers so Submit/Editor users can access workspace pagesAccessOrNotFoundWrapper,WorkspacePageWithSections, sidebar, and Workflows pages to recognize Submit/Editor accessFixed Issues
$ #87261
Tests
SUBMIT_2026beta for your accountPrivate domain path:
Offline tests
same as tests
QA Steps
Same as Tests above.
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))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.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.Screenshots/Videos
Android: Native
Screen.Recording.2026-04-16.at.00.29.49.mov
Screen.Recording.2026-04-16.at.23.48.23.mov
Android: mWeb Chrome
Screen.Recording.2026-04-16.at.00.32.32.mov
Screen.Recording.2026-04-16.at.23.50.23.mov
iOS: Native
Screen.Recording.2026-04-16.at.00.29.49.mov
Screen.Recording.2026-04-16.at.17.43.36.mov
iOS: mWeb Safari
Screen.Recording.2026-04-16.at.00.32.32.mov
Screen.Recording.2026-04-16.at.23.51.54.mov
MacOS: Chrome / Safari
Screen.Recording.2026-04-19.at.00.52.28.mov
Screen.Recording.2026-04-18.at.20.48.26.mov