Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tasks for new user first workspace #55017

Closed
wants to merge 102 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
ba863a3
add tasks for new user first workspace
ishpaul777 Jan 9, 2025
32dc809
prettier
ishpaul777 Jan 9, 2025
bb1374b
Merge branch 'Expensify:main' into onboarding-tasks-workspace
ishpaul777 Jan 10, 2025
ace0d1e
replace meetSetupSpecialist task with meetGuideTask and fix guidedSet…
ishpaul777 Jan 10, 2025
3225931
Merge branch 'Expensify:main' into onboarding-tasks-workspace
ishpaul777 Jan 10, 2025
431e606
Merge branch 'main' into onboarding-tasks-workspace
ishpaul777 Jan 14, 2025
5dddf45
Merge branch 'Expensify:main' into onboarding-tasks-workspace
ishpaul777 Jan 14, 2025
46eaa10
fix upgrade workspace case
ishpaul777 Jan 14, 2025
6926f45
feat: Update the invitation process to include the role
truph01 Jan 14, 2025
d0b1cc1
fix: add marginBottom 24px to role
truph01 Jan 14, 2025
1a414b0
fix: type
truph01 Jan 14, 2025
a253588
fix: update margin bottom role to mb3
truph01 Jan 14, 2025
bcadec3
fix: lint
truph01 Jan 14, 2025
062b01d
fix: remove trans inviteMessageTitle
truph01 Jan 14, 2025
d93f793
Update version to 9.0.85-4
OSBotify Jan 14, 2025
a8d37ad
Update Mobile-Expensify to 9.0.85-4
OSBotify Jan 14, 2025
955ca13
reset transaction on page refresh for IOU distance page
FitseTLT Dec 23, 2024
eff3e36
lint fix
FitseTLT Jan 14, 2025
881dcd2
Update CONST.ts
jamesdeanexpensify Jan 14, 2025
0640a91
Add TRIP_SUPPORT constant and update link in TripDetailsPage
blazejkustra Jan 8, 2025
122ffba
fix: first item is highlighted in contact list and confirmation page
daledah Jan 13, 2025
20f00fd
feat: init local library
szymonrybczak Nov 20, 2024
483f55c
feat: add `defineTask` method
szymonrybczak Nov 20, 2024
2e5d8a9
feat: use BGTaskScheduler api
szymonrybczak Nov 20, 2024
18d01f6
fix: remove useless condition
szymonrybczak Nov 26, 2024
cdb7ec0
feat: properly register & add basic handler
szymonrybczak Nov 27, 2024
5f6ea86
feat: execute js function from native
szymonrybczak Nov 27, 2024
852bf92
chore: clean up usage on JS side
szymonrybczak Nov 27, 2024
ac0336b
fix: replace `BGProcessingTaskRequest` with `BGProcessingTaskRequest`
szymonrybczak Nov 27, 2024
6163ab6
chore: small code cleaning
szymonrybczak Dec 3, 2024
71e46b7
fix: remove android related stuff for now
szymonrybczak Dec 4, 2024
c96a025
fix: replace hardcoded identifier
szymonrybczak Dec 9, 2024
2b6cdbb
chore: code cleanup
szymonrybczak Dec 9, 2024
295136b
chore: one line impl in `AppDelegate.mm`
szymonrybczak Dec 9, 2024
7110449
chore: remove header comments
szymonrybczak Dec 9, 2024
0a477c1
feat: implement sequential task scheduling
szymonrybczak Dec 9, 2024
45f8a4d
chore: remove useless observer
szymonrybczak Dec 9, 2024
c6e365c
fix: properly order packages in `package.json`
szymonrybczak Dec 10, 2024
2692235
feat!: use new EventEmitter API
szymonrybczak Dec 10, 2024
3459183
fix: make 0 warnings
szymonrybczak Dec 10, 2024
3959933
fix: add proper bundle id
szymonrybczak Dec 10, 2024
2b54acd
fix: add release bundle id
szymonrybczak Dec 10, 2024
4b08896
fix: include all bundle identifiers
szymonrybczak Dec 11, 2024
e639f40
fix: replace `BGProcessingTaskRequest` with `BGAppRefreshTaskRequest`
szymonrybczak Dec 17, 2024
ca79968
fix: call `resolve()` only once when there's multiple identifiers
szymonrybczak Dec 17, 2024
5af0e0b
fix: use bg task specific id
szymonrybczak Dec 20, 2024
70165bc
fix: remove oudated condition in `Podfile`
szymonrybczak Dec 30, 2024
795ad3d
chore: update lock
szymonrybczak Jan 7, 2025
9e023fc
fix: eslint warnings
szymonrybczak Jan 7, 2025
39eed38
fix: mock module
szymonrybczak Jan 8, 2025
3bd5984
feat: add a log when executing background task
szymonrybczak Jan 8, 2025
367f95c
fix: move mocks to one file
szymonrybczak Jan 13, 2025
be655b9
feat: pass error to JS
szymonrybczak Jan 13, 2025
93d215d
fix: eslint error
szymonrybczak Jan 14, 2025
fdad6af
Remove custom report welcome message pressable functionality
ikevin127 Jan 13, 2025
cbc2f46
fixed eslint no-restricted-syntax
ikevin127 Jan 14, 2025
b472975
renamed imported methods according to naming convention
ikevin127 Jan 14, 2025
d6b1e7b
applied changes for #rooms and invoice rooms
ikevin127 Jan 14, 2025
a62763c
don't unpause focus trap when deactivated
bernhardoj Dec 27, 2024
05b6cec
don't unpause focus trap when deactivated
bernhardoj Dec 27, 2024
4757a15
fix flushing
perunt Jan 9, 2025
ad313fa
fix: App does not trigger required field validation when no state is …
truph01 Jan 14, 2025
f82383e
fix: remove redundant comment
truph01 Jan 14, 2025
ea713cb
Update version to 9.0.86-0
OSBotify Jan 15, 2025
fc3f816
Update Mobile-Expensify to 9.0.86-0
OSBotify Jan 15, 2025
e373500
pass the personal details
bernhardoj Jan 11, 2025
476bb9c
add test
bernhardoj Jan 13, 2025
752b327
use translate key
bernhardoj Jan 13, 2025
49923e2
lint
bernhardoj Jan 13, 2025
7cdc6cc
add unit test for getSubmitToAccountID and getApprovalChain
nkdengineer Jan 10, 2025
125de4a
use async
nkdengineer Jan 13, 2025
1cb66df
fix lint
nkdengineer Jan 13, 2025
f08a3a1
fix lint error
nkdengineer Jan 14, 2025
b01b26f
Update tests/unit/PolicyUtilsTest.ts
nkdengineer Jan 15, 2025
dd7c3b7
Update tests/unit/ReportUtilsTest.ts
nkdengineer Jan 15, 2025
3b3c95d
refactor test
nkdengineer Jan 15, 2025
5b3efaa
rename test
nkdengineer Jan 15, 2025
1042d50
update policy type
nkdengineer Jan 15, 2025
d4726fe
use fetch instead of simply window.location
NikkiWines Nov 16, 2024
86a0b13
update to use withOnyx, updated props
NikkiWines Nov 16, 2024
1357cde
minor style
NikkiWines Nov 21, 2024
5552aa9
introduce post for SAML native
NikkiWines Nov 21, 2024
67dc592
style
NikkiWines Nov 21, 2024
4f14c04
dry up saml url logic
NikkiWines Nov 22, 2024
987f466
style
NikkiWines Nov 22, 2024
3c8ab4b
update SAML native logic to handle errors
NikkiWines Nov 28, 2024
afc6432
fix error handling for signing in with short lived authtoken
NikkiWines Nov 28, 2024
6b6cf09
minor style
NikkiWines Nov 28, 2024
b3a7320
return early with clean session if no login
NikkiWines Nov 29, 2024
d14631c
prettier
NikkiWines Nov 29, 2024
707fd77
add copy
NikkiWines Nov 30, 2024
bcc43cf
add handleError function
NikkiWines Nov 30, 2024
42f7842
style
NikkiWines Nov 30, 2024
a7df60c
linting changes
NikkiWines Dec 2, 2024
912cc70
error handling
NikkiWines Dec 2, 2024
f05e8a6
remove unneeded url clean
NikkiWines Dec 11, 2024
f246529
dry handle error functionality and rename function
NikkiWines Dec 19, 2024
9158723
remove noop
NikkiWines Dec 20, 2024
d23ad26
fix imports
NikkiWines Dec 20, 2024
ac3825d
add back navigation import
NikkiWines Dec 20, 2024
bc15302
fix import and show loading screen
NikkiWines Dec 21, 2024
fc0f89f
fix double negation
NikkiWines Dec 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 84 additions & 41 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const selectableOnboardingChoices = {
const backendOnboardingChoices = {
ADMIN: 'newDotAdmin',
SUBMIT: 'newDotSubmit',
TRACK_WORKSPACE: 'newDotTrackWorkspace',
} as const;

const onboardingChoices = {
Expand All @@ -98,6 +99,50 @@ const selfGuidedTourTask: OnboardingTask = {
description: ({navatticURL}) => `[Take a self-guided product tour](${navatticURL}) and learn about everything Expensify has to offer.`,
};

const createWorkspaceTask: OnboardingTask = {
type: 'createWorkspace',
autoCompleted: true,
title: 'Create a workspace',
description:
'*Create a workspace* to track expenses, scan receipts, chat, and more.\n' +
'\n' +
'Here’s how to create a workspace:\n' +
'\n' +
'1. Click the settings tab.\n' +
'2. Click *Workspaces* > *New workspace*.\n' +
'\n' +
'*Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.*',
};

const meetGuideTask: OnboardingTask = {
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
type: 'meetGuide',
autoCompleted: false,
title: 'Meet your setup specialist',
description: ({adminsRoomLink}) =>
`Meet your setup specialist, who can answer any questions as you get started with Expensify. Yes, a real human!\n` +
'\n' +
`Chat with the specialist in your [#admins room](${adminsRoomLink}).`,
};

const setupCategoriesTask: OnboardingTask = {
type: 'setupCategories',
autoCompleted: false,
title: 'Set up categories',
description: ({workspaceCategoriesLink}) =>
'*Set up categories* so your team can code expenses for easy reporting.\n' +
'\n' +
'Here’s how to set up categories:\n' +
'\n' +
'1. Click the settings tab.\n' +
'2. Go to *Workspaces*.\n' +
'3. Select your workspace.\n' +
'4. Click *Categories*.\n' +
"5. Disable any categories you don't need.\n" +
'6. Add your own categories in the top right.\n' +
'\n' +
`[Take me to workspace category settings](${workspaceCategoriesLink}).`,
};

const onboardingEmployerOrSubmitMessage: OnboardingMessage = {
message: 'Getting paid back is as easy as sending a message. Let’s go over the basics.',
video: {
Expand Down Expand Up @@ -5014,30 +5059,9 @@ const CONST = {
height: 960,
},
tasks: [
{
type: 'createWorkspace',
autoCompleted: true,
title: 'Create a workspace',
description:
'*Create a workspace* to track expenses, scan receipts, chat, and more.\n' +
'\n' +
'Here’s how to create a workspace:\n' +
'\n' +
'1. Click the settings tab.\n' +
'2. Click *Workspaces* > *New workspace*.\n' +
'\n' +
'*Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.*',
},
createWorkspaceTask,
selfGuidedTourTask,
{
type: 'meetGuide',
autoCompleted: false,
title: 'Meet your setup specialist',
description: ({adminsRoomLink}) =>
`Meet your setup specialist, who can answer any questions as you get started with Expensify. Yes, a real human!\n` +
'\n' +
`Chat with the specialist in your [#admins room](${adminsRoomLink}).`,
},
meetGuideTask,
{
type: 'setupCategoriesAndTags',
autoCompleted: false,
Expand All @@ -5047,24 +5071,7 @@ const CONST = {
'\n' +
`Import them automatically by [connecting your accounting software](${workspaceAccountingLink}), or set them up manually in your [workspace settings](${workspaceSettingsLink}).`,
},
{
type: 'setupCategories',
autoCompleted: false,
title: 'Set up categories',
description: ({workspaceCategoriesLink}) =>
'*Set up categories* so your team can code expenses for easy reporting.\n' +
'\n' +
'Here’s how to set up categories:\n' +
'\n' +
'1. Click the settings tab.\n' +
'2. Go to *Workspaces*.\n' +
'3. Select your workspace.\n' +
'4. Click *Categories*.\n' +
"5. Disable any categories you don't need.\n" +
'6. Add your own categories in the top right.\n' +
'\n' +
`[Take me to workspace category settings](${workspaceCategoriesLink}).`,
},
setupCategoriesTask,
{
type: 'setupTags',
autoCompleted: false,
Expand Down Expand Up @@ -5141,6 +5148,42 @@ const CONST = {
},
],
},
[onboardingChoices.TRACK_WORKSPACE]: {
message: 'Here are some important tasks to help get your workspace set up.',
video: {
url: `${CLOUDFRONT_URL}/videos/guided-setup-manage-team-v2.mp4`,
thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-manage-team.jpg`,
duration: 55,
width: 1280,
height: 960,
},
tasks: [
createWorkspaceTask,
meetGuideTask,
setupCategoriesTask,
{
type: 'inviteAccountant',
autoCompleted: false,
title: 'Invite your accountant',
description: ({workspaceMembersLink}) =>
'*Invite your accountant to Expensify and share your expenses with them to make tax time easier.\n' +
'\n' +
'Here’s how to invite your accountant:\n' +
'\n' +
'1. Click your profile picture.\n' +
'2. Go to *Workspaces*.\n' +
'3. Select your workspace.\n' +
'4. Click *Members* > Invite member.\n' +
'5. Enter their email or phone number.\n' +
'6. Add an invite message if you’d like.\n' +
'7. You’ll be set as the expense approver. You can change this to any admin once you invite your team.\n' +
'\n' +
'That’s it, happy expensing! 😄\n' +
'\n' +
`[View your workspace members](${workspaceMembersLink}).`,
},
],
},
[onboardingChoices.PERSONAL_SPEND]: onboardingPersonalSpendMessage,
[onboardingChoices.CHAT_SPLIT]: {
message: 'Splitting bills with friends is as easy as sending a message. Here’s how.',
Expand Down
1 change: 1 addition & 0 deletions src/libs/API/parameters/CreateWorkspaceParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type CreateWorkspaceParams = {
customUnitID: string;
customUnitRateID: string;
engagementChoice?: string;
guidedSetupData?: string;
};

export default CreateWorkspaceParams;
6 changes: 5 additions & 1 deletion src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2642,7 +2642,7 @@ function getTrackExpenseInformation(
let createdWorkspaceParams: CreateWorkspaceParams | undefined;

if (isDraftReport) {
const workspaceData = Policy.buildPolicyData(undefined, policy?.makeMeAdmin, policy?.name, policy?.id, chatReport?.reportID);
const workspaceData = Policy.buildPolicyData(undefined, policy?.makeMeAdmin, policy?.name, policy?.id, chatReport?.reportID, CONST.ONBOARDING_CHOICES.TRACK_WORKSPACE);
createdWorkspaceParams = workspaceData.params;
optimisticData.push(...workspaceData.optimisticData);
successData.push(...workspaceData.successData);
Expand Down Expand Up @@ -3821,6 +3821,8 @@ function categorizeTrackedExpense(trackedExpenseParams: CategorizeTrackedExpense
policyExpenseCreatedReportActionID: createdWorkspaceParams?.expenseCreatedReportActionID,
adminsChatReportID: createdWorkspaceParams?.adminsChatReportID,
adminsCreatedReportActionID: createdWorkspaceParams?.adminsCreatedReportActionID,
engagementChoice: createdWorkspaceParams?.engagementChoice,
guidedSetupData: createdWorkspaceParams?.guidedSetupData,
};

API.write(WRITE_COMMANDS.CATEGORIZE_TRACKED_EXPENSE, parameters, {optimisticData, successData, failureData});
Expand Down Expand Up @@ -3902,6 +3904,8 @@ function shareTrackedExpense(
policyExpenseCreatedReportActionID: createdWorkspaceParams?.expenseCreatedReportActionID,
adminsChatReportID: createdWorkspaceParams?.adminsChatReportID,
adminsCreatedReportActionID: createdWorkspaceParams?.adminsCreatedReportActionID,
engagementChoice: createdWorkspaceParams?.engagementChoice,
guidedSetupData: createdWorkspaceParams?.guidedSetupData,
};

API.write(WRITE_COMMANDS.SHARE_TRACKED_EXPENSE, parameters, {optimisticData, successData, failureData});
Expand Down
36 changes: 33 additions & 3 deletions src/libs/actions/Policy/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import Onyx from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import type {ReportExportType} from '@components/ButtonWithDropdownMenu/types';
import {prepareOnboardingOnyxData} from '@libs/actions/Report';
import * as API from '@libs/API';
import type {
AddBillingCardAndRequestWorkspaceOwnerChangeParams,
Expand Down Expand Up @@ -78,9 +79,11 @@
import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover';
import * as PaymentMethods from '@userActions/PaymentMethods';
import * as PersistedRequests from '@userActions/PersistedRequests';
import type {OnboardingPurpose} from '@src/CONST';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {
IntroSelected,
InvitedEmailsToAccountIDs,
PersonalDetailsList,
Policy,
Expand Down Expand Up @@ -1676,6 +1679,12 @@
Onyx.update(optimisticData);
}

let introSelected: OnyxEntry<IntroSelected>;
Onyx.connect({
key: ONYXKEYS.NVP_INTRO_SELECTED,
callback: (value) => (introSelected = value),
});

/**
* Generates onyx data for creating a new workspace
*
Expand All @@ -1685,7 +1694,7 @@
* @param [policyID] custom policy id we will use for created workspace
* @param [expenseReportId] the reportID of the expense report that is being used to create the workspace
*/
function buildPolicyData(policyOwnerEmail = '', makeMeAdmin = false, policyName = '', policyID = generatePolicyID(), expenseReportId?: string, engagementChoice?: string) {
function buildPolicyData(policyOwnerEmail = '', makeMeAdmin = false, policyName = '', policyID = generatePolicyID(), expenseReportId?: string, engagementChoice?: OnboardingPurpose) {
const workspaceName = policyName || generateDefaultWorkspaceName(policyOwnerEmail);

const {customUnits, customUnitID, customUnitRateID, outputCurrency} = buildOptimisticDistanceRateCustomUnits();
Expand Down Expand Up @@ -1947,9 +1956,24 @@
expenseCreatedReportActionID,
customUnitID,
customUnitRateID,
engagementChoice,
};

if (!introSelected?.createWorkspace && engagementChoice) {
const {
guidedSetupData,
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
optimisticData: taskOptimisticData,
successData: taskSuccessData,
failureData: taskFailureData,
} = prepareOnboardingOnyxData(engagementChoice, CONST.ONBOARDING_MESSAGES[engagementChoice], expenseChatReportID, policyID);

params.guidedSetupData = JSON.stringify(guidedSetupData);
params.engagementChoice = engagementChoice;

optimisticData.push(...taskOptimisticData);
successData.push(...taskSuccessData);
failureData.push(...taskFailureData);
}

return {successData, optimisticData, failureData, params};
}

Expand All @@ -1962,7 +1986,13 @@
* @param [policyID] custom policy id we will use for created workspace
* @param [engagementChoice] Purpose of using application selected by user in guided setup flow
*/
function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName = '', policyID = generatePolicyID(), engagementChoice = ''): CreateWorkspaceParams {
function createWorkspace(
policyOwnerEmail = '',
makeMeAdmin = false,
policyName = '',
policyID = generatePolicyID(),
engagementChoice = CONST.ONBOARDING_CHOICES.MANAGE_TEAM,
): CreateWorkspaceParams {
const {optimisticData, failureData, successData, params} = buildPolicyData(policyOwnerEmail, makeMeAdmin, policyName, policyID, undefined, engagementChoice);
API.write(WRITE_COMMANDS.CREATE_WORKSPACE, params, {optimisticData, successData, failureData});

Expand Down Expand Up @@ -2266,7 +2296,7 @@
*
* @returns policyID of the workspace we have created
*/
function createWorkspaceFromIOUPayment(iouReport: OnyxEntry<Report>): WorkspaceFromIOUCreationData | undefined {

Check failure on line 2299 in src/libs/actions/Policy/Policy.ts

View workflow job for this annotation

GitHub Actions / ESLint check

Calling actions from inside other actions is forbidden. If an action needs to call another action combine the two actions into a singular API call instead

Check failure on line 2299 in src/libs/actions/Policy/Policy.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Calling actions from inside other actions is forbidden. If an action needs to call another action combine the two actions into a singular API call instead
// This flow only works for IOU reports
if (!ReportUtils.isIOUReportUsingReport(iouReport)) {
return;
Expand Down
Loading
Loading