Skip to content

Commit e39dfbc

Browse files
authored
Merge pull request #55302 from ishpaul777/new-user-workspace-tasks
2 parents c276197 + 142545d commit e39dfbc

File tree

15 files changed

+266
-123
lines changed

15 files changed

+266
-123
lines changed

src/CONST.ts

Lines changed: 85 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ const selectableOnboardingChoices = {
7575
const backendOnboardingChoices = {
7676
ADMIN: 'newDotAdmin',
7777
SUBMIT: 'newDotSubmit',
78+
TRACK_WORKSPACE: 'newDotTrackWorkspace',
7879
} as const;
7980

8081
const onboardingChoices = {
@@ -101,6 +102,50 @@ const selfGuidedTourTask: OnboardingTask = {
101102
description: ({navatticURL}) => `[Take a self-guided product tour](${navatticURL}) and learn about everything Expensify has to offer.`,
102103
};
103104

105+
const createWorkspaceTask: OnboardingTask = {
106+
type: 'createWorkspace',
107+
autoCompleted: true,
108+
title: 'Create a workspace',
109+
description: ({workspaceSettingsLink}) =>
110+
'*Create a workspace* to track expenses, scan receipts, chat, and more.\n' +
111+
'\n' +
112+
'Here’s how to create a workspace:\n' +
113+
'\n' +
114+
'1. Click *Settings*.\n' +
115+
'2. Click *Workspaces* > *New workspace*.\n' +
116+
'\n' +
117+
`*Your new workspace is ready!* [Check it out](${workspaceSettingsLink}).`,
118+
};
119+
120+
const meetGuideTask: OnboardingTask = {
121+
type: 'meetGuide',
122+
autoCompleted: false,
123+
title: 'Meet your setup specialist',
124+
description: ({adminsRoomLink}) =>
125+
`Meet your setup specialist, who can answer any questions as you get started with Expensify. Yes, a real human!\n` +
126+
'\n' +
127+
`Chat with the specialist in your [#admins room](${adminsRoomLink}).`,
128+
};
129+
130+
const setupCategoriesTask: OnboardingTask = {
131+
type: 'setupCategories',
132+
autoCompleted: false,
133+
title: 'Set up categories',
134+
description: ({workspaceCategoriesLink}) =>
135+
'*Set up categories* so your team can code expenses for easy reporting.\n' +
136+
'\n' +
137+
'Here’s how to set up categories:\n' +
138+
'\n' +
139+
'1. Click *Settings*.\n' +
140+
'2. Go to *Workspaces*.\n' +
141+
'3. Select your workspace.\n' +
142+
'4. Click *Categories*.\n' +
143+
"5. Disable any categories you don't need.\n" +
144+
'6. Add your own categories in the top right.\n' +
145+
'\n' +
146+
`[Take me to workspace category settings](${workspaceCategoriesLink}).`,
147+
};
148+
104149
const onboardingEmployerOrSubmitMessage: OnboardingMessage = {
105150
message: 'Getting paid back is as easy as sending a message. Let’s go over the basics.',
106151
tasks: [
@@ -5007,30 +5052,9 @@ const CONST = {
50075052
[onboardingChoices.MANAGE_TEAM]: {
50085053
message: 'Here are some important tasks to help get your team’s expenses under control.',
50095054
tasks: [
5010-
{
5011-
type: 'createWorkspace',
5012-
autoCompleted: true,
5013-
title: 'Create a workspace',
5014-
description: ({workspaceSettingsLink}) =>
5015-
'*Create a workspace* to track expenses, scan receipts, chat, and more.\n' +
5016-
'\n' +
5017-
'Here’s how to create a workspace:\n' +
5018-
'\n' +
5019-
'1. Click *Settings*.\n' +
5020-
'2. Click *Workspaces* > *New workspace*.\n' +
5021-
'\n' +
5022-
`*Your new workspace is ready!* [Check it out](${workspaceSettingsLink}).`,
5023-
},
5055+
createWorkspaceTask,
50245056
selfGuidedTourTask,
5025-
{
5026-
type: 'meetGuide',
5027-
autoCompleted: false,
5028-
title: 'Meet your setup specialist',
5029-
description: ({adminsRoomLink}) =>
5030-
`Meet your setup specialist, who can answer any questions as you get started with Expensify. Yes, a real human!\n` +
5031-
'\n' +
5032-
`Chat with the specialist in your [#admins room](${adminsRoomLink}).`,
5033-
},
5057+
meetGuideTask,
50345058
{
50355059
type: 'setupCategoriesAndTags',
50365060
autoCompleted: false,
@@ -5040,24 +5064,7 @@ const CONST = {
50405064
'\n' +
50415065
`Import them automatically by [connecting your accounting software](${workspaceAccountingLink}), or set them up manually in your [workspace settings](${workspaceSettingsLink}).`,
50425066
},
5043-
{
5044-
type: 'setupCategories',
5045-
autoCompleted: false,
5046-
title: 'Set up categories',
5047-
description: ({workspaceCategoriesLink}) =>
5048-
'*Set up categories* so your team can code expenses for easy reporting.\n' +
5049-
'\n' +
5050-
'Here’s how to set up categories:\n' +
5051-
'\n' +
5052-
'1. Click *Settings*.\n' +
5053-
'2. Go to *Workspaces*.\n' +
5054-
'3. Select your workspace.\n' +
5055-
'4. Click *Categories*.\n' +
5056-
"5. Disable any categories you don't need.\n" +
5057-
'6. Add your own categories in the top right.\n' +
5058-
'\n' +
5059-
`[Take me to workspace category settings](${workspaceCategoriesLink}).`,
5060-
},
5067+
setupCategoriesTask,
50615068
{
50625069
type: 'setupTags',
50635070
autoCompleted: false,
@@ -5135,6 +5142,42 @@ const CONST = {
51355142
},
51365143
],
51375144
},
5145+
[onboardingChoices.TRACK_WORKSPACE]: {
5146+
message: 'Here are some important tasks to help get your workspace set up.',
5147+
video: {
5148+
url: `${CLOUDFRONT_URL}/videos/guided-setup-manage-team-v2.mp4`,
5149+
thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-manage-team.jpg`,
5150+
duration: 55,
5151+
width: 1280,
5152+
height: 960,
5153+
},
5154+
tasks: [
5155+
createWorkspaceTask,
5156+
meetGuideTask,
5157+
setupCategoriesTask,
5158+
{
5159+
type: 'inviteAccountant',
5160+
autoCompleted: false,
5161+
title: 'Invite your accountant',
5162+
description: ({workspaceMembersLink}) =>
5163+
'*Invite your accountant* to Expensify and share your expenses with them to make tax time easier.\n' +
5164+
'\n' +
5165+
'Here’s how to invite your accountant:\n' +
5166+
'\n' +
5167+
'1. Click your profile picture.\n' +
5168+
'2. Go to *Workspaces*.\n' +
5169+
'3. Select your workspace.\n' +
5170+
'4. Click *Members* > Invite member.\n' +
5171+
'5. Enter their email or phone number.\n' +
5172+
'6. Add an invite message if you’d like.\n' +
5173+
'7. You’ll be set as the expense approver. You can change this to any admin once you invite your team.\n' +
5174+
'\n' +
5175+
'That’s it, happy expensing! 😄\n' +
5176+
'\n' +
5177+
`[View your workspace members](${workspaceMembersLink}).`,
5178+
},
5179+
],
5180+
},
51385181
[onboardingChoices.PERSONAL_SPEND]: onboardingPersonalSpendMessage,
51395182
[onboardingChoices.CHAT_SPLIT]: {
51405183
message: 'Splitting bills with friends is as easy as sending a message. Here’s how.',
@@ -5179,15 +5222,7 @@ const CONST = {
51795222
[onboardingChoices.ADMIN]: {
51805223
message: "As an admin, learn how to manage your team's workspace and submit expenses yourself.",
51815224
tasks: [
5182-
{
5183-
type: 'meetSetupSpecialist',
5184-
autoCompleted: false,
5185-
title: 'Meet your setup specialist',
5186-
description:
5187-
'*Meet your setup specialist* who can answer any questions as you get started with Expensify. Yes, a real human!' +
5188-
'\n' +
5189-
'Chat with them in your #admins room or schedule a call today.',
5190-
},
5225+
meetGuideTask,
51915226
{
51925227
type: 'reviewWorkspaceSettings',
51935228
autoCompleted: false,

src/ROUTES.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ const ROUTES = {
531531
},
532532
MONEY_REQUEST_STEP_CATEGORY: {
533533
route: ':action/:iouType/category/:transactionID/:reportID/:reportActionID?',
534-
getRoute: (action: IOUAction, iouType: IOUType, transactionID: string, reportID: string, backTo = '', reportActionID?: string) =>
534+
getRoute: (action: IOUAction, iouType: IOUType, transactionID: string, reportID: string | undefined, backTo = '', reportActionID?: string) =>
535535
getUrlWithBackToParam(`${action as string}/${iouType as string}/category/${transactionID}/${reportID}${reportActionID ? `/${reportActionID}` : ''}`, backTo),
536536
},
537537
MONEY_REQUEST_ATTENDEE: {

src/libs/API/parameters/CategorizeTrackedExpenseParams.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ type CategorizeTrackedExpenseParams = {
2626
policyExpenseCreatedReportActionID?: string;
2727
adminsChatReportID?: string;
2828
adminsCreatedReportActionID?: string;
29+
guidedSetupData?: string;
30+
engagementChoice?: string;
2931
};
3032

3133
export default CategorizeTrackedExpenseParams;

src/libs/API/parameters/CreateWorkspaceParams.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type CreateWorkspaceParams = {
1111
customUnitID: string;
1212
customUnitRateID: string;
1313
engagementChoice?: string;
14+
guidedSetupData?: string;
1415
currency: string;
1516
file?: File;
1617
};

src/libs/API/parameters/ShareTrackedExpenseParams.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ type ShareTrackedExpenseParams = {
2626
policyExpenseCreatedReportActionID?: string;
2727
adminsChatReportID?: string;
2828
adminsCreatedReportActionID?: string;
29+
engagementChoice?: string;
30+
guidedSetupData?: string;
2931
};
3032

3133
export default ShareTrackedExpenseParams;

src/libs/ReportUtils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ import {createDraftTransaction, getIOUReportActionToApproveOrPay, setMoneyReques
6262
import {createDraftWorkspace} from './actions/Policy/Policy';
6363
import {autoSwitchToFocusMode} from './actions/PriorityMode';
6464
import {hasCreditBankAccount} from './actions/ReimbursementAccount/store';
65-
import {handleReportChanged} from './actions/Report';
65+
import {handleReportChanged, prepareOnboardingOnyxData} from './actions/Report';
6666
import {isAnonymousUser as isAnonymousUserSession} from './actions/Session';
6767
import {convertToDisplayString, getCurrencySymbol} from './CurrencyUtils';
6868
import DateUtils from './DateUtils';
@@ -9254,6 +9254,7 @@ export {
92549254
getReportMetadata,
92559255
buildOptimisticSelfDMReport,
92569256
isHiddenForCurrentUser,
9257+
prepareOnboardingOnyxData,
92579258
};
92589259

92599260
export type {

src/libs/actions/App.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ function createWorkspaceWithPolicyDraftAndNavigateToIt(
430430
* @param [file] Optional, avatar file for workspace
431431
*/
432432
function savePolicyDraftByNewWorkspace(policyID?: string, policyName?: string, policyOwnerEmail = '', makeMeAdmin = false, currency = '', file?: File) {
433-
createWorkspace(policyOwnerEmail, makeMeAdmin, policyName, policyID, '', currency, file);
433+
createWorkspace(policyOwnerEmail, makeMeAdmin, policyName, policyID, CONST.ONBOARDING_CHOICES.MANAGE_TEAM, currency, file);
434434
}
435435

436436
/**

src/libs/actions/IOU.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3036,7 +3036,7 @@ function getTrackExpenseInformation(
30363036
let createdWorkspaceParams: CreateWorkspaceParams | undefined;
30373037

30383038
if (isDraftReportLocal) {
3039-
const workspaceData = buildPolicyData(undefined, policy?.makeMeAdmin, policy?.name, policy?.id, chatReport?.reportID);
3039+
const workspaceData = buildPolicyData(undefined, policy?.makeMeAdmin, policy?.name, policy?.id, chatReport?.reportID, CONST.ONBOARDING_CHOICES.TRACK_WORKSPACE);
30403040
createdWorkspaceParams = workspaceData.params;
30413041
optimisticData.push(...workspaceData.optimisticData);
30423042
successData.push(...workspaceData.successData);
@@ -4234,6 +4234,8 @@ function categorizeTrackedExpense(trackedExpenseParams: TrackedExpenseParams) {
42344234
policyExpenseCreatedReportActionID: createdWorkspaceParams?.expenseCreatedReportActionID,
42354235
adminsChatReportID: createdWorkspaceParams?.adminsChatReportID,
42364236
adminsCreatedReportActionID: createdWorkspaceParams?.adminsCreatedReportActionID,
4237+
engagementChoice: createdWorkspaceParams?.engagementChoice,
4238+
guidedSetupData: createdWorkspaceParams?.guidedSetupData,
42374239
};
42384240

42394241
API.write(WRITE_COMMANDS.CATEGORIZE_TRACKED_EXPENSE, parameters, {optimisticData, successData, failureData});
@@ -4292,6 +4294,8 @@ function shareTrackedExpense(trackedExpenseParams: TrackedExpenseParams) {
42924294
policyExpenseCreatedReportActionID: createdWorkspaceParams?.expenseCreatedReportActionID,
42934295
adminsChatReportID: createdWorkspaceParams?.adminsChatReportID,
42944296
adminsCreatedReportActionID: createdWorkspaceParams?.adminsCreatedReportActionID,
4297+
engagementChoice: createdWorkspaceParams?.engagementChoice,
4298+
guidedSetupData: createdWorkspaceParams?.guidedSetupData,
42954299
};
42964300

42974301
API.write(WRITE_COMMANDS.SHARE_TRACKED_EXPENSE, parameters, {optimisticData, successData, failureData});

src/libs/actions/Policy/Policy.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ import * as ReportUtils from '@libs/ReportUtils';
7878
import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover';
7979
import * as PaymentMethods from '@userActions/PaymentMethods';
8080
import * as PersistedRequests from '@userActions/PersistedRequests';
81+
import type {OnboardingPurpose} from '@src/CONST';
8182
import CONST from '@src/CONST';
8283
import ONYXKEYS from '@src/ONYXKEYS';
8384
import type {
85+
IntroSelected,
8486
InvitedEmailsToAccountIDs,
8587
PersonalDetailsList,
8688
Policy,
@@ -1704,6 +1706,12 @@ function createDraftInitialWorkspace(policyOwnerEmail = '', policyName = '', pol
17041706
Onyx.update(optimisticData);
17051707
}
17061708

1709+
let introSelected: OnyxEntry<IntroSelected>;
1710+
Onyx.connect({
1711+
key: ONYXKEYS.NVP_INTRO_SELECTED,
1712+
callback: (value) => (introSelected = value),
1713+
});
1714+
17071715
/**
17081716
* Generates onyx data for creating a new workspace
17091717
*
@@ -1715,16 +1723,18 @@ function createDraftInitialWorkspace(policyOwnerEmail = '', policyName = '', pol
17151723
* @param [engagementChoice] Purpose of using application selected by user in guided setup flow
17161724
* @param [currency] Optional, selected currency for the workspace
17171725
* @param [file] Optional, avatar file for workspace
1726+
* @param [shouldAddOnboardingTasks] whether to add onboarding tasks to the workspace
17181727
*/
17191728
function buildPolicyData(
17201729
policyOwnerEmail = '',
17211730
makeMeAdmin = false,
17221731
policyName = '',
17231732
policyID = generatePolicyID(),
17241733
expenseReportId?: string,
1725-
engagementChoice?: string,
1734+
engagementChoice?: OnboardingPurpose,
17261735
currency = '',
17271736
file?: File,
1737+
shouldAddOnboardingTasks = true,
17281738
) {
17291739
const workspaceName = policyName || generateDefaultWorkspaceName(policyOwnerEmail);
17301740

@@ -1997,6 +2007,21 @@ function buildPolicyData(
19972007
file: clonedFile,
19982008
};
19992009

2010+
if (!introSelected?.createWorkspace && engagementChoice && shouldAddOnboardingTasks) {
2011+
const onboardingData = ReportUtils.prepareOnboardingOnyxData(engagementChoice, CONST.ONBOARDING_MESSAGES[engagementChoice], adminsChatReportID, policyID);
2012+
if (!onboardingData) {
2013+
return {successData, optimisticData, failureData, params};
2014+
}
2015+
const {guidedSetupData, optimisticData: taskOptimisticData, successData: taskSuccessData, failureData: taskFailureData} = onboardingData;
2016+
2017+
params.guidedSetupData = JSON.stringify(guidedSetupData);
2018+
params.engagementChoice = engagementChoice;
2019+
2020+
optimisticData.push(...taskOptimisticData);
2021+
successData.push(...taskSuccessData);
2022+
failureData.push(...taskFailureData);
2023+
}
2024+
20002025
return {successData, optimisticData, failureData, params};
20012026
}
20022027

@@ -2016,11 +2041,22 @@ function createWorkspace(
20162041
makeMeAdmin = false,
20172042
policyName = '',
20182043
policyID = generatePolicyID(),
2019-
engagementChoice = '',
2044+
engagementChoice: OnboardingPurpose = CONST.ONBOARDING_CHOICES.MANAGE_TEAM,
20202045
currency = '',
20212046
file?: File,
2047+
shouldAddOnboardingTasks = true,
20222048
): CreateWorkspaceParams {
2023-
const {optimisticData, failureData, successData, params} = buildPolicyData(policyOwnerEmail, makeMeAdmin, policyName, policyID, undefined, engagementChoice, currency, file);
2049+
const {optimisticData, failureData, successData, params} = buildPolicyData(
2050+
policyOwnerEmail,
2051+
makeMeAdmin,
2052+
policyName,
2053+
policyID,
2054+
undefined,
2055+
engagementChoice,
2056+
currency,
2057+
file,
2058+
shouldAddOnboardingTasks,
2059+
);
20242060
API.write(WRITE_COMMANDS.CREATE_WORKSPACE, params, {optimisticData, successData, failureData});
20252061

20262062
// Publish a workspace created event if this is their first policy

0 commit comments

Comments
 (0)