Expensify / App

Welcome to New Expensify: a complete re-imagination of financial collaboration, centered around chat. Help us build the next generation of Expensify by sharing feedback and contributing to the code.
https://new.expensify.com
MIT License
3.46k stars 2.81k forks source link

[$250] Give users on a domain the ability to join their colleagues when the company is already using Expensify #48189

Open anmurali opened 1 month ago

anmurali commented 1 month ago

Proposal: Allow a private domain sign up, whose company is already using Expensify to request to join relevant workspace(s)

Problem: One of the cool things about Expensify is that anyone can sign up without their company's permission or invitation. But this means when an employee signs up independently they are not aware their company is already using Expensify and so end up creating their own workspaces in error, causing a lot of confusion for themselves and their company

Solution: Mirror Classic when it comes to an employee that signs up with a private domain email of a company that already has one or more workspaces. It goes like this:

  1. Sign-up with an email address on a private domain that has existing workspace owners
  2. We ask for their first name/last name (Ice breaker)
  3. Next, we show a step that:
    • Let’s them know people on derp.com are already using Expensify.
    • We’ve sent a magic code to validate their account so they can join them
    • An input for said magic code to validate the account
    • An option to skip and move on with onboarding as normal if they prefer
  4. If they validate the account, the next step shown is a list of all the workspaces owned by members of their private domain.
    • The CTA is Ask to join or Join based on the workspace JSON's automaticJoiningEnabled parameter being set to false or true respectivey
    • They can only pick one workspace in the list
  5. If they click on the CTA we do one of two things depending on if the workspace pre-approves join requests (Join), or an admin needs to accept (Ask to join):
    • Pre-approval not required:
    • Add them to the workspace
    • Drop them in the LHN
    • populate their onboarding/ConciergeDM with the invited member set of tasks
    • Pre-approval required:
    • Drop them in the LHN to continue exploring the product
    • Send the actionable message in the #admins room to accept or decline (just like policy join links that require approval)
    • On the workspaces page, show the workspace row they’re pending to be accepted to join with the “[Requested]” badge (just like a policy join request that needs to be approved)
    • If they select New Workspace in the + menu or Workspace page, have a warning just to let them know we’re waiting on their colleagues to still accept the request to join
    • Once accepted, they’ll get an email as they’re added to the workspace and we populate their onboarding/ConciergeDM with the invited member set of tasks.
      Upwork Automation - Do Not Edit
      • Upwork Job URL: https://www.upwork.com/jobs/~021832414536636098293
      • Upwork Job ID: 1832414536636098293
      • Last Price Increase: 2024-10-08
Issue OwnerCurrent Issue Owner: @marcaaron
melvin-bot[bot] commented 1 month ago

Current assignee @dubielzyk-expensify is eligible for the Design assigner, not assigning anyone new.

dubielzyk-expensify commented 1 month ago

Here's the overall flow:

CleanShot 2024-08-29 at 14 46 54@2x

Included workspace member count and owner after feedback in Slack. Btw, if there's no existing workspace that they can join, we continue with the intent picker like normal onboarding

cc @Expensify/design for thoughts and feelz

shawnborton commented 1 month ago

Looks solid to me!

shawnborton commented 1 month ago

How does this look on desktop?

dannymcclain commented 1 month ago

Looks solid to me!

Same!

How does this look on desktop?

Also curious 🙃 👀

dubielzyk-expensify commented 1 month ago

Here's the desktop mocks:

image image

Do you think it's better if I don't stretch the validation code to be full-width with the modal? image

trjExpensify commented 1 month ago

I like the full width version, personally! ❤️

shawnborton commented 1 month ago

Yeah, the full width does look nice. Thanks for the desktop mocks, they check out nicely ✅

dannymcclain commented 1 month ago

Agree! Stretch it baby! Desktop mocks looking good. 🫶

dubielzyk-expensify commented 1 month ago

The jury has spoken. Final Figma files can be found here: https://www.figma.com/design/ir27daDKHaB1g4iZCT22K5/Onboarding-v2?node-id=7147-9183

anmurali commented 1 month ago

@trjExpensify - can this be built by the contributor or do we need BE code? Curious for a second set of eyes. Asking you as you wrote down the steps in the solution

trjExpensify commented 1 month ago

I think this is mostly FE, but we might need some BE work for the "Select a workspace" page to get that list of accessibleDomainPolicies - I'm not quite sure if we have that available to NewDot.

@luacmartins & @mountiny we built the request to join stuff in simplified collect with the Share policyJoinLink a while back, so the #admins message to accept or decline (if pre-approval is required) should be in place and usable here already, right?

luacmartins commented 1 month ago

