Skip to content

Commit

Permalink
Merge pull request #35253 from callstack-internal/pac-guerreiro/refac…
Browse files Browse the repository at this point in the history
…tor/migrate-iou-page-to-typescript

[TS migration] Migrate 'IOU' page to TypeScript
  • Loading branch information
srikarparsi authored Mar 29, 2024
2 parents df2694d + 49b4982 commit 2d7addc
Show file tree
Hide file tree
Showing 17 changed files with 276 additions and 288 deletions.
2 changes: 1 addition & 1 deletion src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ type OnyxCollectionValuesMapping = {
[ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT]: OnyxTypes.Transaction;
[ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags;
[ONYXKEYS.COLLECTION.OLD_POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags;
[ONYXKEYS.COLLECTION.SELECTED_TAB]: string;
[ONYXKEYS.COLLECTION.SELECTED_TAB]: OnyxTypes.SelectedTabRequest;
[ONYXKEYS.COLLECTION.PRIVATE_NOTES_DRAFT]: string;
[ONYXKEYS.COLLECTION.NEXT_STEP]: OnyxTypes.ReportNextStep;
[ONYXKEYS.COLLECTION.POLICY_JOIN_MEMBER]: OnyxTypes.PolicyJoinMember;
Expand Down
18 changes: 11 additions & 7 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import ROUTES from '@src/ROUTES';
import type * as OnyxTypes from '@src/types/onyx';
import type {Participant} from '@src/types/onyx/IOU';
import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage';
import type {ReceiptSource} from '@src/types/onyx/Transaction';
import ButtonWithDropdownMenu from './ButtonWithDropdownMenu';
import type {DropdownOption} from './ButtonWithDropdownMenu/types';
import ConfirmedRoute from './ConfirmedRoute';
Expand Down Expand Up @@ -67,7 +68,7 @@ type MoneyRequestConfirmationListOnyxProps = {
};
type MoneyRequestConfirmationListProps = MoneyRequestConfirmationListOnyxProps & {
/** Callback to inform parent modal of success */
onConfirm?: (selectedParticipants: Participant[]) => void;
onConfirm?: (selectedParticipants: Array<Participant | ReportUtils.OptionData>) => void;

/** Callback to parent modal to send money */
onSendMoney?: (paymentMethod: IouType | PaymentMethodType | undefined) => void;
Expand Down Expand Up @@ -109,10 +110,10 @@ type MoneyRequestConfirmationListProps = MoneyRequestConfirmationListOnyxProps &
onToggleBillable?: (isOn: boolean) => void;

/** Selected participants from MoneyRequestModal with login / accountID */
selectedParticipants: Participant[];
selectedParticipants: Array<Participant | ReportUtils.OptionData>;

/** Payee of the money request with login */
payeePersonalDetails?: OnyxTypes.PersonalDetails;
payeePersonalDetails?: OnyxEntry<OnyxTypes.PersonalDetails>;

/** Can the participants be modified or not */
canModifyParticipants?: boolean;
Expand All @@ -130,7 +131,7 @@ type MoneyRequestConfirmationListProps = MoneyRequestConfirmationListOnyxProps &
reportID?: string;

/** File path of the receipt */
receiptPath?: string;
receiptPath?: ReceiptSource;

/** File name of the receipt */
receiptFilename?: string;
Expand Down Expand Up @@ -322,7 +323,7 @@ function MoneyRequestConfirmationList({
* Returns the participants with amount
*/
const getParticipantsWithAmount = useCallback(
(participantsList: Participant[]): Participant[] => {
(participantsList: Array<Participant | ReportUtils.OptionData>): Array<Participant | ReportUtils.OptionData> => {
const calculatedIouAmount = IOUUtils.calculateAmount(participantsList.length, iouAmount, iouCurrencyCode ?? '');
return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(
participantsList,
Expand Down Expand Up @@ -358,7 +359,10 @@ function MoneyRequestConfirmationList({
];
}, [isSplitBill, isTypeRequest, iouType, iouAmount, receiptPath, formattedAmount, isDistanceRequestWithPendingRoute, translate]);

const selectedParticipants: Participant[] = useMemo(() => selectedParticipantsProp.filter((participant) => participant.selected), [selectedParticipantsProp]);
const selectedParticipants: Array<Participant | ReportUtils.OptionData> = useMemo(
() => selectedParticipantsProp.filter((participant) => participant.selected),
[selectedParticipantsProp],
);
const payeePersonalDetails = useMemo(() => payeePersonalDetailsProp ?? currentUserPersonalDetails, [payeePersonalDetailsProp, currentUserPersonalDetails]);
const canModifyParticipants = !isReadOnly && canModifyParticipantsProp && hasMultipleParticipants;
const shouldDisablePaidBySection = canModifyParticipants;
Expand Down Expand Up @@ -424,7 +428,7 @@ function MoneyRequestConfirmationList({
canModifyParticipants,
]);

const selectedOptions: Array<Participant | OptionsListUtils.PayeePersonalDetails> = useMemo(() => {
const selectedOptions: Array<Participant | ReportUtils.OptionData | OptionsListUtils.PayeePersonalDetails> = useMemo(() => {
if (!hasMultipleParticipants) {
return [];
}
Expand Down
6 changes: 4 additions & 2 deletions src/libs/MoneyRequestUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type {OnyxEntry} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import CONST from '@src/CONST';
import type {SelectedTabRequest} from '@src/types/onyx';

/**
* Strip comma from the amount
Expand Down Expand Up @@ -78,14 +80,14 @@ function replaceAllDigits(text: string, convertFn: (char: string) => string): st
/**
* Check if distance request or not
*/
function isDistanceRequest(iouType: ValueOf<typeof CONST.IOU.TYPE>, selectedTab: ValueOf<typeof CONST.TAB_REQUEST>): boolean {
function isDistanceRequest(iouType: ValueOf<typeof CONST.IOU.TYPE>, selectedTab: OnyxEntry<SelectedTabRequest>): boolean {
return iouType === CONST.IOU.TYPE.REQUEST && selectedTab === CONST.TAB_REQUEST.DISTANCE;
}

/**
* Check if scan request or not
*/
function isScanRequest(selectedTab: ValueOf<typeof CONST.TAB_REQUEST>): boolean {
function isScanRequest(selectedTab: SelectedTabRequest): boolean {
return selectedTab === CONST.TAB_REQUEST.SCAN;
}

Expand Down
9 changes: 5 additions & 4 deletions src/libs/Navigation/OnyxTabNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import type {OnyxEntry} from 'react-native-onyx';
import type {TabSelectorProps} from '@components/TabSelector/TabSelector';
import Tab from '@userActions/Tab';
import ONYXKEYS from '@src/ONYXKEYS';
import type {SelectedTabRequest} from '@src/types/onyx';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import {defaultScreenOptions} from './OnyxTabNavigatorConfig';

type OnyxTabNavigatorOnyxProps = {
selectedTab: OnyxEntry<string>;
selectedTab: OnyxEntry<SelectedTabRequest>;
};

type OnyxTabNavigatorProps = OnyxTabNavigatorOnyxProps &
Expand All @@ -20,7 +21,7 @@ type OnyxTabNavigatorProps = OnyxTabNavigatorOnyxProps &
id: string;

/** Name of the selected tab */
selectedTab?: string;
selectedTab?: SelectedTabRequest;

/** A function triggered when a tab has been selected */
onTabSelected?: (newIouType: string) => void;
Expand All @@ -35,7 +36,7 @@ export const TopTab = createMaterialTopTabNavigator();

// This takes all the same props as MaterialTopTabsNavigator: https://reactnavigation.org/docs/material-top-tab-navigator/#props,
// except ID is now required, and it gets a `selectedTab` from Onyx
function OnyxTabNavigator({id, selectedTab = '', children, onTabSelected = () => {}, screenListeners, ...rest}: OnyxTabNavigatorProps) {
function OnyxTabNavigator({id, selectedTab, children, onTabSelected = () => {}, screenListeners, ...rest}: OnyxTabNavigatorProps) {
return (
<TopTab.Navigator
/* eslint-disable-next-line react/jsx-props-no-spreading */
Expand All @@ -50,7 +51,7 @@ function OnyxTabNavigator({id, selectedTab = '', children, onTabSelected = () =>
const state = event.data.state;
const index = state.index;
const routeNames = state.routeNames;
Tab.setSelectedTab(id, routeNames[index]);
Tab.setSelectedTab(id, routeNames[index] as SelectedTabRequest);
onTabSelected(routeNames[index]);
},
...(screenListeners ?? {}),
Expand Down
7 changes: 6 additions & 1 deletion src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,11 @@ type RoomInviteNavigatorParamList = {
};

type MoneyRequestNavigatorParamList = {
[SCREENS.MONEY_REQUEST.AMOUNT]: undefined;
[SCREENS.MONEY_REQUEST.AMOUNT]: {
iouType: ValueOf<typeof CONST.IOU.TYPE>;
reportID: string;
currency: string;
};
[SCREENS.MONEY_REQUEST.PARTICIPANTS]: {
iouType: string;
reportID: string;
Expand Down Expand Up @@ -463,6 +467,7 @@ type EnablePaymentsNavigatorParamList = {

type SplitDetailsNavigatorParamList = {
[SCREENS.SPLIT_DETAILS.ROOT]: {
reportID: string;
reportActionID: string;
};
[SCREENS.SPLIT_DETAILS.EDIT_REQUEST]: {
Expand Down
2 changes: 1 addition & 1 deletion src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1814,7 +1814,7 @@ function getIOUConfirmationOptionsFromPayeePersonalDetail(personalDetail: Person
/**
* Build the IOUConfirmationOptions for showing participants
*/
function getIOUConfirmationOptionsFromParticipants(participants: Participant[], amountText: string): Participant[] {
function getIOUConfirmationOptionsFromParticipants(participants: Array<Participant | ReportUtils.OptionData>, amountText: string): Array<Participant | ReportUtils.OptionData> {
return participants.map((participant) => ({
...participant,
descriptiveText: amountText,
Expand Down
4 changes: 2 additions & 2 deletions src/libs/ReceiptUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {OnyxEntry} from 'react-native-onyx';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type {Transaction} from '@src/types/onyx';
import type {ReceiptError} from '@src/types/onyx/Transaction';
import type {ReceiptError, ReceiptSource} from '@src/types/onyx/Transaction';
import * as FileUtils from './fileDownload/FileUtils';
import * as TransactionUtils from './TransactionUtils';

Expand All @@ -25,7 +25,7 @@ type ThumbnailAndImageURI = {
* @param receiptPath
* @param receiptFileName
*/
function getThumbnailAndImageURIs(transaction: OnyxEntry<Transaction>, receiptPath: string | null = null, receiptFileName: string | null = null): ThumbnailAndImageURI {
function getThumbnailAndImageURIs(transaction: OnyxEntry<Transaction>, receiptPath: ReceiptSource | null = null, receiptFileName: string | null = null): ThumbnailAndImageURI {
if (TransactionUtils.isFetchingWaypointsFromServer(transaction)) {
return {isThumbnail: true, isLocalFile: true};
}
Expand Down
2 changes: 1 addition & 1 deletion src/libs/TransactionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ function hasEReceipt(transaction: Transaction | undefined | null): boolean {
return !!transaction?.hasEReceipt;
}

function hasReceipt(transaction: Transaction | undefined | null): boolean {
function hasReceipt(transaction: OnyxEntry<Transaction> | undefined): boolean {
return !!transaction?.receipt?.state || hasEReceipt(transaction);
}

Expand Down
29 changes: 15 additions & 14 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3064,9 +3064,9 @@ function startSplitBill(
* @param sessionAccountID - accountID of the current user
* @param sessionEmail - email of the current user
*/
function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportAction, updatedTransaction: OnyxTypes.Transaction, sessionAccountID: number, sessionEmail: string) {
function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportAction, updatedTransaction: OnyxEntry<OnyxTypes.Transaction>, sessionAccountID: number, sessionEmail: string) {
const currentUserEmailForIOUSplit = PhoneNumber.addSMSDomainIfPhoneNumber(sessionEmail);
const {transactionID} = updatedTransaction;
const transactionID = updatedTransaction?.transactionID ?? '';
const unmodifiedTransaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];

// Save optimistic updated transaction and action
Expand Down Expand Up @@ -3127,8 +3127,9 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA
},
];

const splitParticipants: Split[] = updatedTransaction.comment.splits ?? [];
const {modifiedAmount: amount, modifiedCurrency: currency} = updatedTransaction;
const splitParticipants: Split[] = updatedTransaction?.comment.splits ?? [];
const amount = updatedTransaction?.modifiedAmount;
const currency = updatedTransaction?.modifiedCurrency;

// Exclude the current user when calculating the split amount, `calculateAmount` takes it into account
const splitAmount = IOUUtils.calculateAmount(splitParticipants.length - 1, amount ?? 0, currency ?? '', false);
Expand Down Expand Up @@ -3185,17 +3186,17 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA
isPolicyExpenseChat ? -splitAmount : splitAmount,
currency ?? '',
oneOnOneIOUReport?.reportID ?? '',
updatedTransaction.comment.comment,
updatedTransaction.modifiedCreated,
updatedTransaction?.comment.comment,
updatedTransaction?.modifiedCreated,
CONST.IOU.TYPE.SPLIT,
transactionID,
updatedTransaction.modifiedMerchant,
{...updatedTransaction.receipt, state: CONST.IOU.RECEIPT_STATE.OPEN},
updatedTransaction.filename,
updatedTransaction?.modifiedMerchant,
{...updatedTransaction?.receipt, state: CONST.IOU.RECEIPT_STATE.OPEN},
updatedTransaction?.filename,
undefined,
updatedTransaction.category,
updatedTransaction.tag,
updatedTransaction.billable,
updatedTransaction?.category,
updatedTransaction?.tag,
updatedTransaction?.billable,
);

const [oneOnOneCreatedActionForChat, oneOnOneCreatedActionForIOU, oneOnOneIOUAction, optimisticTransactionThread, optimisticCreatedActionForTransactionThread] =
Expand All @@ -3204,7 +3205,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA
CONST.IOU.REPORT_ACTION_TYPE.CREATE,
splitAmount,
currency ?? '',
updatedTransaction.comment.comment ?? '',
updatedTransaction?.comment.comment ?? '',
currentUserEmailForIOUSplit,
[participant],
oneOnOneTransaction.transactionID,
Expand Down Expand Up @@ -5050,7 +5051,7 @@ function setShownHoldUseExplanation() {
}

/** Navigates to the next IOU page based on where the IOU request was started */
function navigateToNextPage(iou: OnyxEntry<OnyxTypes.IOU>, iouType: string, report?: OnyxTypes.Report, path = '') {
function navigateToNextPage(iou: OnyxEntry<OnyxTypes.IOU>, iouType: string, report?: OnyxEntry<OnyxTypes.Report>, path = '') {
const moneyRequestID = `${iouType}${report?.reportID ?? ''}`;
const shouldReset = iou?.id !== moneyRequestID && !!report?.reportID;

Expand Down
3 changes: 2 additions & 1 deletion src/libs/actions/Tab.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Onyx from 'react-native-onyx';
import ONYXKEYS from '@src/ONYXKEYS';
import type {SelectedTabRequest} from '@src/types/onyx';

/**
* Sets the selected tab for a given tab ID
*/
function setSelectedTab(id: string, index: string) {
function setSelectedTab(id: string, index: SelectedTabRequest) {
Onyx.merge(`${ONYXKEYS.COLLECTION.SELECTED_TAB}${id}`, index);
}

Expand Down
6 changes: 4 additions & 2 deletions src/pages/home/report/withReportAndReportActionOrNotFound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import withWindowDimensions from '@components/withWindowDimensions';
import type {WindowDimensionsProps} from '@components/withWindowDimensions/types';
import compose from '@libs/compose';
import getComponentDisplayName from '@libs/getComponentDisplayName';
import type {FlagCommentNavigatorParamList} from '@libs/Navigation/types';
import type {FlagCommentNavigatorParamList, SplitDetailsNavigatorParamList} from '@libs/Navigation/types';
import * as ReportUtils from '@libs/ReportUtils';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
import * as Report from '@userActions/Report';
Expand Down Expand Up @@ -44,7 +44,9 @@ type OnyxProps = {
isLoadingReportData: OnyxEntry<boolean>;
};

type WithReportAndReportActionOrNotFoundProps = OnyxProps & WindowDimensionsProps & StackScreenProps<FlagCommentNavigatorParamList, typeof SCREENS.FLAG_COMMENT_ROOT>;
type WithReportAndReportActionOrNotFoundProps = OnyxProps &
WindowDimensionsProps &
StackScreenProps<FlagCommentNavigatorParamList & SplitDetailsNavigatorParamList, typeof SCREENS.FLAG_COMMENT_ROOT | typeof SCREENS.SPLIT_DETAILS.ROOT>;

export default function <TProps extends WithReportAndReportActionOrNotFoundProps, TRef>(
WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>,
Expand Down
Loading

0 comments on commit 2d7addc

Please sign in to comment.