From 1ac1004cb5887f33d73e2d65266e334e91c4db9e Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Fri, 15 Mar 2024 12:58:11 +0000 Subject: [PATCH 1/4] Revert "Revert "[TS migration] Migrate withFullTransactionOrNotFound HOC"" This reverts commit e838d5d4a4fba2ebc17e4d285d848977d3cb6588. --- .../step/withFullTransactionOrNotFound.js | 78 ------------------- .../step/withFullTransactionOrNotFound.tsx | 62 +++++++++++++++ 2 files changed, 62 insertions(+), 78 deletions(-) delete mode 100644 src/pages/iou/request/step/withFullTransactionOrNotFound.js create mode 100644 src/pages/iou/request/step/withFullTransactionOrNotFound.tsx diff --git a/src/pages/iou/request/step/withFullTransactionOrNotFound.js b/src/pages/iou/request/step/withFullTransactionOrNotFound.js deleted file mode 100644 index 7cdbb3484999..000000000000 --- a/src/pages/iou/request/step/withFullTransactionOrNotFound.js +++ /dev/null @@ -1,78 +0,0 @@ -import {useIsFocused} from '@react-navigation/native'; -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React from 'react'; -import {withOnyx} from 'react-native-onyx'; -import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; -import transactionPropTypes from '@components/transactionPropTypes'; -import getComponentDisplayName from '@libs/getComponentDisplayName'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import IOURequestStepRoutePropTypes from './IOURequestStepRoutePropTypes'; - -const propTypes = { - /** The HOC takes an optional ref as a prop and passes it as a ref to the wrapped component. - * That way, if a ref is passed to a component wrapped in the HOC, the ref is a reference to the wrapped component, not the HOC. */ - forwardedRef: PropTypes.func, - - /** The report corresponding to the reportID in the route params */ - transaction: transactionPropTypes, - - route: IOURequestStepRoutePropTypes.isRequired, -}; - -const defaultProps = { - forwardedRef: () => {}, - transaction: {}, -}; - -export default function (WrappedComponent) { - // eslint-disable-next-line rulesdir/no-negated-variables - function WithFullTransactionOrNotFound({forwardedRef, ...props}) { - const { - transaction: {transactionID}, - } = props; - - const isFocused = useIsFocused(); - - // If the transaction does not have a transactionID, then the transaction no longer exists in Onyx as a full transaction and the not-found page should be shown. - // In addition, the not-found page should be shown only if the component screen's route is active (i.e. is focused). - // This is to prevent it from showing when the modal is being dismissed while navigating to a different route (e.g. on requesting money). - if (!transactionID) { - return ; - } - - return ( - - ); - } - - WithFullTransactionOrNotFound.propTypes = propTypes; - WithFullTransactionOrNotFound.defaultProps = defaultProps; - WithFullTransactionOrNotFound.displayName = `withFullTransactionOrNotFound(${getComponentDisplayName(WrappedComponent)})`; - - // eslint-disable-next-line rulesdir/no-negated-variables - const WithFullTransactionOrNotFoundWithRef = React.forwardRef((props, ref) => ( - - )); - - WithFullTransactionOrNotFoundWithRef.displayName = 'WithFullTransactionOrNotFoundWithRef'; - - return withOnyx({ - transaction: { - key: ({route}) => { - const transactionID = lodashGet(route, 'params.transactionID', 0); - const userAction = lodashGet(route, 'params.action', CONST.IOU.ACTION.CREATE); - return `${userAction === CONST.IOU.ACTION.CREATE ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`; - }, - }, - })(WithFullTransactionOrNotFoundWithRef); -} diff --git a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx new file mode 100644 index 000000000000..eb9abd579960 --- /dev/null +++ b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx @@ -0,0 +1,62 @@ +import {useIsFocused} from '@react-navigation/native'; +import type {StackScreenProps} from '@react-navigation/stack'; +import type {ComponentType, ForwardedRef, RefAttributes} from 'react'; +import React, {forwardRef} from 'react'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; +import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; +import getComponentDisplayName from '@libs/getComponentDisplayName'; +import type {MoneyRequestNavigatorParamList} from '@libs/Navigation/types'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type SCREENS from '@src/SCREENS'; +import type {Transaction} from '@src/types/onyx'; + +type WithFullTransactionOrNotFoundOnyxProps = { + /** Indicated whether the report data is loading */ + transaction: OnyxEntry; +}; + +type WithFullTransactionOrNotFoundProps = WithFullTransactionOrNotFoundOnyxProps & StackScreenProps; + +export default function (WrappedComponent: ComponentType>) { + // eslint-disable-next-line rulesdir/no-negated-variables + function WithFullTransactionOrNotFound(props: TProps, ref: ForwardedRef) { + const transactionID = props.transaction?.transactionID; + + const isFocused = useIsFocused(); + + // If the transaction does not have a transactionID, then the transaction no longer exists in Onyx as a full transaction and the not-found page should be shown. + // In addition, the not-found page should be shown only if the component screen's route is active (i.e. is focused). + // This is to prevent it from showing when the modal is being dismissed while navigating to a different route (e.g. on requesting money). + if (!transactionID) { + return ; + } + + return ( + + ); + } + + WithFullTransactionOrNotFound.displayName = `withFullTransactionOrNotFound(${getComponentDisplayName(WrappedComponent)})`; + + return withOnyx, WithFullTransactionOrNotFoundOnyxProps>({ + transaction: { + key: ({route}) => { + const transactionID = route.params.transactionID ?? 0; + const userAction = route.params.action ?? CONST.IOU.ACTION.CREATE; + + if (userAction === CONST.IOU.ACTION.CREATE) { + return `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}` as `${typeof ONYXKEYS.COLLECTION.TRANSACTION}${string}`; + } + return `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`; + }, + }, + })(forwardRef(WithFullTransactionOrNotFound)); +} + +export type {WithFullTransactionOrNotFoundProps}; From f25341152e77e12deacbb7de1bd1b74c64b12c05 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Tue, 26 Mar 2024 10:52:19 +0000 Subject: [PATCH 2/4] [TS migration][withFullTransactionOrNotFound] Fixed regression --- src/pages/iou/MoneyRequestWaypointPage.tsx | 1 - .../request/step/IOURequestStepWaypoint.tsx | 52 +++++++++---------- .../step/withFullTransactionOrNotFound.tsx | 6 ++- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/pages/iou/MoneyRequestWaypointPage.tsx b/src/pages/iou/MoneyRequestWaypointPage.tsx index dd65b76c8d38..35778f37a9ef 100644 --- a/src/pages/iou/MoneyRequestWaypointPage.tsx +++ b/src/pages/iou/MoneyRequestWaypointPage.tsx @@ -15,7 +15,6 @@ type MoneyRequestWaypointPageProps = StackScreenProps({ + userLocation: { + key: ONYXKEYS.USER_LOCATION, + }, + recentWaypoints: { + key: ONYXKEYS.NVP_RECENT_WAYPOINTS, -export default withOnyx({ - userLocation: { - key: ONYXKEYS.USER_LOCATION, - }, - recentWaypoints: { - key: ONYXKEYS.NVP_RECENT_WAYPOINTS, - - // Only grab the most recent 5 waypoints because that's all that is shown in the UI. This also puts them into the format of data - // that the google autocomplete component expects for it's "predefined places" feature. - selector: (waypoints) => - (waypoints ? waypoints.slice(0, 5) : []).map((waypoint) => ({ - name: waypoint.name, - description: waypoint.address ?? '', - geometry: { - location: { - lat: waypoint.lat ?? 0, - lng: waypoint.lng ?? 0, - }, - }, - })), - }, - // @ts-expect-error TODO: Remove this once withFullTransactionOrNotFound (https://github.com/Expensify/App/issues/36123) is migrated to TypeScript. -})(IOURequestStepWaypointWithFullTransactionOrNotFound); + // Only grab the most recent 5 waypoints because that's all that is shown in the UI. This also puts them into the format of data + // that the google autocomplete component expects for it's "predefined places" feature. + selector: (waypoints) => + (waypoints ? waypoints.slice(0, 5) : []).map((waypoint) => ({ + name: waypoint.name, + description: waypoint.address ?? '', + geometry: { + location: { + lat: waypoint.lat ?? 0, + lng: waypoint.lng ?? 0, + }, + }, + })), + }, + })(IOURequestStepWaypoint), + ), +); diff --git a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx index eb9abd579960..f03ee412fa74 100644 --- a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx +++ b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx @@ -1,5 +1,5 @@ +import type {RouteProp} from '@react-navigation/native'; import {useIsFocused} from '@react-navigation/native'; -import type {StackScreenProps} from '@react-navigation/stack'; import type {ComponentType, ForwardedRef, RefAttributes} from 'react'; import React, {forwardRef} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; @@ -17,7 +17,9 @@ type WithFullTransactionOrNotFoundOnyxProps = { transaction: OnyxEntry; }; -type WithFullTransactionOrNotFoundProps = WithFullTransactionOrNotFoundOnyxProps & StackScreenProps; +type Route = RouteProp; + +type WithFullTransactionOrNotFoundProps = WithFullTransactionOrNotFoundOnyxProps & {route: Route}; export default function (WrappedComponent: ComponentType>) { // eslint-disable-next-line rulesdir/no-negated-variables From 5b616af77778cf45f2798cc99d805b249d2f3b47 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Tue, 26 Mar 2024 18:48:03 +0000 Subject: [PATCH 3/4] [TS migration][withFullTransactionOrNotFoundHOC] Comment fix --- src/pages/iou/request/step/withFullTransactionOrNotFound.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx index f03ee412fa74..d4e605c6a7c5 100644 --- a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx +++ b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx @@ -13,7 +13,7 @@ import type SCREENS from '@src/SCREENS'; import type {Transaction} from '@src/types/onyx'; type WithFullTransactionOrNotFoundOnyxProps = { - /** Indicated whether the report data is loading */ + /** Indicates whether the report data is loading */ transaction: OnyxEntry; }; From e062b8053eb8908e766042ffd1ede74c6e08f816 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Wed, 27 Mar 2024 15:16:13 +0000 Subject: [PATCH 4/4] [TS migration][withFullTransactionOrNotFound] Fixed order of HOC --- src/pages/iou/request/step/IOURequestStepWaypoint.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx index 15799ff44948..7525ca6d2e96 100644 --- a/src/pages/iou/request/step/IOURequestStepWaypoint.tsx +++ b/src/pages/iou/request/step/IOURequestStepWaypoint.tsx @@ -232,8 +232,8 @@ function IOURequestStepWaypoint({ IOURequestStepWaypoint.displayName = 'IOURequestStepWaypoint'; -export default withFullTransactionOrNotFound( - withWritableReportOrNotFound( +export default withWritableReportOrNotFound( + withFullTransactionOrNotFound( withOnyx({ userLocation: { key: ONYXKEYS.USER_LOCATION,