From ac334bae4cb4cf5738982f079f7d3fec32640542 Mon Sep 17 00:00:00 2001
From: ruben-rebelo <ruben.rato96@gmail.com>
Date: Tue, 20 Feb 2024 10:11:01 +0000
Subject: [PATCH 1/2] [TS migration] Migrate withFullTransactionOrNotFound HOC

---
 .../step/withFullTransactionOrNotFound.js     | 78 -------------------
 .../step/withFullTransactionOrNotFound.tsx    | 56 +++++++++++++
 2 files changed, 56 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 <FullPageNotFoundView shouldShow={isFocused} />;
-        }
-
-        return (
-            <WrappedComponent
-                // eslint-disable-next-line react/jsx-props-no-spreading
-                {...props}
-                ref={forwardedRef}
-            />
-        );
-    }
-
-    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) => (
-        <WithFullTransactionOrNotFound
-            // eslint-disable-next-line react/jsx-props-no-spreading
-            {...props}
-            forwardedRef={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..ad98d28e0304
--- /dev/null
+++ b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx
@@ -0,0 +1,56 @@
+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 {OnyxCollection, 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: OnyxCollection<Transaction>;
+};
+
+type WithFullTransactionOrNotFoundProps = WithFullTransactionOrNotFoundOnyxProps & StackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_DATE>;
+
+export default function <TProps extends WithFullTransactionOrNotFoundProps, TRef>(WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>) {
+    // eslint-disable-next-line rulesdir/no-negated-variables
+    function WithFullTransactionOrNotFound(props: TProps, ref: ForwardedRef<TRef>) {
+        const transactionID = props.route.params.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 <FullPageNotFoundView shouldShow={isFocused} />;
+        }
+
+        return (
+            <WrappedComponent
+                // eslint-disable-next-line react/jsx-props-no-spreading
+                {...props}
+                ref={ref}
+            />
+        );
+    }
+
+    WithFullTransactionOrNotFound.displayName = `withFullTransactionOrNotFound(${getComponentDisplayName(WrappedComponent)})`;
+
+    return withOnyx<TProps & RefAttributes<TRef>, WithFullTransactionOrNotFoundOnyxProps>({
+        transaction: {
+            key: ({route}) => {
+                const transactionID = route.params.transactionID ?? 0;
+                const userAction = route.params.action ?? CONST.IOU.ACTION.CREATE;
+                return `${userAction === CONST.IOU.ACTION.CREATE ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`;
+            },
+        },
+    })(forwardRef(WithFullTransactionOrNotFound));
+}

From ef01395a56c8dc8df6db965f20a2b76c83fc766a Mon Sep 17 00:00:00 2001
From: ruben-rebelo <ruben.rato96@gmail.com>
Date: Tue, 20 Feb 2024 13:13:04 +0000
Subject: [PATCH 2/2] [TS migration] Type changes

---
 .../request/step/withFullTransactionOrNotFound.tsx | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx
index ad98d28e0304..eb9abd579960 100644
--- a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx
+++ b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx
@@ -2,7 +2,7 @@ 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 {OnyxCollection, OnyxEntry} from 'react-native-onyx';
+import type {OnyxEntry} from 'react-native-onyx';
 import {withOnyx} from 'react-native-onyx';
 import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
 import getComponentDisplayName from '@libs/getComponentDisplayName';
@@ -14,7 +14,7 @@ import type {Transaction} from '@src/types/onyx';
 
 type WithFullTransactionOrNotFoundOnyxProps = {
     /** Indicated whether the report data is loading */
-    transaction: OnyxCollection<Transaction>;
+    transaction: OnyxEntry<Transaction>;
 };
 
 type WithFullTransactionOrNotFoundProps = WithFullTransactionOrNotFoundOnyxProps & StackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_DATE>;
@@ -22,7 +22,7 @@ type WithFullTransactionOrNotFoundProps = WithFullTransactionOrNotFoundOnyxProps
 export default function <TProps extends WithFullTransactionOrNotFoundProps, TRef>(WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>) {
     // eslint-disable-next-line rulesdir/no-negated-variables
     function WithFullTransactionOrNotFound(props: TProps, ref: ForwardedRef<TRef>) {
-        const transactionID = props.route.params.transactionID;
+        const transactionID = props.transaction?.transactionID;
 
         const isFocused = useIsFocused();
 
@@ -49,8 +49,14 @@ export default function <TProps extends WithFullTransactionOrNotFoundProps, TRef
             key: ({route}) => {
                 const transactionID = route.params.transactionID ?? 0;
                 const userAction = route.params.action ?? CONST.IOU.ACTION.CREATE;
-                return `${userAction === CONST.IOU.ACTION.CREATE ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`;
+
+                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};
