From 4e990e42462bc96f5dd709924a1ee960679d4e31 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 30 Jul 2024 11:23:23 +0200 Subject: [PATCH 1/7] feat: add new write command - CreateExpensifyCard --- src/libs/API/parameters/CreateExpensifyCardParams.ts | 10 ++++++++++ src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 3 +++ 3 files changed, 14 insertions(+) create mode 100644 src/libs/API/parameters/CreateExpensifyCardParams.ts diff --git a/src/libs/API/parameters/CreateExpensifyCardParams.ts b/src/libs/API/parameters/CreateExpensifyCardParams.ts new file mode 100644 index 000000000000..1425a4ba9b99 --- /dev/null +++ b/src/libs/API/parameters/CreateExpensifyCardParams.ts @@ -0,0 +1,10 @@ +type CreateExpensifyCardParams = { + policyID: string; + assigneeEmail: string; + limit: number; + limitType: string; + cardTitle: string; + feedCountry: string; +}; + +export default CreateExpensifyCardParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 6b95190cd1ed..a848db9cbe39 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -269,3 +269,4 @@ export type {default as ExportSearchItemsToCSVParams} from './ExportSearchItemsT export type {default as UpdateExpensifyCardLimitParams} from './UpdateExpensifyCardLimitParams'; export type {CreateWorkspaceApprovalParams, UpdateWorkspaceApprovalParams, RemoveWorkspaceApprovalParams} from './WorkspaceApprovalParams'; export type {default as StartIssueNewCardFlowParams} from './StartIssueNewCardFlowParams'; +export type {default as CreateExpensifyCardParams} from './CreateExpensifyCardParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index f15fba20bc98..ab59c66e52ca 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -322,6 +322,7 @@ const WRITE_COMMANDS = { CREATE_WORKSPACE_APPROVAL: 'CreateWorkspaceApproval', UPDATE_WORKSPACE_APPROVAL: 'UpdateWorkspaceApproval', REMOVE_WORKSPACE_APPROVAL: 'RemoveWorkspaceApproval', + CREATE_EXPENSIFY_CARD: 'CreateExpensifyCard', } as const; type WriteCommand = ValueOf; @@ -650,6 +651,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.CREATE_WORKSPACE_APPROVAL]: Parameters.CreateWorkspaceApprovalParams; [WRITE_COMMANDS.UPDATE_WORKSPACE_APPROVAL]: Parameters.UpdateWorkspaceApprovalParams; [WRITE_COMMANDS.REMOVE_WORKSPACE_APPROVAL]: Parameters.RemoveWorkspaceApprovalParams; + [WRITE_COMMANDS.CREATE_EXPENSIFY_CARD]: Parameters.CreateExpensifyCardParams; }; const READ_COMMANDS = { @@ -760,6 +762,7 @@ type ReadCommandParameters = { [READ_COMMANDS.OPEN_SUBSCRIPTION_PAGE]: null; [READ_COMMANDS.OPEN_DRAFT_DISTANCE_EXPENSE]: null; [READ_COMMANDS.START_ISSUE_NEW_CARD_FLOW]: Parameters.StartIssueNewCardFlowParams; + [READ_COMMANDS.START_ISSUE_NEW_CARD_FLOW]: Parameters.StartIssueNewCardFlowParams; }; const SIDE_EFFECT_REQUEST_COMMANDS = { From 4dc1f53f0602d06b1bb0b34b0faf803506b9e734 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 31 Jul 2024 13:21:03 +0200 Subject: [PATCH 2/7] feat: create issueExpensifyCard action --- src/libs/API/types.ts | 2 ++ src/libs/actions/Card.ts | 19 ++++++++++++++++ .../issueNew/ConfirmationStep.tsx | 22 ++++++++++++++++--- .../issueNew/IssueNewCardPage.tsx | 2 +- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index ab59c66e52ca..8444e2b95714 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -323,6 +323,7 @@ const WRITE_COMMANDS = { UPDATE_WORKSPACE_APPROVAL: 'UpdateWorkspaceApproval', REMOVE_WORKSPACE_APPROVAL: 'RemoveWorkspaceApproval', CREATE_EXPENSIFY_CARD: 'CreateExpensifyCard', + CREATE_ADMIN_ISSUED_VIRTUAL_CARD: 'CreateAdminIssuedVirtualCard', } as const; type WriteCommand = ValueOf; @@ -652,6 +653,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.UPDATE_WORKSPACE_APPROVAL]: Parameters.UpdateWorkspaceApprovalParams; [WRITE_COMMANDS.REMOVE_WORKSPACE_APPROVAL]: Parameters.RemoveWorkspaceApprovalParams; [WRITE_COMMANDS.CREATE_EXPENSIFY_CARD]: Parameters.CreateExpensifyCardParams; + [WRITE_COMMANDS.CREATE_ADMIN_ISSUED_VIRTUAL_CARD]: Omit; }; const READ_COMMANDS = { diff --git a/src/libs/actions/Card.ts b/src/libs/actions/Card.ts index 205a8dc41bba..71e40830bf36 100644 --- a/src/libs/actions/Card.ts +++ b/src/libs/actions/Card.ts @@ -381,6 +381,24 @@ function startIssueNewCardFlow(policyID: string) { API.read(READ_COMMANDS.START_ISSUE_NEW_CARD_FLOW, parameters); } +function issueExpensifyCard(policyID: string, feedCountry: string, {assigneeEmail, limit, limitType, cardTitle, cardType}: IssueNewCardData) { + const parameters = { + policyID, + assigneeEmail, + limit, + limitType, + cardTitle, + }; + + if (cardType === CONST.EXPENSIFY_CARD.CARD_TYPE.PHYSICAL) { + API.write(WRITE_COMMANDS.CREATE_EXPENSIFY_CARD, {...parameters, feedCountry}); + return; + } + + // eslint-disable-next-line rulesdir/no-multiple-api-calls + API.write(WRITE_COMMANDS.CREATE_ADMIN_ISSUED_VIRTUAL_CARD, parameters); +} + export { requestReplacementExpensifyCard, activatePhysicalExpensifyCard, @@ -393,5 +411,6 @@ export { updateExpensifyCardLimit, updateSettlementAccount, startIssueNewCardFlow, + issueExpensifyCard, }; export type {ReplacementReason}; diff --git a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx index c063f4246a56..3c3e4de9d822 100644 --- a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx +++ b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx @@ -1,5 +1,6 @@ import React from 'react'; import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; @@ -18,19 +19,34 @@ import Navigation from '@navigation/Navigation'; import * as Card from '@userActions/Card'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type * as OnyxTypes from '@src/types/onyx'; import type {IssueNewCardStep} from '@src/types/onyx/Card'; -function ConfirmationStep() { +type ConfirmationStepProps = { + // The policy that the card will be issued under + policy: OnyxEntry; +}; + +const defaultData = { + assigneeEmail: '', + cardTitle: '', + cardType: CONST.EXPENSIFY_CARD.CARD_TYPE.VIRTUAL, + limit: 0, + limitType: CONST.EXPENSIFY_CARD.LIMIT_TYPES.MONTHLY, +}; + +function ConfirmationStep({policy}: ConfirmationStepProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isOffline} = useNetwork(); const [issueNewCard] = useOnyx(ONYXKEYS.ISSUE_NEW_EXPENSIFY_CARD); - const data = issueNewCard?.data; + const data = issueNewCard?.data ?? defaultData; + const policyID = policy?.id ?? '-1'; const submit = () => { - // TODO: the logic will be created when CreateExpensifyCard is ready + Card.issueExpensifyCard(policyID, 'USA', data); Navigation.goBack(); Card.clearIssueNewCardFlow(); }; diff --git a/src/pages/workspace/expensifyCard/issueNew/IssueNewCardPage.tsx b/src/pages/workspace/expensifyCard/issueNew/IssueNewCardPage.tsx index b16f6ef1dafc..33a5fe13acb9 100644 --- a/src/pages/workspace/expensifyCard/issueNew/IssueNewCardPage.tsx +++ b/src/pages/workspace/expensifyCard/issueNew/IssueNewCardPage.tsx @@ -34,7 +34,7 @@ function IssueNewCardPage({policy}: WithPolicyAndFullscreenLoadingProps) { case CONST.EXPENSIFY_CARD.STEP.CARD_NAME: return ; case CONST.EXPENSIFY_CARD.STEP.CONFIRMATION: - return ; + return ; default: return ; } From 63cde08dac23beea83b5b02f6311e23315c91255 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 7 Aug 2024 10:46:40 +0200 Subject: [PATCH 3/7] fix: minor fix --- src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx index 3c3e4de9d822..31a2c4164fb4 100644 --- a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx +++ b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx @@ -46,7 +46,7 @@ function ConfirmationStep({policy}: ConfirmationStepProps) { const policyID = policy?.id ?? '-1'; const submit = () => { - Card.issueExpensifyCard(policyID, 'USA', data); + Card.issueExpensifyCard(policyID, CONST.COUNTRY.US, data); Navigation.goBack(); Card.clearIssueNewCardFlow(); }; From 38b159a8f83cb063b3b0375911fa658763a474c1 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 7 Aug 2024 17:38:02 +0200 Subject: [PATCH 4/7] fix: remove unnecessary line --- src/libs/API/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index e8c3629d81b9..807027e0858c 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -768,7 +768,6 @@ type ReadCommandParameters = { [READ_COMMANDS.OPEN_SUBSCRIPTION_PAGE]: null; [READ_COMMANDS.OPEN_DRAFT_DISTANCE_EXPENSE]: null; [READ_COMMANDS.START_ISSUE_NEW_CARD_FLOW]: Parameters.StartIssueNewCardFlowParams; - [READ_COMMANDS.START_ISSUE_NEW_CARD_FLOW]: Parameters.StartIssueNewCardFlowParams; }; const SIDE_EFFECT_REQUEST_COMMANDS = { From 37a4fd7b274d6b901da805e5dd3a85204280fae8 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 13 Aug 2024 10:03:34 +0200 Subject: [PATCH 5/7] fix: apply requested changes --- src/libs/actions/Card.ts | 8 +++++++- .../workspace/expensifyCard/issueNew/ConfirmationStep.tsx | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Card.ts b/src/libs/actions/Card.ts index a8def529994d..0ca6a63a61f3 100644 --- a/src/libs/actions/Card.ts +++ b/src/libs/actions/Card.ts @@ -394,7 +394,13 @@ function configureExpensifyCardsForPolicy(policyID: string, bankAccountID?: numb API.write(WRITE_COMMANDS.CONFIGURE_EXPENSIFY_CARDS_FOR_POLICY, parameters); } -function issueExpensifyCard(policyID: string, feedCountry: string, {assigneeEmail, limit, limitType, cardTitle, cardType}: IssueNewCardData) { +function issueExpensifyCard(policyID: string, feedCountry: string, data?: IssueNewCardData) { + if (!data) { + return; + } + + const {assigneeEmail, limit, limitType, cardTitle, cardType} = data; + const parameters = { policyID, assigneeEmail, diff --git a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx index 31a2c4164fb4..819a859cef5d 100644 --- a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx +++ b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx @@ -42,7 +42,7 @@ function ConfirmationStep({policy}: ConfirmationStepProps) { const [issueNewCard] = useOnyx(ONYXKEYS.ISSUE_NEW_EXPENSIFY_CARD); - const data = issueNewCard?.data ?? defaultData; + const data = issueNewCard?.data; const policyID = policy?.id ?? '-1'; const submit = () => { From 948d646117f28b22f7fa55dae853da9d3ea0ce7f Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 13 Aug 2024 11:02:22 +0200 Subject: [PATCH 6/7] fix: lint --- .../workspace/expensifyCard/issueNew/ConfirmationStep.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx index 819a859cef5d..7295b120e471 100644 --- a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx +++ b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx @@ -27,14 +27,6 @@ type ConfirmationStepProps = { policy: OnyxEntry; }; -const defaultData = { - assigneeEmail: '', - cardTitle: '', - cardType: CONST.EXPENSIFY_CARD.CARD_TYPE.VIRTUAL, - limit: 0, - limitType: CONST.EXPENSIFY_CARD.LIMIT_TYPES.MONTHLY, -}; - function ConfirmationStep({policy}: ConfirmationStepProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); From f63c718e0fa0c0affe0575f803576f1e15f2d60b Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 13 Aug 2024 12:56:51 +0200 Subject: [PATCH 7/7] fix: apply requested changes --- .../expensifyCard/issueNew/ConfirmationStep.tsx | 9 +++------ .../expensifyCard/issueNew/IssueNewCardPage.tsx | 8 +++++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx index 7295b120e471..75758e84e62c 100644 --- a/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx +++ b/src/pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx @@ -1,6 +1,5 @@ import React from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; @@ -19,15 +18,14 @@ import Navigation from '@navigation/Navigation'; import * as Card from '@userActions/Card'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type * as OnyxTypes from '@src/types/onyx'; import type {IssueNewCardStep} from '@src/types/onyx/Card'; type ConfirmationStepProps = { - // The policy that the card will be issued under - policy: OnyxEntry; + // ID of the policy that the card will be issued under + policyID: string; }; -function ConfirmationStep({policy}: ConfirmationStepProps) { +function ConfirmationStep({policyID}: ConfirmationStepProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isOffline} = useNetwork(); @@ -35,7 +33,6 @@ function ConfirmationStep({policy}: ConfirmationStepProps) { const [issueNewCard] = useOnyx(ONYXKEYS.ISSUE_NEW_EXPENSIFY_CARD); const data = issueNewCard?.data; - const policyID = policy?.id ?? '-1'; const submit = () => { Card.issueExpensifyCard(policyID, CONST.COUNTRY.US, data); diff --git a/src/pages/workspace/expensifyCard/issueNew/IssueNewCardPage.tsx b/src/pages/workspace/expensifyCard/issueNew/IssueNewCardPage.tsx index 33a5fe13acb9..f1cd737eed46 100644 --- a/src/pages/workspace/expensifyCard/issueNew/IssueNewCardPage.tsx +++ b/src/pages/workspace/expensifyCard/issueNew/IssueNewCardPage.tsx @@ -17,10 +17,12 @@ function IssueNewCardPage({policy}: WithPolicyAndFullscreenLoadingProps) { const {currentStep} = issueNewCard ?? {}; + const policyID = policy?.id ?? '-1'; + // TODO: add logic to skip Assignee step when the flow is started from the member's profile page useEffect(() => { - Card.startIssueNewCardFlow(policy?.id ?? '-1'); - }, [policy?.id]); + Card.startIssueNewCardFlow(policyID); + }, [policyID]); switch (currentStep) { case CONST.EXPENSIFY_CARD.STEP.ASSIGNEE: @@ -34,7 +36,7 @@ function IssueNewCardPage({policy}: WithPolicyAndFullscreenLoadingProps) { case CONST.EXPENSIFY_CARD.STEP.CARD_NAME: return ; case CONST.EXPENSIFY_CARD.STEP.CONFIRMATION: - return ; + return ; default: return ; }