Yes, we have the system message in #admins when users try to join via the link Screenshot 2024-09-05 at 8 59 07 AM

trjExpensify commented 1 month ago

Cool, so should be reusable to call that request to join from here when needed with Ask to join:

image

but we might need some BE work for the "Select a workspace" page to get that list of accessibleDomainPolicies - I'm not quite sure if we have that available to NewDot

Do you have any idea if we'd have a list of accessibleDomainPolicies available in NewDot or if that's going to need BE work here?

luacmartins commented 1 month ago

Do you have any idea if we'd have a list of accessibleDomainPolicies available in NewDot or if that's going to need BE work here?

AFAIK we don't have this data in NewDot yet, so we'd need to fetch it when we open that page.

trjExpensify commented 1 month ago

Kewl, so we do need BE here then yes?

luacmartins commented 1 month ago

yes

mountiny commented 1 month ago

Yeah, agreed we will need to fetch that; also, somehow, indicate which one is "Join now" and which one is "Ask to join". couple questions:

  1. How do the "Join Now" and "Ask to join" changes when you click on them?
  2. If user clicks skip for now, where will they access this modal/ list of workspaces to join with buttons later in the product?
trjExpensify commented 1 month ago

How do the "Join Now" and "Ask to join" changes when you click on them?

Join now = workspace doesn't require approval to join Ask to join = workspace needs admin approval to join

That's the distinction between the two buttons, so I assume that's something on the policy object we store for use with policy join links.

As for what happens when you click them, that's outlined in the OP in step 5. Let me know if you have any qs on that!

If user clicks skip for now, where will they access this modal/ list of workspaces to join with buttons later in the product?

If we're mirroring the Inbox on OldDot, they don't. So maybe "Skip" is better than "Skip for now" which implies you can get back to it. We could look at something on the workspaces page with a list of available workspaces to join instead of the empty state when applicable, but I'm also fine to descope that to start and keep it to this one-time onboarding modal flow.

anmurali commented 1 month ago

That's the distinction between the two buttons, so I assume that's something on the policy object we store for use with policy join links.

I have clarified the exact workspace setting in the original description!

anmurali commented 1 month ago

Final mockuops

Mobile - Employee

image

Web - Employee

image

Actionable whisper in # admins (Exists)

image

melvin-bot[bot] commented 1 month ago

Auto-assigning issues to engineers is no longer supported. If you think this issue should receive engineering attention, please raise it in #whatsnext.

melvin-bot[bot] commented 1 month ago

Job added to Upwork: https://www.upwork.com/jobs/~021832414536636098293

melvin-bot[bot] commented 1 month ago

Triggered auto assignment to Contributor-plus team member for initial proposal review - @parasharrajat (External)

parasharrajat commented 1 month ago

@anmurali Don't we need C+ here for the PR review?

cretadn22 commented 1 month ago

Edited by proposal-police: This proposal was edited at 2024-09-09 04:41:33 UTC.

Proposal

Please re-state the problem that we are trying to solve in this issue.

Give users on a domain the ability to join their colleagues when the company is already using Expensify

What is the root cause of that problem?

New feature

What changes do you think we should make in order to solve the problem?

  1. After a user logs in, we'll check whether their domain already exists (this task should be managed in the backend)

  2. If the domain already exists, we will show a new flow similar to the onboarding process but with updated content.

If I understand correctly, the onboarding modal will not appear for users belonging to an existing domain. In that case, we can integrate this feature into the current onboarding modal by adding two new screens: OnboardingVerify and OnboardingWorkspace to the OnboardingModalNavigator stack.

https://github.com/Expensify/App/blob/aaa60b9103af83aaa58222e3f36e8cbfbd57e5c3/src/libs/Navigation/AppNavigator/Navigators/OnboardingModalNavigator.tsx#L27

After login, the backend should provide information to determine if the current user belongs to a domain. If the user does belong to a domain, the backend should also supply a list of workspaces that the user can either join or request to join. To implement this, we have two options: we can either create a new API to fetch the workspaces with the automaticJoiningEnabled field or integrate this data into the responses of the existing BeginSignIn or OpenApp APIs, as these are called after login. This approach would require either a new API or updates to the existing ones.

With the provided information from the backend, we can then redirect the user to either the onboarding flow or the join domain flow. To achieve this, we need to update the adaptOnboardingRouteState function to include a condition that navigates to the join domain flow if the user belongs to a domain, instead of proceeding with the onboarding flow.

  1. If pre-approval is required:

    • When the user clicks "Ask to join," we might need a new API to notify the backend of this requirement (require new API). The backend can then alert the workspace admin about the join request
    • We will also need to customize the workspace page accordingly.
    • We also need to manage the new invitation messages on the frontend to ensure they are displayed correctly in the admin room. This is handled before as mentioned https://github.com/Expensify/App/issues/48189#issuecomment-2331946213
  2. If pre-approval is not required:

    • The process is simpler. When the user clicks "Join now," we should call an API with the selected policyID, and the backend will return the report data (require new API, can use the API in step 3)

