diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 1776dd75726b..15a8c454487a 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -479,6 +479,14 @@ type MoneyRequestNavigatorParamList = { pageIndex: number; backTo: Routes; }; + [SCREENS.MONEY_REQUEST.STEP_CURRENCY]: { + action: ValueOf; + iouType: ValueOf; + transactionID: string; + reportID: string; + pageIndex?: string; + backTo?: Routes; + }; }; type NewTaskNavigatorParamList = { diff --git a/src/pages/iou/request/step/IOURequestStepCurrency.js b/src/pages/iou/request/step/IOURequestStepCurrency.tsx similarity index 63% rename from src/pages/iou/request/step/IOURequestStepCurrency.js rename to src/pages/iou/request/step/IOURequestStepCurrency.tsx index 24602d527389..e55f510aa589 100644 --- a/src/pages/iou/request/step/IOURequestStepCurrency.js +++ b/src/pages/iou/request/step/IOURequestStepCurrency.tsx @@ -1,15 +1,12 @@ import Str from 'expensify-common/lib/str'; -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React, {useMemo, useRef, useState} from 'react'; +import React, {useMemo, useState} from 'react'; import {Keyboard} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; +import type {OnyxEntry} from 'react-native-onyx'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; -import transactionPropTypes from '@components/transactionPropTypes'; +import type {ListItem} from '@components/SelectionList/types'; import useLocalize from '@hooks/useLocalize'; -import compose from '@libs/compose'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; @@ -17,39 +14,26 @@ import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES, {getUrlWithBackToParam} from '@src/ROUTES'; -import IOURequestStepRoutePropTypes from './IOURequestStepRoutePropTypes'; +import type {Route} from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; +import type {CurrencyList, Transaction} from '@src/types/onyx'; import StepScreenWrapper from './StepScreenWrapper'; import withFullTransactionOrNotFound from './withFullTransactionOrNotFound'; +import type {WithFullTransactionOrNotFoundProps} from './withFullTransactionOrNotFound'; -/** - * IOU Currency selection for selecting currency - */ -const propTypes = { - /** Navigation route context info provided by react navigation */ - route: IOURequestStepRoutePropTypes.isRequired, +type IOURequestStepCurrencyOnyxProps = { + /** Constant, list of available currencies */ + currencyList: OnyxEntry; - /** The currency list constant object from Onyx */ - currencyList: PropTypes.objectOf( - PropTypes.shape({ - /** Symbol for the currency */ - symbol: PropTypes.string, - - /** Name of the currency */ - name: PropTypes.string, - - /** ISO4217 Code for the currency */ - ISO4217: PropTypes.string, - }), - ), - - /* Onyx Props */ /** The draft transaction object being modified in Onyx */ - draftTransaction: transactionPropTypes, + draftTransaction: OnyxEntry; }; -const defaultProps = { - currencyList: {}, - draftTransaction: {}, +type IOURequestStepCurrencyProps = IOURequestStepCurrencyOnyxProps & WithFullTransactionOrNotFoundProps; + +type CurrencyListItem = ListItem & { + currencyName: string; + currencyCode: string; }; function IOURequestStepCurrency({ @@ -58,11 +42,10 @@ function IOURequestStepCurrency({ params: {backTo, iouType, pageIndex, reportID, transactionID, action}, }, draftTransaction, -}) { +}: IOURequestStepCurrencyProps) { const {translate} = useLocalize(); const [searchValue, setSearchValue] = useState(''); - const optionsSelectorRef = useRef(); - const {currency} = ReportUtils.getTransactionDetails(draftTransaction); + const {currency = ''} = ReportUtils.getTransactionDetails(draftTransaction) ?? {}; const navigateBack = () => { // If the currency selection was done from the confirmation step (eg. + > request money > manual > confirm > amount > currency) @@ -71,30 +54,26 @@ function IOURequestStepCurrency({ // to the confirmation page if (pageIndex === 'confirm') { const routeToAmountPageWithConfirmationAsBackTo = getUrlWithBackToParam( - backTo, + backTo as string, `/${ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)}`, ); - Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo); + Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo as Route); return; } Navigation.goBack(backTo); }; - /** - * @param {Object} option - * @param {String} options.currencyCode - */ - const confirmCurrencySelection = (option) => { + const confirmCurrencySelection = (option: CurrencyListItem) => { Keyboard.dismiss(); IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, option.currencyCode, false, action === CONST.IOU.ACTION.EDIT); navigateBack(); }; const {sections, headerMessage, initiallyFocusedOptionKey} = useMemo(() => { - const currencyOptions = _.map(currencyList, (currencyInfo, currencyCode) => { + const currencyOptions: CurrencyListItem[] = Object.entries(currencyList ?? {}).map(([currencyCode, currencyInfo]) => { const isSelectedCurrency = currencyCode === currency.toUpperCase(); return { - currencyName: currencyInfo.name, + currencyName: currencyInfo?.name ?? '', text: `${currencyCode} - ${CurrencyUtils.getLocalizedCurrencySymbol(currencyCode)}`, currencyCode, keyForList: currencyCode, @@ -103,14 +82,11 @@ function IOURequestStepCurrency({ }); const searchRegex = new RegExp(Str.escapeForRegExp(searchValue.trim()), 'i'); - const filteredCurrencies = _.filter(currencyOptions, (currencyOption) => searchRegex.test(currencyOption.text) || searchRegex.test(currencyOption.currencyName)); + const filteredCurrencies = currencyOptions.filter((currencyOption) => searchRegex.test(currencyOption.text ?? '') || searchRegex.test(currencyOption.currencyName)); const isEmpty = searchValue.trim() && !filteredCurrencies.length; return { - initiallyFocusedOptionKey: _.get( - _.find(filteredCurrencies, (filteredCurrency) => filteredCurrency.currencyCode === currency.toUpperCase()), - 'keyForList', - ), + initiallyFocusedOptionKey: filteredCurrencies.find((filteredCurrency) => filteredCurrency.currencyCode === currency.toUpperCase())?.keyForList, sections: isEmpty ? [] : [ @@ -126,7 +102,6 @@ function IOURequestStepCurrency({ optionsSelectorRef.current && optionsSelectorRef.current.focus()} shouldShowWrapper testID={IOURequestStepCurrency.displayName} includeSafeAreaPaddingBottom={false} @@ -154,18 +129,18 @@ function IOURequestStepCurrency({ } IOURequestStepCurrency.displayName = 'IOURequestStepCurrency'; -IOURequestStepCurrency.propTypes = propTypes; -IOURequestStepCurrency.defaultProps = defaultProps; -export default compose( - withFullTransactionOrNotFound, - withOnyx({ - currencyList: {key: ONYXKEYS.CURRENCY_LIST}, - draftTransaction: { - key: ({route}) => { - const transactionID = lodashGet(route, 'params.transactionID', 0); - return `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`; - }, +const IOURequestStepCurrencyWithOnyx = withOnyx({ + currencyList: {key: ONYXKEYS.CURRENCY_LIST}, + draftTransaction: { + key: ({route}) => { + const transactionID = route?.params?.transactionID ?? 0; + return `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`; }, - }), -)(IOURequestStepCurrency); + }, +})(IOURequestStepCurrency); + +/* eslint-disable rulesdir/no-negated-variables */ +const IOURequestStepCurrencyWithFullTransactionOrNotFound = withFullTransactionOrNotFound(IOURequestStepCurrencyWithOnyx); + +export default IOURequestStepCurrencyWithFullTransactionOrNotFound; diff --git a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx index e1a01c9dde69..fee7e2f301db 100644 --- a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx +++ b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx @@ -30,7 +30,8 @@ type MoneyRequestRouteName = | typeof SCREENS.MONEY_REQUEST.STEP_CONFIRMATION | typeof SCREENS.MONEY_REQUEST.STEP_CATEGORY | typeof SCREENS.MONEY_REQUEST.STEP_TAX_RATE - | typeof SCREENS.MONEY_REQUEST.STEP_SCAN; + | typeof SCREENS.MONEY_REQUEST.STEP_SCAN + | typeof SCREENS.MONEY_REQUEST.STEP_CURRENCY; type Route = RouteProp;