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

[Guided Setup Stage 3] Update the Pay w/ Expensify selectors #45264

Merged
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
15c5210
update the pay w/ expensify selectors logic
cdOut Jul 11, 2024
ecc399a
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Jul 29, 2024
f0a4845
update completeEngagement in AddPaymentMethodMenu with inviteType che…
cdOut Jul 29, 2024
7cea50d
fix lint, add useCallback dependency
cdOut Jul 29, 2024
aa98fd4
fix prettier
cdOut Jul 29, 2024
2aaa0be
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Jul 29, 2024
037f433
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Aug 14, 2024
3f00dc6
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Aug 23, 2024
29eda5e
refactor CONST onboarding messages
cdOut Aug 23, 2024
75e336d
correct naming for onboardingPurpose param
cdOut Aug 23, 2024
83d33a1
fix prettier and undefined check
cdOut Aug 23, 2024
9ba23dd
add completePaymentOnboarding method to all necessary components
cdOut Aug 26, 2024
29aa7f9
fix prettier errors
cdOut Aug 26, 2024
fac02f0
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Aug 27, 2024
83e830a
fix lint errors and remove unused imports
cdOut Aug 27, 2024
8f2ad9b
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Sep 2, 2024
516aec9
move PAYMENT_SELECTED to IOU section in CONST
cdOut Sep 2, 2024
9031e1e
correct typescript typing
cdOut Sep 2, 2024
bd147f5
fix lint and prettier
cdOut Sep 2, 2024
fe9662b
add JSDoc to explain onboardingPayment function
cdOut Sep 2, 2024
2d83339
fix typescript errors caused by as const assertion
cdOut Sep 2, 2024
89ccca8
set ONYXKEYS import as type
cdOut Sep 2, 2024
178cd3a
fix remaining lint errors with leftover assertions
cdOut Sep 2, 2024
fbf9e17
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Sep 2, 2024
2480834
change onboarding choice for personal invoice and refactor code around
cdOut Sep 4, 2024
83d2239
fix lint and prettier
cdOut Sep 4, 2024
2c62b38
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Sep 4, 2024
732efbf
remove changes from AddPaymentMethodMenu
cdOut Sep 4, 2024
74aaacb
remove unnecessary prettier changes
cdOut Sep 4, 2024
5fd2f7e
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Sep 4, 2024
d631958
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Sep 5, 2024
7a6a1ac
Merge branch 'main' into @cdOut/guided-3-pay-selectors
cdOut Sep 6, 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
146 changes: 96 additions & 50 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import dateSubtract from 'date-fns/sub';
import Config from 'react-native-config';
import * as KeyCommand from 'react-native-key-command';
import type {ValueOf} from 'type-fest';
import type {Video} from './libs/actions/Report';
import BankAccount from './libs/models/BankAccount';
import * as Url from './libs/Url';
import SCREENS from './SCREENS';
Expand Down Expand Up @@ -64,16 +65,91 @@ const chatTypes = {
// Explicit type annotation is required
const cardActiveStates: number[] = [2, 3, 4, 7];

const onboardingChoices = {
const selectableOnboardingChoices = {
PERSONAL_SPEND: 'newDotPersonalSpend',
MANAGE_TEAM: 'newDotManageTeam',
EMPLOYER: 'newDotEmployer',
CHAT_SPLIT: 'newDotSplitChat',
LOOKING_AROUND: 'newDotLookingAround',
} as const;

const backendOnboardingChoices = {
SUBMIT: 'newDotSubmit',
} as const;

const onboardingChoices = {
...selectableOnboardingChoices,
...backendOnboardingChoices,
} as const;

const onboardingEmployerOrSubmitMessage: OnboardingMessageType = {
message: 'Getting paid back is as easy as sending a message. Let’s go over the basics.',
video: {
url: `${CLOUDFRONT_URL}/videos/guided-setup-get-paid-back-v2.mp4`,
thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-get-paid-back.jpg`,
duration: 55,
width: 1280,
height: 960,
},
tasks: [
{
type: 'submitExpense',
autoCompleted: false,
title: 'Submit an expense',
description:
'*Submit an expense* by entering an amount or scanning a receipt.\n' +
'\n' +
'Here’s how to submit an expense:\n' +
'\n' +
'1. Click the green *+* button.\n' +
'2. Choose *Submit expense*.\n' +
'3. Enter an amount or scan a receipt.\n' +
'4. Add your reimburser to the request.\n' +
'\n' +
'Then, send your request and wait for that sweet “Cha-ching!” when it’s complete.',
},
{
type: 'enableWallet',
autoCompleted: false,
title: 'Enable your wallet',
description:
'You’ll need to *enable your Expensify Wallet* to get paid back. Don’t worry, it’s easy!\n' +
'\n' +
'Here’s how to set up your wallet:\n' +
'\n' +
'1. Click your profile picture.\n' +
'2. Click *Wallet* > *Enable wallet*.\n' +
'3. Connect your bank account.\n' +
'\n' +
'Once that’s done, you can request money from anyone and get paid back right into your personal bank account.',
},
],
};

type OnboardingPurposeType = ValueOf<typeof onboardingChoices>;

const onboardingInviteTypes = {
IOU: 'iou',
INVOICE: 'invoice',
CHAT: 'chat',
} as const;

type OnboardingInviteType = ValueOf<typeof onboardingInviteTypes>;

type OnboardingTaskType = {
type: string;
autoCompleted: boolean;
title: string;
description: string | ((params: Partial<{adminsRoomLink: string; workspaceLink: string}>) => string);
};

type OnboardingMessageType = {
message: string;
video?: Video;
tasks: OnboardingTaskType[];
type?: string;
};

const CONST = {
HEIC_SIGNATURES: [
'6674797068656963', // 'ftypheic' - Indicates standard HEIC file
Expand Down Expand Up @@ -1911,6 +1987,11 @@ const CONST = {
BUSINESS_BANK_ACCOUNT: 'businessBankAccount',
},

PAYMENT_SELECTED: {
BBA: 'BBA',
PBA: 'PBA',
},

PAYMENT_METHOD_ID_KEYS: {
DEBIT_CARD: 'fundID',
BANK_ACCOUNT: 'bankAccountID',
Expand Down Expand Up @@ -1985,6 +2066,10 @@ const CONST = {
ACCESS_VARIANTS: {
CREATE: 'create',
},
PAYMENT_SELECTED: {
BBA: 'BBA',
PBA: 'PBA',
},
},

GROWL: {
Expand Down Expand Up @@ -4267,6 +4352,8 @@ const CONST = {

ONBOARDING_INTRODUCTION: 'Let’s get you set up 🔧',
ONBOARDING_CHOICES: {...onboardingChoices},
SELECTABLE_ONBOARDING_CHOICES: {...selectableOnboardingChoices},
ONBOARDING_INVITE_TYPES: {...onboardingInviteTypes},
ACTIONABLE_TRACK_EXPENSE_WHISPER_MESSAGE: 'What would you like to do with this expense?',
ONBOARDING_CONCIERGE: {
[onboardingChoices.EMPLOYER]:
Expand Down Expand Up @@ -4309,49 +4396,8 @@ const CONST = {
},

ONBOARDING_MESSAGES: {
[onboardingChoices.EMPLOYER]: {
message: 'Getting paid back is as easy as sending a message. Let’s go over the basics.',
video: {
url: `${CLOUDFRONT_URL}/videos/guided-setup-get-paid-back-v2.mp4`,
thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-get-paid-back.jpg`,
duration: 55,
width: 1280,
height: 960,
},
tasks: [
{
type: 'submitExpense',
autoCompleted: false,
title: 'Submit an expense',
description:
'*Submit an expense* by entering an amount or scanning a receipt.\n' +
'\n' +
'Here’s how to submit an expense:\n' +
'\n' +
'1. Click the green *+* button.\n' +
'2. Choose *Submit expense*.\n' +
'3. Enter an amount or scan a receipt.\n' +
'4. Add your reimburser to the request.\n' +
'\n' +
'Then, send your request and wait for that sweet “Cha-ching!” when it’s complete.',
},
{
type: 'enableWallet',
autoCompleted: false,
title: 'Enable your wallet',
description:
'You’ll need to *enable your Expensify Wallet* to get paid back. Don’t worry, it’s easy!\n' +
'\n' +
'Here’s how to set up your wallet:\n' +
'\n' +
'1. Click your profile picture.\n' +
'2. Click *Wallet* > *Enable wallet*.\n' +
'3. Connect your bank account.\n' +
'\n' +
'Once that’s done, you can request money from anyone and get paid back right into your personal bank account.',
},
],
},
[onboardingChoices.EMPLOYER]: onboardingEmployerOrSubmitMessage,
[onboardingChoices.SUBMIT]: onboardingEmployerOrSubmitMessage,
[onboardingChoices.MANAGE_TEAM]: {
message: 'Here are some important tasks to help get your team’s expenses under control.',
video: {
Expand Down Expand Up @@ -4380,7 +4426,7 @@ const CONST = {
type: 'meetGuide',
autoCompleted: false,
title: 'Meet your setup specialist',
description: ({adminsRoomLink}: {adminsRoomLink: string}) =>
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}).`,
Expand All @@ -4389,7 +4435,7 @@ const CONST = {
type: 'setupCategories',
autoCompleted: false,
title: 'Set up categories',
description: ({workspaceLink}: {workspaceLink: string}) =>
description: ({workspaceLink}) =>
'*Set up categories* so your team can code expenses for easy reporting.\n' +
'\n' +
'Here’s how to set up categories:\n' +
Expand All @@ -4406,7 +4452,7 @@ const CONST = {
type: 'addExpenseApprovals',
autoCompleted: false,
title: 'Add expense approvals',
description: ({workspaceLink}: {workspaceLink: string}) =>
description: ({workspaceLink}) =>
'*Add expense approvals* to review your team’s spend and keep it under control.\n' +
'\n' +
'Here’s how to add expense approvals:\n' +
Expand All @@ -4423,7 +4469,7 @@ const CONST = {
type: 'inviteTeam',
autoCompleted: false,
title: 'Invite your team',
description: ({workspaceLink}: {workspaceLink: string}) =>
description: ({workspaceLink}) =>
'*Invite your team* to Expensify so they can start tracking expenses today.\n' +
'\n' +
'Here’s how to invite your team:\n' +
Expand Down Expand Up @@ -4531,7 +4577,7 @@ const CONST = {
"Expensify is best known for expense and corporate card management, but we do a lot more than that. Let me know what you're interested in and I'll help get you started.",
tasks: [],
},
},
} satisfies Record<OnboardingPurposeType, OnboardingMessageType>,

REPORT_FIELD_TITLE_FIELD_ID: 'text_title',

Expand Down Expand Up @@ -5597,6 +5643,6 @@ type FeedbackSurveyOptionID = ValueOf<Pick<ValueOf<typeof CONST.FEEDBACK_SURVEY_
type SubscriptionType = ValueOf<typeof CONST.SUBSCRIPTION.TYPE>;
type CancellationType = ValueOf<typeof CONST.CANCELLATION_TYPE>;

export type {Country, IOUAction, IOUType, RateAndUnit, OnboardingPurposeType, IOURequestType, SubscriptionType, FeedbackSurveyOptionID, CancellationType};
export type {Country, IOUAction, IOUType, RateAndUnit, OnboardingPurposeType, IOURequestType, SubscriptionType, FeedbackSurveyOptionID, CancellationType, OnboardingInviteType};

export default CONST;
3 changes: 2 additions & 1 deletion src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {ValueOf} from 'type-fest';
import type CONST from './CONST';
import type {OnboardingPurposeType} from './CONST';
import type * as FormTypes from './types/form';
import type * as OnyxTypes from './types/onyx';
import type Onboarding from './types/onyx/Onboarding';
Expand Down Expand Up @@ -884,7 +885,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.MAX_CANVAS_AREA]: number;
[ONYXKEYS.MAX_CANVAS_HEIGHT]: number;
[ONYXKEYS.MAX_CANVAS_WIDTH]: number;
[ONYXKEYS.ONBOARDING_PURPOSE_SELECTED]: string;
[ONYXKEYS.ONBOARDING_PURPOSE_SELECTED]: OnboardingPurposeType;
[ONYXKEYS.ONBOARDING_ERROR_MESSAGE]: string;
[ONYXKEYS.ONBOARDING_POLICY_ID]: string;
[ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID]: string;
Expand Down
4 changes: 2 additions & 2 deletions src/components/AvatarWithDisplayName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as ReportUtils from '@libs/ReportUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {PersonalDetails, PersonalDetailsList, Policy, Report, ReportActions} from '@src/types/onyx';
import type {PersonalDetailsList, Policy, Report, ReportActions} from '@src/types/onyx';
import CaretWrapper from './CaretWrapper';
import DisplayNames from './DisplayNames';
import MultipleAvatars from './MultipleAvatars';
Expand Down Expand Up @@ -69,7 +69,7 @@ function AvatarWithDisplayName({
ReportUtils.isMoneyRequestReport(report) || ReportUtils.isMoneyRequest(report) || ReportUtils.isTrackExpenseReport(report) || ReportUtils.isInvoiceReport(report);
const icons = ReportUtils.getIcons(report, personalDetails, null, '', -1, policy, invoiceReceiverPolicy);
const ownerPersonalDetails = OptionsListUtils.getPersonalDetailsForAccountIDs(report?.ownerAccountID ? [report.ownerAccountID] : [], personalDetails);
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(Object.values(ownerPersonalDetails) as PersonalDetails[], false);
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(Object.values(ownerPersonalDetails), false);
const shouldShowSubscriptAvatar = ReportUtils.shouldReportShowSubscript(report);
const avatarBorderColor = isAnonymous ? theme.highlightBG : theme.componentBG;

Expand Down
1 change: 1 addition & 0 deletions src/libs/API/parameters/CompleteGuidedSetupParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type CompleteGuidedSetupParams = {
actorAccountID: number;
guidedSetupData: string;
engagementChoice: OnboardingPurposeType;
paymentSelected?: string;
};

export default CompleteGuidedSetupParams;
5 changes: 3 additions & 2 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import lodashSet from 'lodash/set';
import lodashSortBy from 'lodash/sortBy';
import Onyx from 'react-native-onyx';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import type {SetNonNullable} from 'type-fest';
import {FallbackAvatar} from '@components/Icon/Expensicons';
import type {SelectedTagOption} from '@components/TagPicker';
import type {IOUAction} from '@src/CONST';
Expand Down Expand Up @@ -379,8 +380,8 @@ function getAvatarsForAccountIDs(accountIDs: number[], personalDetails: OnyxEntr
* Returns the personal details for an array of accountIDs
* @returns keys of the object are emails, values are PersonalDetails objects.
*/
function getPersonalDetailsForAccountIDs(accountIDs: number[] | undefined, personalDetails: OnyxInputOrEntry<PersonalDetailsList>): PersonalDetailsList {
const personalDetailsForAccountIDs: PersonalDetailsList = {};
function getPersonalDetailsForAccountIDs(accountIDs: number[] | undefined, personalDetails: OnyxInputOrEntry<PersonalDetailsList>): SetNonNullable<PersonalDetailsList> {
const personalDetailsForAccountIDs: SetNonNullable<PersonalDetailsList> = {};
if (!personalDetails) {
return personalDetailsForAccountIDs;
}
Expand Down
2 changes: 1 addition & 1 deletion src/libs/SidebarUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ function getOptionData({
const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report);
const visibleParticipantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, true);

const participantPersonalDetailList = Object.values(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails)) as PersonalDetails[];
const participantPersonalDetailList = Object.values(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails));
const personalDetail = participantPersonalDetailList[0] ?? {};
const hasErrors = Object.keys(result.allReportErrors ?? {}).length !== 0;

Expand Down
Loading
Loading