From 10cb535cedbe180f6ef73c90bd6f8a9a501d6573 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Wed, 3 Jan 2024 12:02:34 +0300 Subject: [PATCH 01/21] Migrate SettlementButton.js component to TypeScript --- src/components/KYCWall/kycWallPropTypes.js | 5 + ...ttlementButton.js => SettlementButton.tsx} | 189 +++++++----------- 2 files changed, 79 insertions(+), 115 deletions(-) rename src/components/{SettlementButton.js => SettlementButton.tsx} (65%) diff --git a/src/components/KYCWall/kycWallPropTypes.js b/src/components/KYCWall/kycWallPropTypes.js index 2f14f1e12e11..aeda8544dd0d 100644 --- a/src/components/KYCWall/kycWallPropTypes.js +++ b/src/components/KYCWall/kycWallPropTypes.js @@ -65,6 +65,11 @@ const propTypes = { /** Whether the personal bank account option should be shown */ shouldShowPersonalBankAccountOption: PropTypes.bool, + + /** Callback to execute when KYC is successful */ + onSuccessfulKYC: PropTypes.func.isRequired, + + children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired, }; const defaultProps = { diff --git a/src/components/SettlementButton.js b/src/components/SettlementButton.tsx similarity index 65% rename from src/components/SettlementButton.js rename to src/components/SettlementButton.tsx index 0c8e193af4cc..2786cd852434 100644 --- a/src/components/SettlementButton.js +++ b/src/components/SettlementButton.tsx @@ -1,143 +1,106 @@ -import PropTypes from 'prop-types'; -import React, {useEffect, useMemo} from 'react'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; +import _ from 'lodash'; +import React, {MutableRefObject, useEffect, useMemo} from 'react'; +import {StyleProp, ViewStyle} from 'react-native'; +import {OnyxEntry, withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; -import compose from '@libs/compose'; import * as ReportUtils from '@libs/ReportUtils'; -import iouReportPropTypes from '@pages/iouReportPropTypes'; import * as BankAccounts from '@userActions/BankAccounts'; import * as IOU from '@userActions/IOU'; import * as PaymentMethods from '@userActions/PaymentMethods'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import {ButtonSizeValue} from '@src/styles/utils/types'; +import type {Report} from '@src/types/onyx'; +import {EmptyObject} from '@src/types/utils/EmptyObject'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import * as Expensicons from './Icon/Expensicons'; import KYCWall from './KYCWall'; -import withNavigation from './withNavigation'; -const propTypes = { - /** Callback to execute when this button is pressed. Receives a single payment type argument. */ - onPress: PropTypes.func.isRequired, +type AnchorAlignment = { + horizontal: 'left' | 'right' | 'center'; + vertical: 'top' | 'center' | 'bottom'; +}; - /** Call the onPress function on main button when Enter key is pressed */ - pressOnEnter: PropTypes.bool, +type TriggerKYCFlow = (event: Event, iouPaymentType: string) => void; - /** Settlement currency type */ - currency: PropTypes.string, +type SettlementButtonOnyxProps = { + /** The last payment method used per policy */ + nvpLastPaymentMethod?: Record; +}; +type SettlementButtonProps = SettlementButtonOnyxProps & { + /** Callback to execute when this button is pressed. Receives a single payment type argument. */ + onPress: (paymentType: string) => void; + /** The route to redirect if user does not have a payment method setup */ + enablePaymentsRoute: string; + /** Call the onPress function on main button when Enter key is pressed */ + pressOnEnter?: boolean; + /** Settlement currency type */ + currency?: string; /** When the button is opened via an IOU, ID for the chatReport that the IOU is linked to */ - chatReportID: PropTypes.string, - + chatReportID?: string; /** The IOU/Expense report we are paying */ - iouReport: iouReportPropTypes, - - /** The route to redirect if user does not have a payment method setup */ - enablePaymentsRoute: PropTypes.string.isRequired, - - /** Should we show the approve button? */ - shouldHidePaymentOptions: PropTypes.bool, - + iouReport?: OnyxEntry | EmptyObject; /** Should we show the payment options? */ - shouldShowApproveButton: PropTypes.bool, - - /** The last payment method used per policy */ - nvp_lastPaymentMethod: PropTypes.objectOf(PropTypes.string), - + shouldHidePaymentOptions?: boolean; + /** Should we show the payment options? */ + shouldShowApproveButton?: boolean; /** The policyID of the report we are paying */ - policyID: PropTypes.string, - + policyID?: string; /** Additional styles to add to the component */ - style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), - + style?: StyleProp; /** Total money amount in form */ - formattedAmount: PropTypes.string, - + formattedAmount?: string; /** The size of button size */ - buttonSize: PropTypes.oneOf(_.values(CONST.DROPDOWN_BUTTON_SIZE)), - + buttonSize?: ButtonSizeValue; // Replace with the actual sizes /** Route for the Add Bank Account screen for a given navigation stack */ - addBankAccountRoute: PropTypes.string, - + addBankAccountRoute?: string; /** Route for the Add Debit Card screen for a given navigation stack */ - addDebitCardRoute: PropTypes.string, - + addDebitCardRoute?: string; /** Whether the button should be disabled */ - isDisabled: PropTypes.bool, - + isDisabled?: boolean; /** Whether we should show a loading state for the main button */ - isLoading: PropTypes.bool, - + isLoading?: boolean; /** The anchor alignment of the popover menu for payment method dropdown */ - paymentMethodDropdownAnchorAlignment: PropTypes.shape({ - horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)), - vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)), - }), - + paymentMethodDropdownAnchorAlignment?: AnchorAlignment; /** The anchor alignment of the popover menu for KYC wall popover */ - kycWallAnchorAlignment: PropTypes.shape({ - horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)), - vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)), - }), - + kycWallAnchorAlignment?: AnchorAlignment; /** Whether the personal bank account option should be shown */ - shouldShowPersonalBankAccountOption: PropTypes.bool, + shouldShowPersonalBankAccountOption?: boolean; }; -const defaultProps = { - isLoading: false, - isDisabled: false, - pressOnEnter: false, - addBankAccountRoute: '', - addDebitCardRoute: '', - currency: CONST.CURRENCY.USD, - chatReportID: '', - - // The "iouReport" and "nvp_lastPaymentMethod" objects needs to be stable to prevent the "useMemo" - // hook from being recreated unnecessarily, hence the use of CONST.EMPTY_ARRAY and CONST.EMPTY_OBJECT - iouReport: CONST.EMPTY_OBJECT, - nvp_lastPaymentMethod: CONST.EMPTY_OBJECT, - shouldHidePaymentOptions: false, - shouldShowApproveButton: false, - style: [], - policyID: '', - formattedAmount: '', - buttonSize: CONST.DROPDOWN_BUTTON_SIZE.MEDIUM, - kycWallAnchorAlignment: { +function SettlementButton({ + addDebitCardRoute = '', + addBankAccountRoute = '', + kycWallAnchorAlignment = { horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, // button is at left, so horizontal anchor is at LEFT vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP, // we assume that popover menu opens below the button, anchor is at TOP }, - paymentMethodDropdownAnchorAlignment: { + paymentMethodDropdownAnchorAlignment = { horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT, // caret for dropdown is at right, so horizontal anchor is at RIGHT vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP, // we assume that popover menu opens below the button, anchor is at TOP }, - shouldShowPersonalBankAccountOption: false, -}; - -function SettlementButton({ - addDebitCardRoute, - addBankAccountRoute, - kycWallAnchorAlignment, - paymentMethodDropdownAnchorAlignment, - buttonSize, - chatReportID, - currency, + buttonSize = CONST.DROPDOWN_BUTTON_SIZE.MEDIUM, + chatReportID = '', + currency = CONST.CURRENCY.USD, enablePaymentsRoute, - iouReport, - isDisabled, - isLoading, - formattedAmount, - nvp_lastPaymentMethod, + // The "iouReport" and "nvpLastPaymentMethod" objects needs to be stable to prevent the "useMemo" + // hook from being recreated unnecessarily, hence the use of CONST.EMPTY_ARRAY and CONST.EMPTY_OBJECT + iouReport = CONST.EMPTY_OBJECT, + nvpLastPaymentMethod = CONST.EMPTY_OBJECT, + isDisabled = false, + isLoading = false, + formattedAmount = '', onPress, - pressOnEnter, - policyID, - shouldHidePaymentOptions, - shouldShowApproveButton, - style, - shouldShowPersonalBankAccountOption, -}) { + pressOnEnter = false, + policyID = '', + shouldHidePaymentOptions = false, + shouldShowApproveButton = false, + style = [], + shouldShowPersonalBankAccountOption = false, +}: SettlementButtonProps) { const {translate} = useLocalize(); const {isOffline} = useNetwork(); @@ -179,7 +142,7 @@ function SettlementButton({ // To achieve the one tap pay experience we need to choose the correct payment type as default, // if user already paid for some request or expense, let's use the last payment method or use default. - const paymentMethod = nvp_lastPaymentMethod[policyID] || ''; + const paymentMethod = nvpLastPaymentMethod[policyID] || ''; if (canUseWallet) { buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.EXPENSIFY]); } @@ -197,9 +160,9 @@ function SettlementButton({ return _.sortBy(buttonOptions, (method) => (method.value === paymentMethod ? 0 : 1)); } return buttonOptions; - }, [currency, formattedAmount, iouReport, nvp_lastPaymentMethod, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton]); + }, [currency, formattedAmount, iouReport, nvpLastPaymentMethod, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton]); - const selectPaymentType = (event, iouPaymentType, triggerKYCFlow) => { + const selectPaymentType = (event: Event, iouPaymentType: string, triggerKYCFlow: TriggerKYCFlow) => { if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || iouPaymentType === CONST.IOU.PAYMENT_TYPE.VBBA) { triggerKYCFlow(event, iouPaymentType); BankAccounts.setPersonalBankAccountContinueKYCOnSuccess(ROUTES.ENABLE_PAYMENTS); @@ -227,7 +190,7 @@ function SettlementButton({ anchorAlignment={kycWallAnchorAlignment} shouldShowPersonalBankAccountOption={shouldShowPersonalBankAccountOption} > - {(triggerKYCFlow, buttonRef) => ( + {(triggerKYCFlow: TriggerKYCFlow, buttonRef: MutableRefObject) => ( selectPaymentType(event, iouPaymentType, triggerKYCFlow)} pressOnEnter={pressOnEnter} options={paymentButtonOptions} - style={style} + style={[style]} buttonSize={buttonSize} anchorAlignment={paymentMethodDropdownAnchorAlignment} /> @@ -244,15 +207,11 @@ function SettlementButton({ ); } -SettlementButton.propTypes = propTypes; -SettlementButton.defaultProps = defaultProps; SettlementButton.displayName = 'SettlementButton'; -export default compose( - withNavigation, - withOnyx({ - nvp_lastPaymentMethod: { - key: ONYXKEYS.NVP_LAST_PAYMENT_METHOD, - }, - }), -)(SettlementButton); +export default withOnyx({ + nvpLastPaymentMethod: { + key: ONYXKEYS.NVP_LAST_PAYMENT_METHOD, + selector: (paymentMethod) => paymentMethod ?? {}, + }, +})(SettlementButton); From 53e4b00429ebc9663d55599f3487d90280faea69 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Wed, 3 Jan 2024 13:06:18 +0300 Subject: [PATCH 02/21] Update types --- src/components/SettlementButton.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 2786cd852434..3eb4ac844fb2 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -195,10 +195,10 @@ function SettlementButton({ buttonRef={buttonRef} isDisabled={isDisabled} isLoading={isLoading} - onPress={(event, iouPaymentType) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} + onPress={(event: Event, iouPaymentType: string) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} pressOnEnter={pressOnEnter} options={paymentButtonOptions} - style={[style]} + style={style as Record} buttonSize={buttonSize} anchorAlignment={paymentMethodDropdownAnchorAlignment} /> From dcdf95b12e86c34f0efb4f366c0b01ee02fabf0b Mon Sep 17 00:00:00 2001 From: Yauheni Date: Fri, 5 Jan 2024 13:30:24 +0300 Subject: [PATCH 03/21] Update types --- src/components/Popover/types.ts | 13 ++-------- src/components/PopoverMenu.tsx | 2 +- src/components/SettlementButton.tsx | 37 ++++++++++++++++------------- src/types/onyx/AnchorAlignment.ts | 12 ++++++++++ 4 files changed, 35 insertions(+), 29 deletions(-) create mode 100644 src/types/onyx/AnchorAlignment.ts diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 3d1f95822e6a..4875676a3caa 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -1,16 +1,7 @@ -import type {ValueOf} from 'type-fest'; import type {PopoverAnchorPosition} from '@components/Modal/types'; import type BaseModalProps from '@components/Modal/types'; import type {WindowDimensionsProps} from '@components/withWindowDimensions/types'; -import type CONST from '@src/CONST'; - -type AnchorAlignment = { - /** The horizontal anchor alignment of the popover */ - horizontal: ValueOf; - - /** The vertical anchor alignment of the popover */ - vertical: ValueOf; -}; +import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; type PopoverDimensions = { width: number; @@ -48,4 +39,4 @@ type PopoverProps = BaseModalProps & { type PopoverWithWindowDimensionsProps = PopoverProps & WindowDimensionsProps; -export type {PopoverProps, PopoverWithWindowDimensionsProps, AnchorAlignment}; +export type {PopoverProps, PopoverWithWindowDimensionsProps}; diff --git a/src/components/PopoverMenu.tsx b/src/components/PopoverMenu.tsx index 502bdbf83b53..9b59b87056e0 100644 --- a/src/components/PopoverMenu.tsx +++ b/src/components/PopoverMenu.tsx @@ -10,8 +10,8 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import CONST from '@src/CONST'; import type {AnchorPosition} from '@src/styles'; +import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; import MenuItem from './MenuItem'; -import type {AnchorAlignment} from './Popover/types'; import PopoverWithMeasuredContent from './PopoverWithMeasuredContent'; import Text from './Text'; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 3eb4ac844fb2..f09a31701536 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -1,7 +1,9 @@ import _ from 'lodash'; -import React, {MutableRefObject, useEffect, useMemo} from 'react'; -import {StyleProp, ViewStyle} from 'react-native'; -import {OnyxEntry, withOnyx} from 'react-native-onyx'; +import type {MutableRefObject} from 'react'; +import React, {useEffect, useMemo} from 'react'; +import type {StyleProp, ViewStyle} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import * as ReportUtils from '@libs/ReportUtils'; @@ -11,30 +13,29 @@ import * as PaymentMethods from '@userActions/PaymentMethods'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import {ButtonSizeValue} from '@src/styles/utils/types'; +import type {ButtonSizeValue} from '@src/styles/utils/types'; import type {Report} from '@src/types/onyx'; -import {EmptyObject} from '@src/types/utils/EmptyObject'; +import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; +import type DeepValueOf from '@src/types/utils/DeepValueOf'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import * as Expensicons from './Icon/Expensicons'; import KYCWall from './KYCWall'; -type AnchorAlignment = { - horizontal: 'left' | 'right' | 'center'; - vertical: 'top' | 'center' | 'bottom'; -}; - type TriggerKYCFlow = (event: Event, iouPaymentType: string) => void; +type PaymentType = DeepValueOf; + type SettlementButtonOnyxProps = { /** The last payment method used per policy */ - nvpLastPaymentMethod?: Record; + nvpLastPaymentMethod?: OnyxEntry>; }; type SettlementButtonProps = SettlementButtonOnyxProps & { /** Callback to execute when this button is pressed. Receives a single payment type argument. */ - onPress: (paymentType: string) => void; + onPress: (paymentType: PaymentType) => void; /** The route to redirect if user does not have a payment method setup */ - enablePaymentsRoute: string; + enablePaymentsRoute: typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEND_ENABLE_PAYMENTS | typeof ROUTES.SETTINGS_ENABLE_PAYMENTS; /** Call the onPress function on main button when Enter key is pressed */ pressOnEnter?: boolean; /** Settlement currency type */ @@ -98,7 +99,7 @@ function SettlementButton({ policyID = '', shouldHidePaymentOptions = false, shouldShowApproveButton = false, - style = [], + style, shouldShowPersonalBankAccountOption = false, }: SettlementButtonProps) { const {translate} = useLocalize(); @@ -142,7 +143,7 @@ function SettlementButton({ // To achieve the one tap pay experience we need to choose the correct payment type as default, // if user already paid for some request or expense, let's use the last payment method or use default. - const paymentMethod = nvpLastPaymentMethod[policyID] || ''; + const paymentMethod = nvpLastPaymentMethod?.[policyID] ?? ''; if (canUseWallet) { buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.EXPENSIFY]); } @@ -162,7 +163,7 @@ function SettlementButton({ return buttonOptions; }, [currency, formattedAmount, iouReport, nvpLastPaymentMethod, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton]); - const selectPaymentType = (event: Event, iouPaymentType: string, triggerKYCFlow: TriggerKYCFlow) => { + const selectPaymentType = (event: Event, iouPaymentType: PaymentType, triggerKYCFlow: TriggerKYCFlow) => { if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || iouPaymentType === CONST.IOU.PAYMENT_TYPE.VBBA) { triggerKYCFlow(event, iouPaymentType); BankAccounts.setPersonalBankAccountContinueKYCOnSuccess(ROUTES.ENABLE_PAYMENTS); @@ -195,7 +196,9 @@ function SettlementButton({ buttonRef={buttonRef} isDisabled={isDisabled} isLoading={isLoading} - onPress={(event: Event, iouPaymentType: string) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} + onPress={(event: Event, iouPaymentType: PaymentType) => + selectPaymentType(event, iouPaymentType, triggerKYCFlow) + } pressOnEnter={pressOnEnter} options={paymentButtonOptions} style={style as Record} diff --git a/src/types/onyx/AnchorAlignment.ts b/src/types/onyx/AnchorAlignment.ts new file mode 100644 index 000000000000..899e3d9e277b --- /dev/null +++ b/src/types/onyx/AnchorAlignment.ts @@ -0,0 +1,12 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type AnchorAlignment = { + /** The horizontal anchor alignment of the popover */ + horizontal: ValueOf; + + /** The vertical anchor alignment of the popover */ + vertical: ValueOf; +}; + +export default AnchorAlignment; From f3004da4052942de46f8134f1faa9a9434794593 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Fri, 5 Jan 2024 15:01:21 +0300 Subject: [PATCH 04/21] Update types x2 --- src/components/SettlementButton.tsx | 39 +++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index f09a31701536..a11481c99cb1 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -1,7 +1,6 @@ -import _ from 'lodash'; import type {MutableRefObject} from 'react'; import React, {useEffect, useMemo} from 'react'; -import type {StyleProp, ViewStyle} from 'react-native'; +import type {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; @@ -11,6 +10,7 @@ import * as BankAccounts from '@userActions/BankAccounts'; import * as IOU from '@userActions/IOU'; import * as PaymentMethods from '@userActions/PaymentMethods'; import CONST from '@src/CONST'; +import type {OnyxValues} from '@src/ONYXKEYS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; @@ -22,52 +22,72 @@ import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import * as Expensicons from './Icon/Expensicons'; import KYCWall from './KYCWall'; +type Event = GestureResponderEvent | KeyboardEvent; + type TriggerKYCFlow = (event: Event, iouPaymentType: string) => void; type PaymentType = DeepValueOf; type SettlementButtonOnyxProps = { /** The last payment method used per policy */ - nvpLastPaymentMethod?: OnyxEntry>; + nvpLastPaymentMethod?: OnyxEntry; }; type SettlementButtonProps = SettlementButtonOnyxProps & { /** Callback to execute when this button is pressed. Receives a single payment type argument. */ onPress: (paymentType: PaymentType) => void; + /** The route to redirect if user does not have a payment method setup */ enablePaymentsRoute: typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEND_ENABLE_PAYMENTS | typeof ROUTES.SETTINGS_ENABLE_PAYMENTS; + /** Call the onPress function on main button when Enter key is pressed */ pressOnEnter?: boolean; + /** Settlement currency type */ currency?: string; + /** When the button is opened via an IOU, ID for the chatReport that the IOU is linked to */ chatReportID?: string; + /** The IOU/Expense report we are paying */ iouReport?: OnyxEntry | EmptyObject; + /** Should we show the payment options? */ shouldHidePaymentOptions?: boolean; + /** Should we show the payment options? */ shouldShowApproveButton?: boolean; + /** The policyID of the report we are paying */ policyID?: string; + /** Additional styles to add to the component */ style?: StyleProp; + /** Total money amount in form */ formattedAmount?: string; + /** The size of button size */ - buttonSize?: ButtonSizeValue; // Replace with the actual sizes + buttonSize?: ButtonSizeValue; + /** Route for the Add Bank Account screen for a given navigation stack */ addBankAccountRoute?: string; + /** Route for the Add Debit Card screen for a given navigation stack */ addDebitCardRoute?: string; + /** Whether the button should be disabled */ isDisabled?: boolean; + /** Whether we should show a loading state for the main button */ isLoading?: boolean; + /** The anchor alignment of the popover menu for payment method dropdown */ paymentMethodDropdownAnchorAlignment?: AnchorAlignment; + /** The anchor alignment of the popover menu for KYC wall popover */ kycWallAnchorAlignment?: AnchorAlignment; + /** Whether the personal bank account option should be shown */ shouldShowPersonalBankAccountOption?: boolean; }; @@ -158,7 +178,7 @@ function SettlementButton({ // Put the preferred payment method to the front of the array so its shown as default if (paymentMethod) { - return _.sortBy(buttonOptions, (method) => (method.value === paymentMethod ? 0 : 1)); + return buttonOptions.sort((method) => (method.value === paymentMethod ? 0 : 1)); } return buttonOptions; }, [currency, formattedAmount, iouReport, nvpLastPaymentMethod, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton]); @@ -191,17 +211,16 @@ function SettlementButton({ anchorAlignment={kycWallAnchorAlignment} shouldShowPersonalBankAccountOption={shouldShowPersonalBankAccountOption} > - {(triggerKYCFlow: TriggerKYCFlow, buttonRef: MutableRefObject) => ( + {(triggerKYCFlow: TriggerKYCFlow, buttonRef: MutableRefObject) => ( - selectPaymentType(event, iouPaymentType, triggerKYCFlow) - } + onPress={(event: Event, iouPaymentType: PaymentType) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} pressOnEnter={pressOnEnter} options={paymentButtonOptions} - style={style as Record} + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/issues/25065) is migrated to TypeScript. + style={style} buttonSize={buttonSize} anchorAlignment={paymentMethodDropdownAnchorAlignment} /> From c92cde7964361533e28ef4b04f8ce1880faba90a Mon Sep 17 00:00:00 2001 From: Yauheni Date: Mon, 8 Jan 2024 10:59:51 +0300 Subject: [PATCH 05/21] Fix ts issue --- src/components/ProcessMoneyRequestHoldMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ProcessMoneyRequestHoldMenu.tsx b/src/components/ProcessMoneyRequestHoldMenu.tsx index 1b711633ed3b..a6b53da467b5 100644 --- a/src/components/ProcessMoneyRequestHoldMenu.tsx +++ b/src/components/ProcessMoneyRequestHoldMenu.tsx @@ -2,11 +2,11 @@ import React from 'react'; import {View} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; import Button from './Button'; import HoldMenuSectionList from './HoldMenuSectionList'; import type {PopoverAnchorPosition} from './Modal/types'; import Popover from './Popover'; -import type {AnchorAlignment} from './Popover/types'; import Text from './Text'; import TextPill from './TextPill'; From 3fec0575686d919ac3e1b341e39dfb281fae9b43 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Tue, 9 Jan 2024 18:39:13 +0100 Subject: [PATCH 06/21] Fix comments --- src/components/SettlementButton.tsx | 15 +++++++-------- src/types/onyx/LastPaymentMethod.ts | 3 +++ src/types/onyx/index.ts | 2 ++ 3 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 src/types/onyx/LastPaymentMethod.ts diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index a11481c99cb1..1ad4cb496008 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -10,11 +10,10 @@ import * as BankAccounts from '@userActions/BankAccounts'; import * as IOU from '@userActions/IOU'; import * as PaymentMethods from '@userActions/PaymentMethods'; import CONST from '@src/CONST'; -import type {OnyxValues} from '@src/ONYXKEYS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; -import type {Report} from '@src/types/onyx'; +import type {LastPaymentMethod, Report} from '@src/types/onyx'; import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; @@ -22,15 +21,15 @@ import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import * as Expensicons from './Icon/Expensicons'; import KYCWall from './KYCWall'; -type Event = GestureResponderEvent | KeyboardEvent; +type KYCFlowEvent = GestureResponderEvent | KeyboardEvent; -type TriggerKYCFlow = (event: Event, iouPaymentType: string) => void; +type TriggerKYCFlow = (event: KYCFlowEvent, iouPaymentType: string) => void; type PaymentType = DeepValueOf; type SettlementButtonOnyxProps = { /** The last payment method used per policy */ - nvpLastPaymentMethod?: OnyxEntry; + nvpLastPaymentMethod?: OnyxEntry; }; type SettlementButtonProps = SettlementButtonOnyxProps & { @@ -183,7 +182,7 @@ function SettlementButton({ return buttonOptions; }, [currency, formattedAmount, iouReport, nvpLastPaymentMethod, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton]); - const selectPaymentType = (event: Event, iouPaymentType: PaymentType, triggerKYCFlow: TriggerKYCFlow) => { + const selectPaymentType = (event: KYCFlowEvent, iouPaymentType: PaymentType, triggerKYCFlow: TriggerKYCFlow) => { if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || iouPaymentType === CONST.IOU.PAYMENT_TYPE.VBBA) { triggerKYCFlow(event, iouPaymentType); BankAccounts.setPersonalBankAccountContinueKYCOnSuccess(ROUTES.ENABLE_PAYMENTS); @@ -211,12 +210,12 @@ function SettlementButton({ anchorAlignment={kycWallAnchorAlignment} shouldShowPersonalBankAccountOption={shouldShowPersonalBankAccountOption} > - {(triggerKYCFlow: TriggerKYCFlow, buttonRef: MutableRefObject) => ( + {(triggerKYCFlow: TriggerKYCFlow, buttonRef: MutableRefObject) => ( selectPaymentType(event, iouPaymentType, triggerKYCFlow)} + onPress={(event: KYCFlowEvent, iouPaymentType: PaymentType) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} pressOnEnter={pressOnEnter} options={paymentButtonOptions} // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/issues/25065) is migrated to TypeScript. diff --git a/src/types/onyx/LastPaymentMethod.ts b/src/types/onyx/LastPaymentMethod.ts new file mode 100644 index 000000000000..677a23fa9586 --- /dev/null +++ b/src/types/onyx/LastPaymentMethod.ts @@ -0,0 +1,3 @@ +type LastPaymentMethod = Record; + +export default LastPaymentMethod; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 7bd9c321be5e..824275ace170 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -15,6 +15,7 @@ import type FrequentlyUsedEmoji from './FrequentlyUsedEmoji'; import type {FundList} from './Fund'; import type Fund from './Fund'; import type IOU from './IOU'; +import type LastPaymentMethod from './LastPaymentMethod'; import type Locale from './Locale'; import type {LoginList} from './Login'; import type Login from './Login'; @@ -137,4 +138,5 @@ export type { ReportUserIsTyping, PolicyReportField, RecentlyUsedReportFields, + LastPaymentMethod, }; From 5754adc74b3158b0c0d63a74999974f6cf709dc7 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Wed, 10 Jan 2024 11:34:14 +0100 Subject: [PATCH 07/21] Update type imports --- src/components/Popover/types.ts | 2 +- src/components/PopoverMenu.tsx | 2 +- src/components/ProcessMoneyRequestHoldMenu.tsx | 2 +- src/components/SettlementButton.tsx | 3 +-- src/types/onyx/index.ts | 2 ++ 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 4875676a3caa..298c95eeca76 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -1,7 +1,7 @@ import type {PopoverAnchorPosition} from '@components/Modal/types'; import type BaseModalProps from '@components/Modal/types'; import type {WindowDimensionsProps} from '@components/withWindowDimensions/types'; -import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; +import type {AnchorAlignment} from '@src/types/onyx'; type PopoverDimensions = { width: number; diff --git a/src/components/PopoverMenu.tsx b/src/components/PopoverMenu.tsx index 9b59b87056e0..0a1fdf38a172 100644 --- a/src/components/PopoverMenu.tsx +++ b/src/components/PopoverMenu.tsx @@ -10,7 +10,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import CONST from '@src/CONST'; import type {AnchorPosition} from '@src/styles'; -import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; +import type {AnchorAlignment} from '@src/types/onyx'; import MenuItem from './MenuItem'; import PopoverWithMeasuredContent from './PopoverWithMeasuredContent'; import Text from './Text'; diff --git a/src/components/ProcessMoneyRequestHoldMenu.tsx b/src/components/ProcessMoneyRequestHoldMenu.tsx index a6b53da467b5..1fd37b82afc8 100644 --- a/src/components/ProcessMoneyRequestHoldMenu.tsx +++ b/src/components/ProcessMoneyRequestHoldMenu.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {View} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; +import type {AnchorAlignment} from '@src/types/onyx'; import Button from './Button'; import HoldMenuSectionList from './HoldMenuSectionList'; import type {PopoverAnchorPosition} from './Modal/types'; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 1ad4cb496008..2fe45e6f7b90 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -13,8 +13,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; -import type {LastPaymentMethod, Report} from '@src/types/onyx'; -import type AnchorAlignment from '@src/types/onyx/AnchorAlignment'; +import type {AnchorAlignment, LastPaymentMethod, Report} from '@src/types/onyx'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 824275ace170..ecc3603e8f8d 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -1,5 +1,6 @@ import type Account from './Account'; import type AccountData from './AccountData'; +import type AnchorAlignment from './AnchorAlignment'; import type {BankAccountList} from './BankAccount'; import type BankAccount from './BankAccount'; import type Beta from './Beta'; @@ -139,4 +140,5 @@ export type { PolicyReportField, RecentlyUsedReportFields, LastPaymentMethod, + AnchorAlignment, }; From ef7487ab74bc146b82e40dcbe69dd6875cb617dc Mon Sep 17 00:00:00 2001 From: Yauheni Date: Wed, 10 Jan 2024 14:24:13 +0100 Subject: [PATCH 08/21] Fix comments --- src/ONYXKEYS.ts | 4 +++- src/components/SettlementButton.tsx | 7 +++++-- src/types/onyx/LastPaymentMethod.ts | 3 --- src/types/onyx/index.ts | 2 -- 4 files changed, 8 insertions(+), 8 deletions(-) delete mode 100644 src/types/onyx/LastPaymentMethod.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 89ddbdc06883..d3c7756b0dee 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -530,5 +530,7 @@ type OnyxValues = { type OnyxKeyValue = OnyxEntry; +type LastPaymentMethod = Record; + export default ONYXKEYS; -export type {OnyxKey, OnyxCollectionKey, OnyxValues, OnyxKeyValue, OnyxFormKey, OnyxKeysMap}; +export type {OnyxKey, OnyxCollectionKey, OnyxValues, OnyxKeyValue, OnyxFormKey, OnyxKeysMap,LastPaymentMethod}; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 2fe45e6f7b90..1fae611018c1 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -10,10 +10,11 @@ import * as BankAccounts from '@userActions/BankAccounts'; import * as IOU from '@userActions/IOU'; import * as PaymentMethods from '@userActions/PaymentMethods'; import CONST from '@src/CONST'; +import type {LastPaymentMethod} from '@src/ONYXKEYS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; -import type {AnchorAlignment, LastPaymentMethod, Report} from '@src/types/onyx'; +import type {AnchorAlignment, Report} from '@src/types/onyx'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; @@ -26,6 +27,8 @@ type TriggerKYCFlow = (event: KYCFlowEvent, iouPaymentType: string) => void; type PaymentType = DeepValueOf; +type EnablePaymentsRoute = typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEND_ENABLE_PAYMENTS | typeof ROUTES.SETTINGS_ENABLE_PAYMENTS; + type SettlementButtonOnyxProps = { /** The last payment method used per policy */ nvpLastPaymentMethod?: OnyxEntry; @@ -36,7 +39,7 @@ type SettlementButtonProps = SettlementButtonOnyxProps & { onPress: (paymentType: PaymentType) => void; /** The route to redirect if user does not have a payment method setup */ - enablePaymentsRoute: typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEND_ENABLE_PAYMENTS | typeof ROUTES.SETTINGS_ENABLE_PAYMENTS; + enablePaymentsRoute: EnablePaymentsRoute; /** Call the onPress function on main button when Enter key is pressed */ pressOnEnter?: boolean; diff --git a/src/types/onyx/LastPaymentMethod.ts b/src/types/onyx/LastPaymentMethod.ts deleted file mode 100644 index 677a23fa9586..000000000000 --- a/src/types/onyx/LastPaymentMethod.ts +++ /dev/null @@ -1,3 +0,0 @@ -type LastPaymentMethod = Record; - -export default LastPaymentMethod; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index ecc3603e8f8d..4e199e88ce88 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -16,7 +16,6 @@ import type FrequentlyUsedEmoji from './FrequentlyUsedEmoji'; import type {FundList} from './Fund'; import type Fund from './Fund'; import type IOU from './IOU'; -import type LastPaymentMethod from './LastPaymentMethod'; import type Locale from './Locale'; import type {LoginList} from './Login'; import type Login from './Login'; @@ -139,6 +138,5 @@ export type { ReportUserIsTyping, PolicyReportField, RecentlyUsedReportFields, - LastPaymentMethod, AnchorAlignment, }; From c2d9c887fcc609d90324b556d1716640f6547018 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Wed, 10 Jan 2024 20:05:55 +0100 Subject: [PATCH 09/21] Fix comments x2 --- src/ONYXKEYS.ts | 6 ++---- src/components/SettlementButton.tsx | 3 +-- src/types/onyx/LastPaymentMethod.ts | 3 +++ src/types/onyx/index.ts | 2 ++ 4 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 src/types/onyx/LastPaymentMethod.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index d3c7756b0dee..63eecbea3984 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -391,7 +391,7 @@ type OnyxValues = { [ONYXKEYS.NVP_PRIVATE_PUSH_NOTIFICATION_ID]: string; [ONYXKEYS.NVP_TRY_FOCUS_MODE]: boolean; [ONYXKEYS.FOCUS_MODE_NOTIFICATION]: boolean; - [ONYXKEYS.NVP_LAST_PAYMENT_METHOD]: Record; + [ONYXKEYS.NVP_LAST_PAYMENT_METHOD]: OnyxTypes.LastPaymentMethod; [ONYXKEYS.NVP_RECENT_WAYPOINTS]: OnyxTypes.RecentWaypoint[]; [ONYXKEYS.PUSH_NOTIFICATIONS_ENABLED]: boolean; [ONYXKEYS.PLAID_DATA]: OnyxTypes.PlaidData; @@ -530,7 +530,5 @@ type OnyxValues = { type OnyxKeyValue = OnyxEntry; -type LastPaymentMethod = Record; - export default ONYXKEYS; -export type {OnyxKey, OnyxCollectionKey, OnyxValues, OnyxKeyValue, OnyxFormKey, OnyxKeysMap,LastPaymentMethod}; +export type {OnyxKey, OnyxCollectionKey, OnyxValues, OnyxKeyValue, OnyxFormKey, OnyxKeysMap}; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 1fae611018c1..4a4abea14c70 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -10,11 +10,10 @@ import * as BankAccounts from '@userActions/BankAccounts'; import * as IOU from '@userActions/IOU'; import * as PaymentMethods from '@userActions/PaymentMethods'; import CONST from '@src/CONST'; -import type {LastPaymentMethod} from '@src/ONYXKEYS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; -import type {AnchorAlignment, Report} from '@src/types/onyx'; +import type {AnchorAlignment, LastPaymentMethod, Report} from '@src/types/onyx'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; diff --git a/src/types/onyx/LastPaymentMethod.ts b/src/types/onyx/LastPaymentMethod.ts new file mode 100644 index 000000000000..677a23fa9586 --- /dev/null +++ b/src/types/onyx/LastPaymentMethod.ts @@ -0,0 +1,3 @@ +type LastPaymentMethod = Record; + +export default LastPaymentMethod; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 4e199e88ce88..ecc3603e8f8d 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -16,6 +16,7 @@ import type FrequentlyUsedEmoji from './FrequentlyUsedEmoji'; import type {FundList} from './Fund'; import type Fund from './Fund'; import type IOU from './IOU'; +import type LastPaymentMethod from './LastPaymentMethod'; import type Locale from './Locale'; import type {LoginList} from './Login'; import type Login from './Login'; @@ -138,5 +139,6 @@ export type { ReportUserIsTyping, PolicyReportField, RecentlyUsedReportFields, + LastPaymentMethod, AnchorAlignment, }; From baf50f2b497b32bd730410a3959ae0e7f0d1d645 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Tue, 16 Jan 2024 18:35:30 +0100 Subject: [PATCH 10/21] Refactor types --- src/components/ButtonWithDropdownMenu.tsx | 9 ++++++--- src/components/Popover/types.ts | 2 +- src/components/PopoverMenu.tsx | 2 +- src/components/ProcessMoneyRequestHoldMenu.tsx | 2 +- src/components/SettlementButton.tsx | 10 +++++----- src/types/onyx/index.ts | 2 -- src/types/{onyx => utils}/AnchorAlignment.ts | 0 7 files changed, 14 insertions(+), 13 deletions(-) rename src/types/{onyx => utils}/AnchorAlignment.ts (100%) diff --git a/src/components/ButtonWithDropdownMenu.tsx b/src/components/ButtonWithDropdownMenu.tsx index 466c68229a32..011089af8ab9 100644 --- a/src/components/ButtonWithDropdownMenu.tsx +++ b/src/components/ButtonWithDropdownMenu.tsx @@ -9,15 +9,18 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import type {AnchorPosition} from '@styles/index'; import CONST from '@src/CONST'; +import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; +import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type IconAsset from '@src/types/utils/IconAsset'; import Button from './Button'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; -import type {AnchorAlignment} from './Popover/types'; import PopoverMenu from './PopoverMenu'; +type PaymentType = DeepValueOf; + type DropdownOption = { - value: string; + value: PaymentType; text: string; icon: IconAsset; iconWidth?: number; @@ -30,7 +33,7 @@ type ButtonWithDropdownMenuProps = { menuHeaderText?: string; /** Callback to execute when the main button is pressed */ - onPress: (event: GestureResponderEvent | KeyboardEvent | undefined, value: string) => void; + onPress: (event: GestureResponderEvent | KeyboardEvent | undefined, value: PaymentType) => void; /** Call the onPress function on main button when Enter key is pressed */ pressOnEnter?: boolean; diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 298c95eeca76..4409e8a7e296 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -1,7 +1,7 @@ import type {PopoverAnchorPosition} from '@components/Modal/types'; import type BaseModalProps from '@components/Modal/types'; import type {WindowDimensionsProps} from '@components/withWindowDimensions/types'; -import type {AnchorAlignment} from '@src/types/onyx'; +import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; type PopoverDimensions = { width: number; diff --git a/src/components/PopoverMenu.tsx b/src/components/PopoverMenu.tsx index 10599330945f..6990a453a931 100644 --- a/src/components/PopoverMenu.tsx +++ b/src/components/PopoverMenu.tsx @@ -9,7 +9,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import CONST from '@src/CONST'; import type {AnchorPosition} from '@src/styles'; -import type {AnchorAlignment} from '@src/types/onyx'; +import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; import type IconAsset from '@src/types/utils/IconAsset'; import MenuItem from './MenuItem'; import PopoverWithMeasuredContent from './PopoverWithMeasuredContent'; diff --git a/src/components/ProcessMoneyRequestHoldMenu.tsx b/src/components/ProcessMoneyRequestHoldMenu.tsx index 1fd37b82afc8..a069bcfa1a07 100644 --- a/src/components/ProcessMoneyRequestHoldMenu.tsx +++ b/src/components/ProcessMoneyRequestHoldMenu.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {View} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import type {AnchorAlignment} from '@src/types/onyx'; +import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; import Button from './Button'; import HoldMenuSectionList from './HoldMenuSectionList'; import type {PopoverAnchorPosition} from './Modal/types'; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 4a4abea14c70..82da026d4014 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -1,4 +1,4 @@ -import type {MutableRefObject} from 'react'; +import type {RefObject} from 'react'; import React, {useEffect, useMemo} from 'react'; import type {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; @@ -13,14 +13,15 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; -import type {AnchorAlignment, LastPaymentMethod, Report} from '@src/types/onyx'; +import type {LastPaymentMethod, Report} from '@src/types/onyx'; +import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import * as Expensicons from './Icon/Expensicons'; import KYCWall from './KYCWall'; -type KYCFlowEvent = GestureResponderEvent | KeyboardEvent; +type KYCFlowEvent = GestureResponderEvent | KeyboardEvent | undefined; type TriggerKYCFlow = (event: KYCFlowEvent, iouPaymentType: string) => void; @@ -211,7 +212,7 @@ function SettlementButton({ anchorAlignment={kycWallAnchorAlignment} shouldShowPersonalBankAccountOption={shouldShowPersonalBankAccountOption} > - {(triggerKYCFlow: TriggerKYCFlow, buttonRef: MutableRefObject) => ( + {(triggerKYCFlow: TriggerKYCFlow, buttonRef: RefObject) => ( selectPaymentType(event, iouPaymentType, triggerKYCFlow)} pressOnEnter={pressOnEnter} options={paymentButtonOptions} - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/issues/25065) is migrated to TypeScript. style={style} buttonSize={buttonSize} anchorAlignment={paymentMethodDropdownAnchorAlignment} diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 8b2586db597a..3dd083d47865 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -1,6 +1,5 @@ import type Account from './Account'; import type AccountData from './AccountData'; -import type AnchorAlignment from './AnchorAlignment'; import type {BankAccountList} from './BankAccount'; import type BankAccount from './BankAccount'; import type Beta from './Beta'; @@ -142,5 +141,4 @@ export type { PolicyReportField, RecentlyUsedReportFields, LastPaymentMethod, - AnchorAlignment, }; diff --git a/src/types/onyx/AnchorAlignment.ts b/src/types/utils/AnchorAlignment.ts similarity index 100% rename from src/types/onyx/AnchorAlignment.ts rename to src/types/utils/AnchorAlignment.ts From d078c1051b3b1cf6d77cbea025f4bbffd757e4d6 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Fri, 19 Jan 2024 19:39:12 +0100 Subject: [PATCH 11/21] Update types PART-1 --- src/components/KYCWall/types.ts | 9 +++------ src/components/SettlementButton.tsx | 5 +++-- src/libs/actions/Policy.ts | 7 +++++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/KYCWall/types.ts b/src/components/KYCWall/types.ts index aee5b569cc46..2144dc1a878e 100644 --- a/src/components/KYCWall/types.ts +++ b/src/components/KYCWall/types.ts @@ -5,6 +5,8 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type {Route} from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; +import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; type Source = ValueOf; @@ -14,11 +16,6 @@ type DOMRectProperties = 'top' | 'bottom' | 'left' | 'right' | 'height' | 'x' | type DomRect = Pick; -type AnchorAlignment = { - horizontal: ValueOf; - vertical: ValueOf; -}; - type AnchorPosition = { anchorPositionVertical: number; anchorPositionHorizontal: number; @@ -49,7 +46,7 @@ type KYCWallProps = { chatReportID?: string; /** The IOU/Expense report we are paying */ - iouReport?: OnyxEntry; + iouReport?: OnyxEntry | EmptyObject; /** Where the popover should be positioned relative to the anchor points. */ anchorAlignment?: AnchorAlignment; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 82da026d4014..32dd4ffec7e7 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -12,6 +12,7 @@ import * as PaymentMethods from '@userActions/PaymentMethods'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type {Route} from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; import type {LastPaymentMethod, Report} from '@src/types/onyx'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; @@ -72,10 +73,10 @@ type SettlementButtonProps = SettlementButtonOnyxProps & { buttonSize?: ButtonSizeValue; /** Route for the Add Bank Account screen for a given navigation stack */ - addBankAccountRoute?: string; + addBankAccountRoute?: Route; /** Route for the Add Debit Card screen for a given navigation stack */ - addDebitCardRoute?: string; + addDebitCardRoute?: Route; /** Whether the button should be disabled */ isDisabled?: boolean; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 263d5fb68529..b6e729d3698e 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -22,6 +22,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {PersonalDetailsList, Policy, PolicyMember, PolicyTags, RecentlyUsedCategories, RecentlyUsedTags, ReimbursementAccount, Report, ReportAction, Transaction} from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; import type {CustomUnit} from '@src/types/onyx/Policy'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; type AnnounceRoomMembersOnyxData = { @@ -1589,12 +1590,14 @@ function buildOptimisticPolicyRecentlyUsedTags(policyID: string, tag: string): R * * @returns policyID of the workspace we have created */ -function createWorkspaceFromIOUPayment(iouReport: Report): string | undefined { +function createWorkspaceFromIOUPayment(iouReportParam: Report | EmptyObject): string | undefined { // This flow only works for IOU reports - if (!ReportUtils.isIOUReport(iouReport)) { + if (!ReportUtils.isIOUReport(iouReportParam)) { return; } + const iouReport = iouReportParam as Report; + // Generate new variables for the policy const policyID = generatePolicyID(); const workspaceName = generateDefaultWorkspaceName(sessionEmail); From 2d7f408065cf2135a9ef7aecccca55dd0d65c69f Mon Sep 17 00:00:00 2001 From: Yauheni Date: Sun, 21 Jan 2024 21:52:18 +0100 Subject: [PATCH 12/21] Update types PART-2 --- src/components/MoneyReportHeader.tsx | 2 -- src/libs/ReportUtils.ts | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index afdc62218f95..88e368a8bbbb 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -127,7 +127,6 @@ function MoneyReportHeader({session, personalDetails, policy, chatReport, nextSt {shouldShowSettlementButton && !isSmallScreenWidth && ( ): boolean { * If the report is a policy expense, the route should be for adding bank account for that policy * else since the report is a personal IOU, the route should be for personal bank account. */ -function getBankAccountRoute(report: OnyxEntry): string { +function getBankAccountRoute(report: OnyxEntry): Route { return isPolicyExpenseChat(report) ? ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('', report?.policyID) : ROUTES.SETTINGS_ADD_BANK_ACCOUNT; } From 44e688c476bae6216f883c85cd1362566edb1e0a Mon Sep 17 00:00:00 2001 From: Yauheni Date: Mon, 22 Jan 2024 10:12:48 +0100 Subject: [PATCH 13/21] Update types PART-3 --- src/components/KYCWall/BaseKYCWall.tsx | 2 +- src/components/KYCWall/types.ts | 4 ++-- src/components/SettlementButton.tsx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index 04c8397bc33b..17e00af3b2ce 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -203,7 +203,7 @@ function KYCWall({ Log.info('[KYC Wallet] User has valid payment method and passed KYC checks or did not need them'); - onSuccessfulKYC(currentSource, iouPaymentType); + onSuccessfulKYC(iouPaymentType, currentSource); }, [ bankAccountList, diff --git a/src/components/KYCWall/types.ts b/src/components/KYCWall/types.ts index 2144dc1a878e..7147f86814fa 100644 --- a/src/components/KYCWall/types.ts +++ b/src/components/KYCWall/types.ts @@ -10,7 +10,7 @@ import type {EmptyObject} from '@src/types/utils/EmptyObject'; type Source = ValueOf; -type TransferMethod = ValueOf; +type TransferMethod = ValueOf; type DOMRectProperties = 'top' | 'bottom' | 'left' | 'right' | 'height' | 'x' | 'y'; @@ -61,7 +61,7 @@ type KYCWallProps = { shouldShowPersonalBankAccountOption?: boolean; /** Callback for the end of the onContinue trigger on option selection */ - onSuccessfulKYC: (currentSource?: Source, iouPaymentType?: TransferMethod) => void; + onSuccessfulKYC: (iouPaymentType?: TransferMethod, currentSource?: Source) => void; /** Children to build the KYC */ children: (continueAction: (event: SyntheticEvent, method: TransferMethod) => void, anchorRef: ForwardedRef) => void; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 32dd4ffec7e7..82b9805620cc 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -26,7 +26,7 @@ type KYCFlowEvent = GestureResponderEvent | KeyboardEvent | undefined; type TriggerKYCFlow = (event: KYCFlowEvent, iouPaymentType: string) => void; -type PaymentType = DeepValueOf; +type PaymentType = DeepValueOf; type EnablePaymentsRoute = typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEND_ENABLE_PAYMENTS | typeof ROUTES.SETTINGS_ENABLE_PAYMENTS; @@ -37,7 +37,7 @@ type SettlementButtonOnyxProps = { type SettlementButtonProps = SettlementButtonOnyxProps & { /** Callback to execute when this button is pressed. Receives a single payment type argument. */ - onPress: (paymentType: PaymentType) => void; + onPress: (paymentType?: PaymentType) => void; /** The route to redirect if user does not have a payment method setup */ enablePaymentsRoute: EnablePaymentsRoute; From 3fadd8aaff92edff3dbd8ce6194d12e55997bd89 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Mon, 22 Jan 2024 10:50:11 +0100 Subject: [PATCH 14/21] Update types PART-4 --- src/components/KYCWall/BaseKYCWall.tsx | 6 +++--- src/components/KYCWall/types.ts | 10 ++++++---- src/components/SettlementButton.tsx | 10 +++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index 17e00af3b2ce..939b87e22376 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -1,7 +1,7 @@ import React, {useCallback, useEffect, useRef, useState} from 'react'; import type {SyntheticEvent} from 'react'; import {Dimensions} from 'react-native'; -import type {EmitterSubscription, NativeTouchEvent} from 'react-native'; +import type {EmitterSubscription, GestureResponderEvent, NativeTouchEvent} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import AddPaymentMethodMenu from '@components/AddPaymentMethodMenu'; @@ -146,7 +146,7 @@ function KYCWall({ * */ const continueAction = useCallback( - (event?: SyntheticEvent, iouPaymentType?: TransferMethod) => { + (event?: GestureResponderEvent | KeyboardEvent | SyntheticEvent, iouPaymentType?: TransferMethod) => { const currentSource = walletTerms?.source ?? source; /** @@ -161,7 +161,7 @@ function KYCWall({ } // Use event target as fallback if anchorRef is null for safety - const targetElement = anchorRef.current ?? (event?.nativeEvent.target as HTMLDivElement); + const targetElement = anchorRef.current ?? ((event as SyntheticEvent)?.nativeEvent.target as HTMLDivElement); transferBalanceButtonRef.current = targetElement; diff --git a/src/components/KYCWall/types.ts b/src/components/KYCWall/types.ts index 7147f86814fa..c0b738746985 100644 --- a/src/components/KYCWall/types.ts +++ b/src/components/KYCWall/types.ts @@ -1,16 +1,17 @@ -import type {ForwardedRef, SyntheticEvent} from 'react'; -import type {NativeTouchEvent} from 'react-native'; +import type {ForwardedRef} from 'react'; +import type {GestureResponderEvent} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type {Route} from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; +import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; type Source = ValueOf; -type TransferMethod = ValueOf; +type TransferMethod = DeepValueOf; type DOMRectProperties = 'top' | 'bottom' | 'left' | 'right' | 'height' | 'x' | 'y'; @@ -64,7 +65,8 @@ type KYCWallProps = { onSuccessfulKYC: (iouPaymentType?: TransferMethod, currentSource?: Source) => void; /** Children to build the KYC */ - children: (continueAction: (event: SyntheticEvent, method: TransferMethod) => void, anchorRef: ForwardedRef) => void; + children: (continueAction: (event?: GestureResponderEvent | KeyboardEvent, method?: TransferMethod) => void, anchorRef: ForwardedRef) => void; + // }; export type {AnchorPosition, KYCWallProps, PaymentMethod, TransferMethod, DomRect}; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 82b9805620cc..8124509ec4f3 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -1,4 +1,4 @@ -import type {RefObject} from 'react'; +import type {ForwardedRef, RefObject} from 'react'; import React, {useEffect, useMemo} from 'react'; import type {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; @@ -24,10 +24,10 @@ import KYCWall from './KYCWall'; type KYCFlowEvent = GestureResponderEvent | KeyboardEvent | undefined; -type TriggerKYCFlow = (event: KYCFlowEvent, iouPaymentType: string) => void; - type PaymentType = DeepValueOf; +type TriggerKYCFlow = (event: KYCFlowEvent, iouPaymentType: PaymentType) => void; + type EnablePaymentsRoute = typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEND_ENABLE_PAYMENTS | typeof ROUTES.SETTINGS_ENABLE_PAYMENTS; type SettlementButtonOnyxProps = { @@ -213,9 +213,9 @@ function SettlementButton({ anchorAlignment={kycWallAnchorAlignment} shouldShowPersonalBankAccountOption={shouldShowPersonalBankAccountOption} > - {(triggerKYCFlow: TriggerKYCFlow, buttonRef: RefObject) => ( + {(triggerKYCFlow: TriggerKYCFlow, buttonRef: ForwardedRef) => ( } isDisabled={isDisabled} isLoading={isLoading} onPress={(event: KYCFlowEvent, iouPaymentType: PaymentType) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} From 907ece0712d4ae652cd6452fea6a10b9193a5778 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Mon, 22 Jan 2024 10:51:35 +0100 Subject: [PATCH 15/21] Update types PART-5 --- src/components/KYCWall/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/KYCWall/types.ts b/src/components/KYCWall/types.ts index c0b738746985..ebf9cd3b0a43 100644 --- a/src/components/KYCWall/types.ts +++ b/src/components/KYCWall/types.ts @@ -65,7 +65,7 @@ type KYCWallProps = { onSuccessfulKYC: (iouPaymentType?: TransferMethod, currentSource?: Source) => void; /** Children to build the KYC */ - children: (continueAction: (event?: GestureResponderEvent | KeyboardEvent, method?: TransferMethod) => void, anchorRef: ForwardedRef) => void; + children: (continueAction: (event?: GestureResponderEvent | KeyboardEvent, method?: TransferMethod) => void, anchorRef: ForwardedRef) => void; // }; From 9cb7f8a41b67877a69fd1a1310962538cdfdeb1f Mon Sep 17 00:00:00 2001 From: Yauheni Date: Mon, 22 Jan 2024 10:52:13 +0100 Subject: [PATCH 16/21] Update types PART-6 --- src/components/KYCWall/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/KYCWall/types.ts b/src/components/KYCWall/types.ts index ebf9cd3b0a43..d0e5c2e32e2f 100644 --- a/src/components/KYCWall/types.ts +++ b/src/components/KYCWall/types.ts @@ -66,7 +66,6 @@ type KYCWallProps = { /** Children to build the KYC */ children: (continueAction: (event?: GestureResponderEvent | KeyboardEvent, method?: TransferMethod) => void, anchorRef: ForwardedRef) => void; - // }; export type {AnchorPosition, KYCWallProps, PaymentMethod, TransferMethod, DomRect}; From 8e934fabeb192e867f80585c5758b4f4995ad9b1 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Wed, 24 Jan 2024 17:44:05 +0100 Subject: [PATCH 17/21] Update createWorkspaceFromIOUPayment --- src/libs/actions/Policy.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 2c9dbcee371c..ec9cb6d7cae8 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -1612,14 +1612,12 @@ function buildOptimisticPolicyRecentlyUsedTags(policyID: string, tag: string): R * * @returns policyID of the workspace we have created */ -function createWorkspaceFromIOUPayment(iouReportParam: Report | EmptyObject): string | undefined { +function createWorkspaceFromIOUPayment(iouReport: Report | EmptyObject): string | undefined { // This flow only works for IOU reports - if (!ReportUtils.isIOUReport(iouReportParam)) { + if (isEmptyObject(iouReport) || !ReportUtils.isIOUReport(iouReport)) { return; } - const iouReport = iouReportParam as Report; - // Generate new variables for the policy const policyID = generatePolicyID(); const workspaceName = generateDefaultWorkspaceName(sessionEmail); From 47b8c2ab046a78787548e531a92f5261df61b220 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Thu, 25 Jan 2024 16:38:41 +0100 Subject: [PATCH 18/21] Fix ts issue --- src/components/ThreeDotsMenu/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ThreeDotsMenu/index.tsx b/src/components/ThreeDotsMenu/index.tsx index 920b8f9f4130..e087456943ce 100644 --- a/src/components/ThreeDotsMenu/index.tsx +++ b/src/components/ThreeDotsMenu/index.tsx @@ -3,7 +3,6 @@ import type {StyleProp, ViewStyle} from 'react-native'; import {View} from 'react-native'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; -import type {AnchorAlignment} from '@components/Popover/types'; import type {PopoverMenuItem} from '@components/PopoverMenu'; import PopoverMenu from '@components/PopoverMenu'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; @@ -15,6 +14,7 @@ import * as Browser from '@libs/Browser'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import type {AnchorPosition} from '@src/styles'; +import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; import type IconAsset from '@src/types/utils/IconAsset'; type ThreeDotsMenuProps = { From 48748d1cbc18d1024f92b1f36866a1d583b40563 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Thu, 25 Jan 2024 18:29:08 +0100 Subject: [PATCH 19/21] Fix comments --- src/components/SettlementButton.tsx | 6 +++--- src/libs/ReportUtils.ts | 9 ++++++++- src/libs/actions/Policy.ts | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 8124509ec4f3..7a2a94aff301 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -1,4 +1,4 @@ -import type {ForwardedRef, RefObject} from 'react'; +import type {RefObject} from 'react'; import React, {useEffect, useMemo} from 'react'; import type {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; @@ -213,12 +213,12 @@ function SettlementButton({ anchorAlignment={kycWallAnchorAlignment} shouldShowPersonalBankAccountOption={shouldShowPersonalBankAccountOption} > - {(triggerKYCFlow: TriggerKYCFlow, buttonRef: ForwardedRef) => ( + {(triggerKYCFlow, buttonRef) => ( } isDisabled={isDisabled} isLoading={isLoading} - onPress={(event: KYCFlowEvent, iouPaymentType: PaymentType) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} + onPress={(event, iouPaymentType) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} pressOnEnter={pressOnEnter} options={paymentButtonOptions} style={style} diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 91a558e7ce4e..264cf665f599 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -604,13 +604,19 @@ function isExpenseReport(report: OnyxEntry | EmptyObject): boolean { } /** - * Checks if a report is an IOU report. + * Checks if a report is an IOU report using report or reportID */ function isIOUReport(reportOrID: OnyxEntry | string | EmptyObject): boolean { const report = typeof reportOrID === 'string' ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; return report?.type === CONST.REPORT.TYPE.IOU; } +/** + * Checks if a report is an IOU report using report + */ +function isIOUReportUsingReport(report: OnyxEntry | EmptyObject): report is Report { + return report?.type === CONST.REPORT.TYPE.IOU; +} /** * Checks if a report is a task report. */ @@ -4812,6 +4818,7 @@ export { doesReportBelongToWorkspace, getChildReportNotificationPreference, isReportFieldOfTypeTitle, + isIOUReportUsingReport, }; export type { diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 86282312bed4..f00b0774d881 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -1615,7 +1615,7 @@ function buildOptimisticPolicyRecentlyUsedTags(policyID: string, tag: string): R */ function createWorkspaceFromIOUPayment(iouReport: Report | EmptyObject): string | undefined { // This flow only works for IOU reports - if (isEmptyObject(iouReport) || !ReportUtils.isIOUReport(iouReport)) { + if (!ReportUtils.isIOUReportUsingReport(iouReport)) { return; } From 000d9ab4fb06d169dc7af4f362d7af58d1840218 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Wed, 31 Jan 2024 18:25:07 +0100 Subject: [PATCH 20/21] Update types --- src/components/KYCWall/BaseKYCWall.tsx | 10 ++++++---- src/components/KYCWall/types.ts | 14 ++++++-------- src/components/ReportActionItem/ReportPreview.tsx | 3 +-- src/components/SettlementButton.tsx | 15 ++++++--------- src/libs/actions/PaymentMethods.ts | 4 ++-- src/types/onyx/OriginalMessage.ts | 2 +- 6 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index 89cceadc0fb0..ab2d217deb0e 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -17,7 +17,9 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {BankAccountList, FundList, ReimbursementAccount, UserWallet, WalletTerms} from '@src/types/onyx'; -import type {AnchorPosition, DomRect, KYCWallProps, PaymentMethod, TransferMethod} from './types'; +import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import viewRef from '@src/types/utils/viewRef'; +import type {AnchorPosition, DomRect, KYCWallProps, PaymentMethod} from './types'; // This sets the Horizontal anchor position offset for POPOVER MENU. const POPOVER_MENU_ANCHOR_POSITION_HORIZONTAL_OFFSET = 20; @@ -67,7 +69,7 @@ function KYCWall({ walletTerms, shouldShowPersonalBankAccountOption = false, }: BaseKYCWallProps) { - const anchorRef = useRef(null); + const anchorRef = useRef(null); const transferBalanceButtonRef = useRef(null); const [shouldShowAddPaymentMenu, setShouldShowAddPaymentMenu] = useState(false); @@ -145,7 +147,7 @@ function KYCWall({ * */ const continueAction = useCallback( - (event?: GestureResponderEvent | KeyboardEvent, iouPaymentType?: TransferMethod) => { + (event?: GestureResponderEvent | KeyboardEvent, iouPaymentType?: PaymentMethodType) => { const currentSource = walletTerms?.source ?? source; /** @@ -259,7 +261,7 @@ function KYCWall({ }} shouldShowPersonalBankAccountOption={shouldShowPersonalBankAccountOption} /> - {children(continueAction, anchorRef)} + {children(continueAction, viewRef(anchorRef))} ); } diff --git a/src/components/KYCWall/types.ts b/src/components/KYCWall/types.ts index 1e6aae3299b1..1ee8010574c3 100644 --- a/src/components/KYCWall/types.ts +++ b/src/components/KYCWall/types.ts @@ -1,18 +1,16 @@ -import type {ForwardedRef} from 'react'; -import type {GestureResponderEvent} from 'react-native'; +import type {RefObject} from 'react'; +import type {GestureResponderEvent, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type {Route} from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; +import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; -import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; type Source = ValueOf; -type TransferMethod = DeepValueOf; - type DOMRectProperties = 'top' | 'bottom' | 'left' | 'right' | 'height' | 'x' | 'y'; type DomRect = Pick; @@ -62,10 +60,10 @@ type KYCWallProps = { shouldShowPersonalBankAccountOption?: boolean; /** Callback for the end of the onContinue trigger on option selection */ - onSuccessfulKYC: (iouPaymentType?: TransferMethod, currentSource?: Source) => void; + onSuccessfulKYC: (iouPaymentType?: PaymentMethodType, currentSource?: Source) => void; /** Children to build the KYC */ - children: (continueAction: (event: GestureResponderEvent | KeyboardEvent | undefined, method: TransferMethod) => void, anchorRef: ForwardedRef) => void; + children: (continueAction: (event: GestureResponderEvent | KeyboardEvent | undefined, method: PaymentMethodType) => void, anchorRef: RefObject) => void; }; -export type {AnchorPosition, KYCWallProps, PaymentMethod, TransferMethod, DomRect}; +export type {AnchorPosition, KYCWallProps, PaymentMethod, DomRect}; diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index b2fece085f57..46dbd87e55f1 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -285,12 +285,11 @@ function ReportPreview({ )} {shouldShowSettlementButton && ( chatReport && iouReport && IOU.payMoneyRequest(paymentType, chatReport, iouReport)} + onPress={(paymentType?: PaymentMethodType) => chatReport && iouReport && paymentType && IOU.payMoneyRequest(paymentType, chatReport, iouReport)} enablePaymentsRoute={ROUTES.ENABLE_PAYMENTS} addBankAccountRoute={bankAccountRoute} shouldHidePaymentOptions={!shouldShowPayButton} diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 7a2a94aff301..02f51c67c64d 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -1,6 +1,5 @@ -import type {RefObject} from 'react'; import React, {useEffect, useMemo} from 'react'; -import type {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'; +import type {GestureResponderEvent, StyleProp, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; @@ -15,8 +14,8 @@ import ROUTES from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; import type {LastPaymentMethod, Report} from '@src/types/onyx'; +import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; -import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import * as Expensicons from './Icon/Expensicons'; @@ -24,9 +23,7 @@ import KYCWall from './KYCWall'; type KYCFlowEvent = GestureResponderEvent | KeyboardEvent | undefined; -type PaymentType = DeepValueOf; - -type TriggerKYCFlow = (event: KYCFlowEvent, iouPaymentType: PaymentType) => void; +type TriggerKYCFlow = (event: KYCFlowEvent, iouPaymentType: PaymentMethodType) => void; type EnablePaymentsRoute = typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEND_ENABLE_PAYMENTS | typeof ROUTES.SETTINGS_ENABLE_PAYMENTS; @@ -37,7 +34,7 @@ type SettlementButtonOnyxProps = { type SettlementButtonProps = SettlementButtonOnyxProps & { /** Callback to execute when this button is pressed. Receives a single payment type argument. */ - onPress: (paymentType?: PaymentType) => void; + onPress: (paymentType?: PaymentMethodType) => void; /** The route to redirect if user does not have a payment method setup */ enablePaymentsRoute: EnablePaymentsRoute; @@ -185,7 +182,7 @@ function SettlementButton({ return buttonOptions; }, [currency, formattedAmount, iouReport, nvpLastPaymentMethod, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton]); - const selectPaymentType = (event: KYCFlowEvent, iouPaymentType: PaymentType, triggerKYCFlow: TriggerKYCFlow) => { + const selectPaymentType = (event: KYCFlowEvent, iouPaymentType: PaymentMethodType, triggerKYCFlow: TriggerKYCFlow) => { if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || iouPaymentType === CONST.IOU.PAYMENT_TYPE.VBBA) { triggerKYCFlow(event, iouPaymentType); BankAccounts.setPersonalBankAccountContinueKYCOnSuccess(ROUTES.ENABLE_PAYMENTS); @@ -215,7 +212,7 @@ function SettlementButton({ > {(triggerKYCFlow, buttonRef) => ( } + buttonRef={buttonRef} isDisabled={isDisabled} isLoading={isLoading} onPress={(event, iouPaymentType) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)} diff --git a/src/libs/actions/PaymentMethods.ts b/src/libs/actions/PaymentMethods.ts index cbc5778187a1..2199c5768612 100644 --- a/src/libs/actions/PaymentMethods.ts +++ b/src/libs/actions/PaymentMethods.ts @@ -3,7 +3,6 @@ import type {MutableRefObject} from 'react'; import type {GestureResponderEvent} from 'react-native'; import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; -import type {TransferMethod} from '@components/KYCWall/types'; import * as API from '@libs/API'; import type {AddPaymentCardParams, DeletePaymentCardParams, MakeDefaultPaymentMethodParams, PaymentCardParams, TransferWalletBalanceParams} from '@libs/API/parameters'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; @@ -14,11 +13,12 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; import type {BankAccountList, FundList} from '@src/types/onyx'; +import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type PaymentMethod from '@src/types/onyx/PaymentMethod'; import type {FilterMethodPaymentType} from '@src/types/onyx/WalletTransfer'; type KYCWallRef = { - continueAction?: (event?: GestureResponderEvent | KeyboardEvent, iouPaymentType?: TransferMethod) => void; + continueAction?: (event?: GestureResponderEvent | KeyboardEvent, iouPaymentType?: PaymentMethodType) => void; }; /** diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index 070b91e2d920..baa5c8d6c904 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -2,7 +2,7 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -type PaymentMethodType = DeepValueOf; +type PaymentMethodType = DeepValueOf; type ActionName = DeepValueOf; type OriginalMessageActionName = From e645f46476a4c6e6a55a8d957fabf69597cd598e Mon Sep 17 00:00:00 2001 From: Yauheni Date: Thu, 1 Feb 2024 11:25:56 +0100 Subject: [PATCH 21/21] Fix lint issue --- src/components/SettlementButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index 95218e0783a6..c2a22fa04bfe 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -163,7 +163,7 @@ function SettlementButton({ // To achieve the one tap pay experience we need to choose the correct payment type as default. // If the user has previously chosen a specific payment option or paid for some request or expense, // let's use the last payment method or use default. - const paymentMethod = nvpLastPaymentMethod?.[policyID] || ''; + const paymentMethod = nvpLastPaymentMethod?.[policyID] ?? ''; if (canUseWallet) { buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.EXPENSIFY]); }