What alternative solutions did you explore? (Optional)

parasharrajat commented 1 month ago

I think it needs C+ for sure so I will start review.

parasharrajat commented 1 month ago

@cretadn22 Thanks for the proposal. But it will be great if you can go into more specifics. Compose your proposal using the existing functionality and Suggest where the changes will be needed in the App. also highlight what will be needed from BE etc and at what step.

A lot of information is already available in the app which you have mentioned in your proposal.

cretadn22 commented 1 month ago

@parasharrajat I’ve updated my proposal to include additional details, and I’ve bolded places that need to be updated on the backend.

marcaaron commented 1 month ago

populate their onboarding/ConciergeDM with the invited member set of tasks

Just for reference... what are these exactly? Is this built already or a new set of tasks we are showing? Is it the same set of tasks when you select "Get paid back by my employer"?

An option to skip and move on with onboarding as normal if they prefer

In other words, they will land back on this screen?

2024-09-09_17-11-28

marcaaron commented 1 month ago

Looking into returning the accessible domain policies ~during OpenApp (I assume that should be fine)~ as a first step here. Edit: Oh actually, OpenApp is wrong. As we need to check a validate code first. So, we'll need a new command that does this and then returns the accessible policies.

I think we will just need one new command for joining the accessible policy - how about JoinAccessiblePolicy?

And seems like we will be able to use the existing RequestPolicyAccess when the user is requesting.

trjExpensify commented 4 weeks ago

I think we will just need one new command for joining the accessible policy - how about JoinAccessiblePolicy?

Sounds like a solid name for this to me. 👍

anmurali commented 4 weeks ago

populate their onboarding/ConciergeDM with the invited member set of tasks

  • Just for reference... what are these exactly? Is this built already or a new set of tasks we are showing? Is it the same set of tasks when you select "Get paid back by my employer"?

@marcaaron - this is being built as part of Stage 3 onboarding (1.b)

anmurali commented 4 weeks ago

An option to skip and move on with onboarding as normal if they prefer

  • In other words, they will land back on this screen?

Yes

melvin-bot[bot] commented 3 weeks ago

@parasharrajat, @marcaaron Whoops! This issue is 2 days overdue. Let's get this updated quick!

marcaaron commented 3 weeks ago

Working on the backend changes for this now.

melvin-bot[bot] commented 3 weeks ago

@parasharrajat, @marcaaron Whoops! This issue is 2 days overdue. Let's get this updated quick!

marcaaron commented 3 weeks ago

Re-adding the Help Wanted label. Seems like Melvin removed it.

Still working on the backend changes for this. Unfortunately, it's a little bit tricky to implement since it essentially adds a new email validation flow for a new user who has signed in with an unvalidated login. When they enter their magic code we need to also create a passwordless login if I'm not mistaken.

Could actually use a second opinion from @johnmlee101 or @NikkiWines on that whenever they get a chance.

melvin-bot[bot] commented 3 weeks ago

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

marcaaron commented 3 weeks ago

Let's get some proposals here for the frontend? It may be easier to implement the backend changes with the frontend partially built.

marcaaron commented 2 weeks ago

@cretadn22 did you want to revise your proposal? @parasharrajat how can we get this one moving?

marcaaron commented 2 weeks ago

Still working through the BE changes in these two PRs:

parasharrajat commented 2 weeks ago

Looking into the details now on the proposal.

melvin-bot[bot] commented 2 weeks ago

@parasharrajat, @marcaaron Whoops! This issue is 2 days overdue. Let's get this updated quick!

melvin-bot[bot] commented 2 weeks ago

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

marcaaron commented 2 weeks ago

Still working on the backend stuff, but it's all in review now. The changes required some consensus from engineering on how to build it out and turned out to be pretty involved.

I'm going OOO starting on Friday and would love to try and get the PRs merged before then so this will be in a potentially good state to hand off to someone else.

melvin-bot[bot] commented 1 week ago

@parasharrajat, @marcaaron Huh... This is 4 days overdue. Who can take care of this?

melvin-bot[bot] commented 1 week ago

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

melvin-bot[bot] commented 1 week ago

@parasharrajat, @marcaaron 6 days overdue. This is scarier than being forced to listen to Vogon poetry!

parasharrajat commented 1 week ago

This is not showing up in my K2. I will look at the frontend proposal tomorrow.