From 841e4bff4cdc3192dcfd77fbf7319dd75b18ca13 Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 31 Jan 2024 16:09:06 +0700 Subject: [PATCH 01/61] remove MoneyRequestConfirmPage --- src/ROUTES.ts | 4 - src/SCREENS.ts | 1 - src/components/DistanceRequest/index.js | 2 +- .../AppNavigator/ModalStackNavigators.tsx | 1 - src/libs/Navigation/linkingConfig.ts | 1 - src/libs/Navigation/types.ts | 3 +- src/libs/actions/IOU.js | 4 +- src/pages/iou/MoneyRequestCategoryPage.js | 4 +- src/pages/iou/MoneyRequestDatePage.js | 2 +- src/pages/iou/MoneyRequestDescriptionPage.js | 2 +- src/pages/iou/MoneyRequestMerchantPage.js | 2 +- src/pages/iou/MoneyRequestTagPage.js | 2 +- src/pages/iou/NewDistanceRequestPage.js | 2 +- .../step/IOURequestStepConfirmation.js | 14 +- .../iou/steps/MoneyRequestConfirmPage.js | 473 ------------------ .../MoneyRequestParticipantsPage.js | 2 +- src/pages/iou/steps/NewRequestAmountPage.js | 4 +- 17 files changed, 17 insertions(+), 506 deletions(-) delete mode 100644 src/pages/iou/steps/MoneyRequestConfirmPage.js diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 9c4375b84ab6..deabdc0ac853 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -267,10 +267,6 @@ const ROUTES = { route: ':iouType/new/participants/:reportID?', getRoute: (iouType: string, reportID = '') => `${iouType}/new/participants/${reportID}` as const, }, - MONEY_REQUEST_CONFIRMATION: { - route: ':iouType/new/confirmation/:reportID?', - getRoute: (iouType: string, reportID = '') => `${iouType}/new/confirmation/${reportID}` as const, - }, MONEY_REQUEST_DATE: { route: ':iouType/new/date/:reportID?', getRoute: (iouType: string, reportID = '') => `${iouType}/new/date/${reportID}` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 2bf40caede57..5a8922ee01c3 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -141,7 +141,6 @@ const SCREENS = { ROOT: 'Money_Request', AMOUNT: 'Money_Request_Amount', PARTICIPANTS: 'Money_Request_Participants', - CONFIRMATION: 'Money_Request_Confirmation', CURRENCY: 'Money_Request_Currency', DATE: 'Money_Request_Date', DESCRIPTION: 'Money_Request_Description', diff --git a/src/components/DistanceRequest/index.js b/src/components/DistanceRequest/index.js index b63ce337a1d9..34295dda74e7 100644 --- a/src/components/DistanceRequest/index.js +++ b/src/components/DistanceRequest/index.js @@ -163,7 +163,7 @@ function DistanceRequest({transactionID, report, transaction, route, isEditingRe }, [waypoints, previousWaypoints]); const navigateBack = () => { - Navigation.goBack(isEditingNewRequest ? ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID) : ROUTES.HOME); + Navigation.goBack(isEditingNewRequest ? ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, transactionID, reportID) : ROUTES.HOME); }; /** diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx index c9325206e5b2..3a843e400409 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx @@ -93,7 +93,6 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator require('../../../pages/iou/MoneyRequestSelectorPage').default as React.ComponentType, [SCREENS.MONEY_REQUEST.AMOUNT]: () => require('../../../pages/iou/steps/NewRequestAmountPage').default as React.ComponentType, [SCREENS.MONEY_REQUEST.PARTICIPANTS]: () => require('../../../pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage').default as React.ComponentType, - [SCREENS.MONEY_REQUEST.CONFIRMATION]: () => require('../../../pages/iou/steps/MoneyRequestConfirmPage').default as React.ComponentType, [SCREENS.MONEY_REQUEST.CURRENCY]: () => require('../../../pages/iou/IOUCurrencySelection').default as React.ComponentType, [SCREENS.MONEY_REQUEST.DATE]: () => require('../../../pages/iou/MoneyRequestDatePage').default as React.ComponentType, [SCREENS.MONEY_REQUEST.DESCRIPTION]: () => require('../../../pages/iou/MoneyRequestDescriptionPage').default as React.ComponentType, diff --git a/src/libs/Navigation/linkingConfig.ts b/src/libs/Navigation/linkingConfig.ts index 5df2bcf0e57b..d4e04d5402e2 100644 --- a/src/libs/Navigation/linkingConfig.ts +++ b/src/libs/Navigation/linkingConfig.ts @@ -428,7 +428,6 @@ const linkingConfig: LinkingOptions = { [SCREENS.MONEY_REQUEST.STEP_TAX_AMOUNT]: ROUTES.MONEY_REQUEST_STEP_TAX_AMOUNT.route, [SCREENS.MONEY_REQUEST.STEP_TAX_RATE]: ROUTES.MONEY_REQUEST_STEP_TAX_RATE.route, [SCREENS.MONEY_REQUEST.PARTICIPANTS]: ROUTES.MONEY_REQUEST_PARTICIPANTS.route, - [SCREENS.MONEY_REQUEST.CONFIRMATION]: ROUTES.MONEY_REQUEST_CONFIRMATION.route, [SCREENS.MONEY_REQUEST.DATE]: ROUTES.MONEY_REQUEST_DATE.route, [SCREENS.MONEY_REQUEST.CURRENCY]: ROUTES.MONEY_REQUEST_CURRENCY.route, [SCREENS.MONEY_REQUEST.DESCRIPTION]: ROUTES.MONEY_REQUEST_DESCRIPTION.route, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 2371c764f42a..29f7cd4aac30 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -185,8 +185,9 @@ type MoneyRequestNavigatorParamList = { iouType: string; reportID: string; }; - [SCREENS.MONEY_REQUEST.CONFIRMATION]: { + [SCREENS.MONEY_REQUEST.STEP_CONFIRMATION]: { iouType: string; + transactionID: string; reportID: string; }; [SCREENS.MONEY_REQUEST.CURRENCY]: { diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a9e1b09ed984..34fb20091493 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -3684,7 +3684,7 @@ function navigateToNextPage(iou, iouType, report, path = '') { // If we're adding a receipt, that means the user came from the confirmation page and we need to navigate back to it. if (path.slice(1) === ROUTES.MONEY_REQUEST_RECEIPT.getRoute(iouType, report.reportID)) { - Navigation.navigate(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, report.reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', report.reportID)); return; } @@ -3705,7 +3705,7 @@ function navigateToNextPage(iou, iouType, report, path = '') { resetMoneyRequestCategory(); resetMoneyRequestTag(); } - Navigation.navigate(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, report.reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', report.reportID)); return; } Navigation.navigate(ROUTES.MONEY_REQUEST_PARTICIPANTS.getRoute(iouType)); diff --git a/src/pages/iou/MoneyRequestCategoryPage.js b/src/pages/iou/MoneyRequestCategoryPage.js index ceb2152d2b49..b3ca0a5d7ae0 100644 --- a/src/pages/iou/MoneyRequestCategoryPage.js +++ b/src/pages/iou/MoneyRequestCategoryPage.js @@ -50,7 +50,7 @@ function MoneyRequestCategoryPage({route, report, iou}) { const iouType = lodashGet(route, 'params.iouType', ''); const navigateBack = () => { - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); }; const updateCategory = (category) => { @@ -60,7 +60,7 @@ function MoneyRequestCategoryPage({route, report, iou}) { IOU.setMoneyRequestCategory(category.searchText); } - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); }; return ( diff --git a/src/pages/iou/MoneyRequestDatePage.js b/src/pages/iou/MoneyRequestDatePage.js index f6159abd73f6..c99c07a80624 100644 --- a/src/pages/iou/MoneyRequestDatePage.js +++ b/src/pages/iou/MoneyRequestDatePage.js @@ -69,7 +69,7 @@ function MoneyRequestDatePage({iou, route, selectedTab}) { }, [iou.id, iou.participants, iou.amount, iou.receiptPath, iouType, reportID, isDistanceRequest]); function navigateBack() { - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); } /** diff --git a/src/pages/iou/MoneyRequestDescriptionPage.js b/src/pages/iou/MoneyRequestDescriptionPage.js index fe3100b8c3bd..a2209818ee1a 100644 --- a/src/pages/iou/MoneyRequestDescriptionPage.js +++ b/src/pages/iou/MoneyRequestDescriptionPage.js @@ -92,7 +92,7 @@ function MoneyRequestDescriptionPage({iou, route, selectedTab}) { }, [iou.id, iou.participants, iou.amount, iou.receiptPath, iouType, reportID, isDistanceRequest]); function navigateBack() { - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); } /** diff --git a/src/pages/iou/MoneyRequestMerchantPage.js b/src/pages/iou/MoneyRequestMerchantPage.js index ce96a09446b9..894bd317464c 100644 --- a/src/pages/iou/MoneyRequestMerchantPage.js +++ b/src/pages/iou/MoneyRequestMerchantPage.js @@ -68,7 +68,7 @@ function MoneyRequestMerchantPage({iou, route}) { }, [iou.id, iou.participants, iou.amount, iou.receiptPath, iouType, reportID]); function navigateBack() { - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST__STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); } const validate = useCallback((value) => { diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js index 60e40d665580..7fd08f20d652 100644 --- a/src/pages/iou/MoneyRequestTagPage.js +++ b/src/pages/iou/MoneyRequestTagPage.js @@ -60,7 +60,7 @@ function MoneyRequestTagPage({route, report, policyTags, iou}) { const policyTagListName = PolicyUtils.getTagListName(policyTags) || translate('common.tag'); const navigateBack = () => { - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, report.reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', report.reportID)); }; const updateTag = (selectedTag) => { diff --git a/src/pages/iou/NewDistanceRequestPage.js b/src/pages/iou/NewDistanceRequestPage.js index 750ac5d0141e..87f92b8c1907 100644 --- a/src/pages/iou/NewDistanceRequestPage.js +++ b/src/pages/iou/NewDistanceRequestPage.js @@ -57,7 +57,7 @@ function NewDistanceRequestPage({iou, report, route}) { const onSubmit = useCallback(() => { if (isEditingNewRequest) { - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, report.reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, lodashGet(iou, 'transactionID', '1'), report.reportID)); return; } IOU.navigateToNextPage(iou, iouType, report); diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.js b/src/pages/iou/request/step/IOURequestStepConfirmation.js index 6028a735d132..cb9edfb5868b 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.js +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.js @@ -23,7 +23,7 @@ import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; -import personalDetailsPropType from '@pages/personalDetailsPropType'; +import {usePersonalDetails} from '@components/OnyxProvider'; import reportPropTypes from '@pages/reportPropTypes'; import {policyPropTypes} from '@pages/workspace/withPolicy'; import * as IOU from '@userActions/IOU'; @@ -43,9 +43,6 @@ const propTypes = { /** The personal details of the current user */ ...withCurrentUserPersonalDetailsPropTypes, - /** Personal details of all users */ - personalDetails: personalDetailsPropType, - /** The policy of the report */ ...policyPropTypes, @@ -62,7 +59,6 @@ const propTypes = { transaction: transactionPropTypes, }; const defaultProps = { - personalDetails: {}, policy: {}, policyCategories: {}, policyTags: {}, @@ -72,7 +68,6 @@ const defaultProps = { }; function IOURequestStepConfirmation({ currentUserPersonalDetails, - personalDetails, policy, policyTags, policyCategories, @@ -86,6 +81,7 @@ function IOURequestStepConfirmation({ const {translate} = useLocalize(); const {windowWidth} = useWindowDimensions(); const {isOffline} = useNetwork(); + const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const [receiptFile, setReceiptFile] = useState(); const receiptFilename = lodashGet(transaction, 'filename'); const receiptPath = lodashGet(transaction, 'receipt.source'); @@ -385,12 +381,6 @@ export default compose( withCurrentUserPersonalDetails, withWritableReportOrNotFound, withFullTransactionOrNotFound, - withOnyx({ - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, - }), - // eslint-disable-next-line rulesdir/no-multiple-onyx-in-file withOnyx({ policy: { key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report ? report.policyID : '0'}`, diff --git a/src/pages/iou/steps/MoneyRequestConfirmPage.js b/src/pages/iou/steps/MoneyRequestConfirmPage.js deleted file mode 100644 index 1738ac78df47..000000000000 --- a/src/pages/iou/steps/MoneyRequestConfirmPage.js +++ /dev/null @@ -1,473 +0,0 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; -import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; -import categoryPropTypes from '@components/categoryPropTypes'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import * as Expensicons from '@components/Icon/Expensicons'; -import MoneyRequestConfirmationList from '@components/MoneyRequestConfirmationList'; -import {usePersonalDetails} from '@components/OnyxProvider'; -import ScreenWrapper from '@components/ScreenWrapper'; -import tagPropTypes from '@components/tagPropTypes'; -import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps, withCurrentUserPersonalDetailsPropTypes} from '@components/withCurrentUserPersonalDetails'; -import withLocalize from '@components/withLocalize'; -import useInitialValue from '@hooks/useInitialValue'; -import useNetwork from '@hooks/useNetwork'; -import useThemeStyles from '@hooks/useThemeStyles'; -import useWindowDimensions from '@hooks/useWindowDimensions'; -import compose from '@libs/compose'; -import * as FileUtils from '@libs/fileDownload/FileUtils'; -import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; -import Navigation from '@libs/Navigation/Navigation'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as ReportUtils from '@libs/ReportUtils'; -import {iouDefaultProps, iouPropTypes} from '@pages/iou/propTypes'; -import reportPropTypes from '@pages/reportPropTypes'; -import {policyDefaultProps, policyPropTypes} from '@pages/workspace/withPolicy'; -import * as IOU from '@userActions/IOU'; -import * as Policy from '@userActions/Policy'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; - -const propTypes = { - /** React Navigation route */ - route: PropTypes.shape({ - /** Params from the route */ - params: PropTypes.shape({ - /** The type of IOU report, i.e. bill, request, send */ - iouType: PropTypes.string, - - /** The report ID of the IOU */ - reportID: PropTypes.string, - }), - }).isRequired, - - report: reportPropTypes, - - /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: iouPropTypes, - - /** The policy of the current request */ - policy: policyPropTypes, - - policyTags: tagPropTypes, - - policyCategories: PropTypes.objectOf(categoryPropTypes), - - ...withCurrentUserPersonalDetailsPropTypes, -}; - -const defaultProps = { - report: {}, - policyCategories: {}, - policyTags: {}, - iou: iouDefaultProps, - policy: policyDefaultProps, - ...withCurrentUserPersonalDetailsDefaultProps, -}; - -function MoneyRequestConfirmPage(props) { - const styles = useThemeStyles(); - const {isOffline} = useNetwork(); - const {windowWidth} = useWindowDimensions(); - const prevMoneyRequestId = useRef(props.iou.id); - const iouType = useInitialValue(() => lodashGet(props.route, 'params.iouType', '')); - const reportID = useInitialValue(() => lodashGet(props.route, 'params.reportID', '')); - const isDistanceRequest = MoneyRequestUtils.isDistanceRequest(iouType, props.selectedTab); - const isScanRequest = MoneyRequestUtils.isScanRequest(props.selectedTab); - const [receiptFile, setReceiptFile] = useState(); - const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; - - const participants = useMemo( - () => - _.map(props.iou.participants, (participant) => { - const isPolicyExpenseChat = lodashGet(participant, 'isPolicyExpenseChat', false); - return isPolicyExpenseChat ? OptionsListUtils.getPolicyExpenseReportOption(participant) : OptionsListUtils.getParticipantsOption(participant, personalDetails); - }), - [props.iou.participants, personalDetails], - ); - const isPolicyExpenseChat = useMemo(() => ReportUtils.isPolicyExpenseChat(ReportUtils.getRootParentReport(props.report)), [props.report]); - const isManualRequestDM = props.selectedTab === CONST.TAB_REQUEST.MANUAL && iouType === CONST.IOU.TYPE.REQUEST; - - useEffect(() => { - const policyExpenseChat = _.find(participants, (participant) => participant.isPolicyExpenseChat); - if (policyExpenseChat) { - Policy.openDraftWorkspaceRequest(policyExpenseChat.policyID); - } - }, [isOffline, participants, props.iou.billable, props.policy]); - - const defaultBillable = lodashGet(props.policy, 'defaultBillable', false); - useEffect(() => { - IOU.setMoneyRequestBillable(defaultBillable); - }, [defaultBillable, isOffline]); - - useEffect(() => { - if (!props.iou.receiptPath || !props.iou.receiptFilename) { - return; - } - const onSuccess = (file) => { - const receipt = file; - receipt.state = file && isManualRequestDM ? CONST.IOU.RECEIPT_STATE.OPEN : CONST.IOU.RECEIPT_STATE.SCANREADY; - setReceiptFile(receipt); - }; - const onFailure = () => { - Navigation.goBack(ROUTES.MONEY_REQUEST.getRoute(iouType, reportID)); - }; - FileUtils.readFileAsync(props.iou.receiptPath, props.iou.receiptFilename, onSuccess, onFailure); - }, [props.iou.receiptPath, props.iou.receiptFilename, isManualRequestDM, iouType, reportID]); - - useEffect(() => { - // ID in Onyx could change by initiating a new request in a separate browser tab or completing a request - if (!isDistanceRequest && prevMoneyRequestId.current !== props.iou.id) { - // The ID is cleared on completing a request. In that case, we will do nothing. - if (props.iou.id) { - Navigation.goBack(ROUTES.MONEY_REQUEST.getRoute(iouType, reportID), true); - } - return; - } - - // Reset the money request Onyx if the ID in Onyx does not match the ID from params - const moneyRequestId = `${iouType}${reportID}`; - const shouldReset = !isDistanceRequest && props.iou.id !== moneyRequestId && !_.isEmpty(reportID); - if (shouldReset) { - IOU.resetMoneyRequestInfo(moneyRequestId); - } - - if (_.isEmpty(props.iou.participants) || (props.iou.amount === 0 && !props.iou.receiptPath && !isDistanceRequest) || shouldReset || ReportUtils.isArchivedRoom(props.report)) { - Navigation.goBack(ROUTES.MONEY_REQUEST.getRoute(iouType, reportID), true); - } - - return () => { - prevMoneyRequestId.current = props.iou.id; - }; - }, [props.iou.participants, props.iou.amount, props.iou.id, props.iou.receiptPath, isDistanceRequest, props.report, iouType, reportID]); - - const navigateBack = () => { - let fallback; - if (reportID) { - fallback = ROUTES.MONEY_REQUEST.getRoute(iouType, reportID); - } else { - fallback = ROUTES.MONEY_REQUEST_PARTICIPANTS.getRoute(iouType); - } - Navigation.goBack(fallback); - }; - - /** - * @param {Array} selectedParticipants - * @param {String} trimmedComment - * @param {File} [receipt] - */ - const requestMoney = useCallback( - (selectedParticipants, trimmedComment, receipt) => { - IOU.requestMoney( - props.report, - props.iou.amount, - props.iou.currency, - props.iou.created, - props.iou.merchant, - props.currentUserPersonalDetails.login, - props.currentUserPersonalDetails.accountID, - selectedParticipants[0], - trimmedComment, - receipt, - props.iou.category, - props.iou.tag, - props.iou.billable, - props.policy, - props.policyTags, - props.policyCategories, - ); - }, - [ - props.report, - props.iou.amount, - props.iou.currency, - props.iou.created, - props.iou.merchant, - props.currentUserPersonalDetails.login, - props.currentUserPersonalDetails.accountID, - props.iou.category, - props.iou.tag, - props.iou.billable, - props.policy, - props.policyTags, - props.policyCategories, - ], - ); - - /** - * @param {Array} selectedParticipants - * @param {String} trimmedComment - */ - const createDistanceRequest = useCallback( - (selectedParticipants, trimmedComment) => { - IOU.createDistanceRequest( - props.report, - selectedParticipants[0], - trimmedComment, - props.iou.created, - props.iou.transactionID, - props.iou.category, - props.iou.tag, - props.iou.amount, - props.iou.currency, - props.iou.merchant, - props.iou.billable, - props.policy, - props.policyTags, - props.policyCategories, - ); - }, - [ - props.report, - props.iou.created, - props.iou.transactionID, - props.iou.category, - props.iou.tag, - props.iou.amount, - props.iou.currency, - props.iou.merchant, - props.iou.billable, - props.policy, - props.policyTags, - props.policyCategories, - ], - ); - - const createTransaction = useCallback( - (selectedParticipants) => { - const trimmedComment = props.iou.comment.trim(); - - // If we have a receipt let's start the split bill by creating only the action, the transaction, and the group DM if needed - if (iouType === CONST.IOU.TYPE.SPLIT && props.iou.receiptPath) { - const existingSplitChatReportID = CONST.REGEX.NUMBER.test(reportID) ? reportID : ''; - const onSuccess = (receipt) => { - IOU.startSplitBill( - selectedParticipants, - props.currentUserPersonalDetails.login, - props.currentUserPersonalDetails.accountID, - trimmedComment, - receipt, - existingSplitChatReportID, - ); - }; - FileUtils.readFileAsync(props.iou.receiptPath, props.iou.receiptFilename, onSuccess); - return; - } - - // IOUs created from a group report will have a reportID param in the route. - // Since the user is already viewing the report, we don't need to navigate them to the report - if (iouType === CONST.IOU.TYPE.SPLIT && CONST.REGEX.NUMBER.test(reportID)) { - IOU.splitBill( - selectedParticipants, - props.currentUserPersonalDetails.login, - props.currentUserPersonalDetails.accountID, - props.iou.amount, - trimmedComment, - props.iou.currency, - props.iou.category, - props.iou.tag, - reportID, - props.iou.merchant, - ); - return; - } - - // If the request is created from the global create menu, we also navigate the user to the group report - if (iouType === CONST.IOU.TYPE.SPLIT) { - IOU.splitBillAndOpenReport( - selectedParticipants, - props.currentUserPersonalDetails.login, - props.currentUserPersonalDetails.accountID, - props.iou.amount, - trimmedComment, - props.iou.currency, - props.iou.category, - props.iou.tag, - props.iou.merchant, - ); - return; - } - - if (receiptFile) { - requestMoney(selectedParticipants, trimmedComment, receiptFile); - return; - } - - if (isDistanceRequest) { - createDistanceRequest(selectedParticipants, trimmedComment); - return; - } - - requestMoney(selectedParticipants, trimmedComment); - }, - [ - props.iou.amount, - props.iou.comment, - props.currentUserPersonalDetails.login, - props.currentUserPersonalDetails.accountID, - props.iou.currency, - props.iou.category, - props.iou.tag, - props.iou.receiptPath, - props.iou.receiptFilename, - isDistanceRequest, - requestMoney, - createDistanceRequest, - receiptFile, - iouType, - reportID, - props.iou.merchant, - ], - ); - - /** - * Checks if user has a GOLD wallet then creates a paid IOU report on the fly - * - * @param {String} paymentMethodType - */ - const sendMoney = useCallback( - (paymentMethodType) => { - const currency = props.iou.currency; - const trimmedComment = props.iou.comment.trim(); - const participant = participants[0]; - - if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.ELSEWHERE) { - IOU.sendMoneyElsewhere(props.report, props.iou.amount, currency, trimmedComment, props.currentUserPersonalDetails.accountID, participant); - return; - } - - if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY) { - IOU.sendMoneyWithWallet(props.report, props.iou.amount, currency, trimmedComment, props.currentUserPersonalDetails.accountID, participant); - } - }, - [props.iou.amount, props.iou.comment, participants, props.iou.currency, props.currentUserPersonalDetails.accountID, props.report], - ); - - const headerTitle = () => { - if (isDistanceRequest) { - return props.translate('common.distance'); - } - - if (iouType === CONST.IOU.TYPE.SPLIT) { - return props.translate('iou.split'); - } - - if (iouType === CONST.IOU.TYPE.SEND) { - return props.translate('common.send'); - } - - if (isScanRequest) { - return props.translate('tabSelector.scan'); - } - - return props.translate('tabSelector.manual'); - }; - - return ( - - {({safeAreaPaddingBottomStyle}) => ( - - Navigation.navigate(ROUTES.MONEY_REQUEST_RECEIPT.getRoute(iouType, reportID)), - }, - ]} - /> - { - const newParticipants = _.map(props.iou.participants, (participant) => { - if (participant.accountID === option.accountID) { - return {...participant, selected: !participant.selected}; - } - return participant; - }); - IOU.setMoneyRequestParticipants(newParticipants); - }} - receiptPath={props.iou.receiptPath} - receiptFilename={props.iou.receiptFilename} - iouType={iouType} - reportID={reportID} - isPolicyExpenseChat={isPolicyExpenseChat} - // The participants can only be modified when the action is initiated from directly within a group chat and not the floating-action-button. - // This is because when there is a group of people, say they are on a trip, and you have some shared expenses with some of the people, - // but not all of them (maybe someone skipped out on dinner). Then it's nice to be able to select/deselect people from the group chat bill - // split rather than forcing the user to create a new group, just for that expense. The reportID is empty, when the action was initiated from - // the floating-action-button (since it is something that exists outside the context of a report). - canModifyParticipants={!_.isEmpty(reportID)} - policyID={props.report.policyID} - bankAccountRoute={ReportUtils.getBankAccountRoute(props.report)} - iouMerchant={props.iou.merchant} - iouCreated={props.iou.created} - isScanRequest={isScanRequest} - isDistanceRequest={isDistanceRequest} - shouldShowSmartScanFields={_.isEmpty(props.iou.receiptPath)} - /> - - )} - - ); -} - -MoneyRequestConfirmPage.displayName = 'MoneyRequestConfirmPage'; -MoneyRequestConfirmPage.propTypes = propTypes; -MoneyRequestConfirmPage.defaultProps = defaultProps; - -export default compose( - withCurrentUserPersonalDetails, - withLocalize, - withOnyx({ - iou: { - key: ONYXKEYS.IOU, - }, - }), - // eslint-disable-next-line rulesdir/no-multiple-onyx-in-file - withOnyx({ - report: { - key: ({route, iou}) => { - const reportID = IOU.getIOUReportID(iou, route); - - return `${ONYXKEYS.COLLECTION.REPORT}${reportID}`; - }, - }, - selectedTab: { - key: `${ONYXKEYS.COLLECTION.SELECTED_TAB}${CONST.TAB.RECEIPT_TAB_ID}`, - }, - }), - withOnyx({ - policy: { - key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report ? report.policyID : '0'}`, - }, - policyCategories: { - key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${report ? report.policyID : '0'}`, - }, - policyTags: { - key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${report ? report.policyID : '0'}`, - }, - }), -)(MoneyRequestConfirmPage); diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js index 216154be9cd4..1feb7a2c32fd 100644 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js @@ -89,7 +89,7 @@ function MoneyRequestParticipantsPage({iou, selectedTab, route, transaction}) { IOU.setMoneyRequestId(moneyRequestType); IOU.resetMoneyRequestCategory(); IOU.resetMoneyRequestTag(); - Navigation.navigate(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(moneyRequestType, reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(moneyRequestType, lodashGet(transaction, 'transactionID', 1), reportID)); }; const navigateBack = useCallback((forceFallback = false) => { diff --git a/src/pages/iou/steps/NewRequestAmountPage.js b/src/pages/iou/steps/NewRequestAmountPage.js index 1df74569e4c3..007a63bdb713 100644 --- a/src/pages/iou/steps/NewRequestAmountPage.js +++ b/src/pages/iou/steps/NewRequestAmountPage.js @@ -113,7 +113,7 @@ function NewRequestAmountPage({route, iou, report, selectedTab}) { }, [iou.participants, iou.amount, iou.id, isEditing, iouType, reportID, isDistanceRequestTab]); const navigateBack = () => { - Navigation.goBack(isEditing ? ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID) : ROUTES.HOME); + Navigation.goBack(isEditing ? ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID) : ROUTES.HOME); }; const navigateToCurrencySelectionPage = () => { @@ -134,7 +134,7 @@ function NewRequestAmountPage({route, iou, report, selectedTab}) { IOU.setMoneyRequestCurrency(currency); if (isEditing) { - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); return; } From 8e4e4d803f40cd0c35b05ee1a51da2c4899154a3 Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 31 Jan 2024 16:54:59 +0700 Subject: [PATCH 02/61] fix lint --- src/pages/iou/request/step/IOURequestStepConfirmation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.js b/src/pages/iou/request/step/IOURequestStepConfirmation.js index cb9edfb5868b..f867e57f9a13 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.js +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.js @@ -8,6 +8,7 @@ import categoryPropTypes from '@components/categoryPropTypes'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import MoneyRequestConfirmationList from '@components/MoneyTemporaryForRefactorRequestConfirmationList'; +import {usePersonalDetails} from '@components/OnyxProvider'; import ScreenWrapper from '@components/ScreenWrapper'; import tagPropTypes from '@components/tagPropTypes'; import transactionPropTypes from '@components/transactionPropTypes'; @@ -23,7 +24,6 @@ import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; -import {usePersonalDetails} from '@components/OnyxProvider'; import reportPropTypes from '@pages/reportPropTypes'; import {policyPropTypes} from '@pages/workspace/withPolicy'; import * as IOU from '@userActions/IOU'; From ee1efe95e93aea8be888b50338534cf3f6f28bff Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 31 Jan 2024 17:09:35 +0700 Subject: [PATCH 03/61] update send money flow --- .../SidebarScreen/FloatingActionButtonAndPopover.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js index bbcdc5cebef4..7281868f47d9 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js @@ -182,7 +182,14 @@ function FloatingActionButtonAndPopover(props) { { icon: Expensicons.Send, text: props.translate('iou.sendMoney'), - onSelected: () => interceptAnonymousUser(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SEND)), + onSelected: () => + interceptAnonymousUser(() => + Navigation.navigate( + // When starting to create a money request from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used + // for all of the routes in the creation flow. + ROUTES.MONEY_REQUEST_CREATE.getRoute(CONST.IOU.TYPE.SEND, CONST.IOU.OPTIMISTIC_TRANSACTION_ID, ReportUtils.generateReportID()), + ), + ), }, ...[ { From 73dff71e03d9163de1e41d69a77f22575f715bb3 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Mon, 18 Mar 2024 19:42:55 +0700 Subject: [PATCH 04/61] merge main --- src/pages/iou/MoneyRequestCategoryPage.js | 106 ------------ src/pages/iou/MoneyRequestDatePage.js | 126 -------------- src/pages/iou/MoneyRequestDescriptionPage.js | 165 ------------------- src/pages/iou/MoneyRequestMerchantPage.js | 140 ---------------- src/pages/iou/MoneyRequestTagPage.js | 127 -------------- 5 files changed, 664 deletions(-) delete mode 100644 src/pages/iou/MoneyRequestCategoryPage.js delete mode 100644 src/pages/iou/MoneyRequestDatePage.js delete mode 100644 src/pages/iou/MoneyRequestDescriptionPage.js delete mode 100644 src/pages/iou/MoneyRequestMerchantPage.js delete mode 100644 src/pages/iou/MoneyRequestTagPage.js diff --git a/src/pages/iou/MoneyRequestCategoryPage.js b/src/pages/iou/MoneyRequestCategoryPage.js deleted file mode 100644 index b3ca0a5d7ae0..000000000000 --- a/src/pages/iou/MoneyRequestCategoryPage.js +++ /dev/null @@ -1,106 +0,0 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React from 'react'; -import {withOnyx} from 'react-native-onyx'; -import CategoryPicker from '@components/CategoryPicker'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import Text from '@components/Text'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import compose from '@libs/compose'; -import Navigation from '@libs/Navigation/Navigation'; -import reportPropTypes from '@pages/reportPropTypes'; -import * as IOU from '@userActions/IOU'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import {iouDefaultProps, iouPropTypes} from './propTypes'; - -const propTypes = { - /** Navigation route context info provided by react navigation */ - route: PropTypes.shape({ - /** Route specific parameters used on this screen via route :iouType/new/category/:reportID? */ - params: PropTypes.shape({ - /** The type of IOU report, i.e. bill, request, send */ - iouType: PropTypes.string, - - /** The report ID of the IOU */ - reportID: PropTypes.string, - }), - }).isRequired, - - /* Onyx Props */ - /** The report currently being used */ - report: reportPropTypes, - - /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: iouPropTypes, -}; - -const defaultProps = { - report: {}, - iou: iouDefaultProps, -}; - -function MoneyRequestCategoryPage({route, report, iou}) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - - const reportID = lodashGet(route, 'params.reportID', ''); - const iouType = lodashGet(route, 'params.iouType', ''); - - const navigateBack = () => { - Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); - }; - - const updateCategory = (category) => { - if (category.searchText === iou.category) { - IOU.resetMoneyRequestCategory(); - } else { - IOU.setMoneyRequestCategory(category.searchText); - } - - Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); - }; - - return ( - - - {translate('iou.categorySelection')} - - - ); -} - -MoneyRequestCategoryPage.displayName = 'MoneyRequestCategoryPage'; -MoneyRequestCategoryPage.propTypes = propTypes; -MoneyRequestCategoryPage.defaultProps = defaultProps; - -export default compose( - withOnyx({ - iou: { - key: ONYXKEYS.IOU, - }, - }), - // eslint-disable-next-line rulesdir/no-multiple-onyx-in-file - withOnyx({ - report: { - key: ({route, iou}) => { - const reportID = IOU.getIOUReportID(iou, route); - - return `${ONYXKEYS.COLLECTION.REPORT}${reportID}`; - }, - }, - }), -)(MoneyRequestCategoryPage); diff --git a/src/pages/iou/MoneyRequestDatePage.js b/src/pages/iou/MoneyRequestDatePage.js deleted file mode 100644 index c99c07a80624..000000000000 --- a/src/pages/iou/MoneyRequestDatePage.js +++ /dev/null @@ -1,126 +0,0 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React, {useEffect} from 'react'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; -import DatePicker from '@components/DatePicker'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapper from '@components/Form/InputWrapper'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; -import Navigation from '@libs/Navigation/Navigation'; -import * as IOU from '@userActions/IOU'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import {iouDefaultProps, iouPropTypes} from './propTypes'; - -const propTypes = { - /** Onyx Props */ - /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: iouPropTypes, - - /** Route from navigation */ - route: PropTypes.shape({ - /** Params from the route */ - params: PropTypes.shape({ - /** The type of IOU report, i.e. bill, request, send */ - iouType: PropTypes.string, - - /** The report ID of the IOU */ - reportID: PropTypes.string, - - /** Which field we are editing */ - field: PropTypes.string, - - /** reportID for the "transaction thread" */ - threadReportID: PropTypes.string, - }), - }).isRequired, - - /** The current tab we have navigated to in the request modal. String that corresponds to the request type. */ - selectedTab: PropTypes.oneOf(_.values(CONST.TAB_REQUEST)).isRequired, -}; - -const defaultProps = { - iou: iouDefaultProps, -}; - -function MoneyRequestDatePage({iou, route, selectedTab}) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const iouType = lodashGet(route, 'params.iouType', ''); - const reportID = lodashGet(route, 'params.reportID', ''); - const isDistanceRequest = MoneyRequestUtils.isDistanceRequest(iouType, selectedTab); - - useEffect(() => { - const moneyRequestId = `${iouType}${reportID}`; - const shouldReset = iou.id !== moneyRequestId; - if (shouldReset) { - IOU.resetMoneyRequestInfo(moneyRequestId); - } - - if (!isDistanceRequest && (_.isEmpty(iou.participants) || (iou.amount === 0 && !iou.receiptPath) || shouldReset)) { - Navigation.goBack(ROUTES.MONEY_REQUEST.getRoute(iouType, reportID), true); - } - }, [iou.id, iou.participants, iou.amount, iou.receiptPath, iouType, reportID, isDistanceRequest]); - - function navigateBack() { - Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); - } - - /** - * Sets the money request comment by saving it to Onyx. - * - * @param {Object} value - * @param {String} value.moneyRequestCreated - */ - function updateDate(value) { - IOU.setMoneyRequestCreated(value.moneyRequestCreated); - navigateBack(); - } - - return ( - - navigateBack()} - /> - updateDate(value)} - submitButtonText={translate('common.save')} - enabledWhenOffline - > - - - - ); -} - -MoneyRequestDatePage.propTypes = propTypes; -MoneyRequestDatePage.defaultProps = defaultProps; -MoneyRequestDatePage.displayName = 'MoneyRequestDatePage'; - -export default withOnyx({ - iou: { - key: ONYXKEYS.IOU, - }, - selectedTab: { - key: `${ONYXKEYS.COLLECTION.SELECTED_TAB}${CONST.TAB.RECEIPT_TAB_ID}`, - }, -})(MoneyRequestDatePage); diff --git a/src/pages/iou/MoneyRequestDescriptionPage.js b/src/pages/iou/MoneyRequestDescriptionPage.js deleted file mode 100644 index a2209818ee1a..000000000000 --- a/src/pages/iou/MoneyRequestDescriptionPage.js +++ /dev/null @@ -1,165 +0,0 @@ -import {useFocusEffect} from '@react-navigation/native'; -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React, {useCallback, useEffect, useRef} from 'react'; -import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapperWithRef from '@components/Form/InputWrapper'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import TextInput from '@components/TextInput'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import * as IOU from '@libs/actions/IOU'; -import * as Browser from '@libs/Browser'; -import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; -import Navigation from '@libs/Navigation/Navigation'; -import updateMultilineInputRange from '@libs/updateMultilineInputRange'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import {iouDefaultProps, iouPropTypes} from './propTypes'; - -const propTypes = { - /** Onyx Props */ - /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: iouPropTypes, - - /** Route from navigation */ - route: PropTypes.shape({ - /** Params from the route */ - params: PropTypes.shape({ - /** The type of IOU report, i.e. bill, request, send */ - iouType: PropTypes.string, - - /** The report ID of the IOU */ - reportID: PropTypes.string, - - /** Which field we are editing */ - field: PropTypes.string, - - /** reportID for the "transaction thread" */ - threadReportID: PropTypes.string, - }), - }).isRequired, - - /** The current tab we have navigated to in the request modal. String that corresponds to the request type. */ - selectedTab: PropTypes.oneOf(_.values(CONST.TAB_REQUEST)), -}; - -const defaultProps = { - iou: iouDefaultProps, - selectedTab: '', -}; - -function MoneyRequestDescriptionPage({iou, route, selectedTab}) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const inputRef = useRef(null); - const focusTimeoutRef = useRef(null); - const iouType = lodashGet(route, 'params.iouType', ''); - const reportID = lodashGet(route, 'params.reportID', ''); - const isDistanceRequest = MoneyRequestUtils.isDistanceRequest(iouType, selectedTab); - - useFocusEffect( - useCallback(() => { - focusTimeoutRef.current = setTimeout(() => { - if (inputRef.current) { - inputRef.current.focus(); - } - return () => { - if (!focusTimeoutRef.current) { - return; - } - clearTimeout(focusTimeoutRef.current); - }; - }, CONST.ANIMATED_TRANSITION); - }, []), - ); - - useEffect(() => { - const moneyRequestId = `${iouType}${reportID}`; - const shouldReset = iou.id !== moneyRequestId; - if (shouldReset) { - IOU.resetMoneyRequestInfo(moneyRequestId); - } - - if (!isDistanceRequest && (_.isEmpty(iou.participants) || (iou.amount === 0 && !iou.receiptPath) || shouldReset)) { - Navigation.goBack(ROUTES.MONEY_REQUEST.getRoute(iouType, reportID), true); - } - }, [iou.id, iou.participants, iou.amount, iou.receiptPath, iouType, reportID, isDistanceRequest]); - - function navigateBack() { - Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); - } - - /** - * Sets the money request comment by saving it to Onyx. - * - * @param {Object} value - * @param {String} value.moneyRequestComment - */ - function updateComment(value) { - IOU.setMoneyRequestDescription(value.moneyRequestComment); - navigateBack(); - } - - return ( - - <> - navigateBack()} - /> - updateComment(value)} - submitButtonText={translate('common.save')} - enabledWhenOffline - > - - { - if (!el) { - return; - } - inputRef.current = el; - updateMultilineInputRange(inputRef.current); - }} - autoGrowHeight - containerStyles={[styles.autoGrowHeightMultilineInput]} - submitOnEnter={!Browser.isMobile()} - /> - - - - - ); -} - -MoneyRequestDescriptionPage.propTypes = propTypes; -MoneyRequestDescriptionPage.defaultProps = defaultProps; -MoneyRequestDescriptionPage.displayName = 'MoneyRequestDescriptionPage'; - -export default withOnyx({ - iou: { - key: ONYXKEYS.IOU, - }, - selectedTab: { - key: `${ONYXKEYS.COLLECTION.SELECTED_TAB}${CONST.TAB.RECEIPT_TAB_ID}`, - }, -})(MoneyRequestDescriptionPage); diff --git a/src/pages/iou/MoneyRequestMerchantPage.js b/src/pages/iou/MoneyRequestMerchantPage.js deleted file mode 100644 index 1d3fc6f19584..000000000000 --- a/src/pages/iou/MoneyRequestMerchantPage.js +++ /dev/null @@ -1,140 +0,0 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React, {useCallback, useEffect} from 'react'; -import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapperWithRef from '@components/Form/InputWrapper'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import TextInput from '@components/TextInput'; -import useAutoFocusInput from '@hooks/useAutoFocusInput'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import Navigation from '@libs/Navigation/Navigation'; -import * as IOU from '@userActions/IOU'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import INPUT_IDS from '@src/types/form/MoneyRequestMerchantForm'; -import {iouDefaultProps, iouPropTypes} from './propTypes'; - -const propTypes = { - /** Onyx Props */ - /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: iouPropTypes, - - /** Route from navigation */ - route: PropTypes.shape({ - /** Params from the route */ - params: PropTypes.shape({ - /** The type of IOU report, i.e. bill, request, send */ - iouType: PropTypes.string, - - /** The report ID of the IOU */ - reportID: PropTypes.string, - - /** Which field we are editing */ - field: PropTypes.string, - - /** reportID for the "transaction thread" */ - threadReportID: PropTypes.string, - }), - }).isRequired, -}; - -const defaultProps = { - iou: iouDefaultProps, -}; - -function MoneyRequestMerchantPage({iou, route}) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const {inputCallbackRef} = useAutoFocusInput(); - const iouType = lodashGet(route, 'params.iouType', ''); - const reportID = lodashGet(route, 'params.reportID', ''); - const isEmptyMerchant = iou.merchant === '' || iou.merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT; - - useEffect(() => { - const moneyRequestId = `${iouType}${reportID}`; - const shouldReset = iou.id !== moneyRequestId; - if (shouldReset) { - IOU.resetMoneyRequestInfo(moneyRequestId); - } - - if (_.isEmpty(iou.participants) || (iou.amount === 0 && !iou.receiptPath) || shouldReset) { - Navigation.goBack(ROUTES.MONEY_REQUEST.getRoute(iouType, reportID), true); - } - }, [iou.id, iou.participants, iou.amount, iou.receiptPath, iouType, reportID]); - - function navigateBack() { - Navigation.goBack(ROUTES.MONEY_REQUEST__STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); - } - - const validate = useCallback((value) => { - const errors = {}; - - if (_.isEmpty(value.moneyRequestMerchant)) { - errors.moneyRequestMerchant = 'common.error.fieldRequired'; - } - - return errors; - }, []); - - /** - * Sets the money request comment by saving it to Onyx. - * - * @param {Object} value - * @param {String} value.moneyRequestMerchant - */ - function updateMerchant(value) { - IOU.setMoneyRequestMerchant(value.moneyRequestMerchant); - navigateBack(); - } - - return ( - - navigateBack()} - /> - updateMerchant(value)} - validate={validate} - submitButtonText={translate('common.save')} - enabledWhenOffline - > - - - - - - ); -} - -MoneyRequestMerchantPage.propTypes = propTypes; -MoneyRequestMerchantPage.defaultProps = defaultProps; -MoneyRequestMerchantPage.displayName = 'MoneyRequestMerchantPage'; - -export default withOnyx({ - iou: { - key: ONYXKEYS.IOU, - }, -})(MoneyRequestMerchantPage); diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js deleted file mode 100644 index 7fd08f20d652..000000000000 --- a/src/pages/iou/MoneyRequestTagPage.js +++ /dev/null @@ -1,127 +0,0 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React from 'react'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import TagPicker from '@components/TagPicker'; -import tagPropTypes from '@components/tagPropTypes'; -import Text from '@components/Text'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import compose from '@libs/compose'; -import Navigation from '@libs/Navigation/Navigation'; -import * as PolicyUtils from '@libs/PolicyUtils'; -import reportPropTypes from '@pages/reportPropTypes'; -import * as IOU from '@userActions/IOU'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import {iouDefaultProps, iouPropTypes} from './propTypes'; - -const propTypes = { - /** Navigation route context info provided by react navigation */ - route: PropTypes.shape({ - /** Route specific parameters used on this screen via route :iouType/new/tag/:reportID? */ - params: PropTypes.shape({ - /** The type of IOU report, i.e. bill, request, send */ - iouType: PropTypes.string, - - /** The report ID of the IOU */ - reportID: PropTypes.string, - }), - }).isRequired, - - /* Onyx props */ - /** The report currently being used */ - report: reportPropTypes, - - /** Collection of tags attached to a policy */ - policyTags: tagPropTypes, - - /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: iouPropTypes, -}; - -const defaultProps = { - report: {}, - policyTags: {}, - iou: iouDefaultProps, -}; - -function MoneyRequestTagPage({route, report, policyTags, iou}) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - - const iouType = lodashGet(route, 'params.iouType', ''); - - // Fetches the first tag list of the policy - const tagListKey = _.first(_.keys(policyTags)); - const policyTagListName = PolicyUtils.getTagListName(policyTags) || translate('common.tag'); - - const navigateBack = () => { - Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', report.reportID)); - }; - - const updateTag = (selectedTag) => { - if (selectedTag.searchText === iou.tag) { - IOU.resetMoneyRequestTag(); - } else { - IOU.setMoneyRequestTag(selectedTag.searchText); - } - navigateBack(); - }; - - return ( - - {({insets}) => ( - <> - - {translate('iou.tagSelection', {tagName: policyTagListName})} - - - )} - - ); -} - -MoneyRequestTagPage.displayName = 'MoneyRequestTagPage'; -MoneyRequestTagPage.propTypes = propTypes; -MoneyRequestTagPage.defaultProps = defaultProps; - -export default compose( - withOnyx({ - iou: { - key: ONYXKEYS.IOU, - }, - }), - // eslint-disable-next-line rulesdir/no-multiple-onyx-in-file - withOnyx({ - report: { - key: ({route, iou}) => { - const reportID = IOU.getIOUReportID(iou, route); - - return `${ONYXKEYS.COLLECTION.REPORT}${reportID}`; - }, - }, - }), - // eslint-disable-next-line rulesdir/no-multiple-onyx-in-file - withOnyx({ - policyTags: { - key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${report ? report.policyID : '0'}`, - }, - }), -)(MoneyRequestTagPage); From 26801e73a92c0e86bb9e379ab3cfe037dcb2f156 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Mon, 18 Mar 2024 19:45:19 +0700 Subject: [PATCH 05/61] merge main --- src/pages/EditRequestMerchantPage.js | 85 ---------------------------- 1 file changed, 85 deletions(-) delete mode 100644 src/pages/EditRequestMerchantPage.js diff --git a/src/pages/EditRequestMerchantPage.js b/src/pages/EditRequestMerchantPage.js deleted file mode 100644 index 33c04df39e3e..000000000000 --- a/src/pages/EditRequestMerchantPage.js +++ /dev/null @@ -1,85 +0,0 @@ -import PropTypes from 'prop-types'; -import React, {useCallback, useRef} from 'react'; -import {View} from 'react-native'; -import _ from 'underscore'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapper from '@components/Form/InputWrapper'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import TextInput from '@components/TextInput'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import INPUT_IDS from '@src/types/form/MoneyRequestMerchantForm'; - -const propTypes = { - /** Transaction default merchant value */ - defaultMerchant: PropTypes.string.isRequired, - - /** Callback to fire when the Save button is pressed */ - onSubmit: PropTypes.func.isRequired, - - /** Boolean to enable validation */ - isPolicyExpenseChat: PropTypes.bool, -}; - -const defaultProps = { - isPolicyExpenseChat: false, -}; - -function EditRequestMerchantPage({defaultMerchant, onSubmit, isPolicyExpenseChat}) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const merchantInputRef = useRef(null); - const isEmptyMerchant = defaultMerchant === '' || defaultMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT; - - const validate = useCallback( - (value) => { - const errors = {}; - if (_.isEmpty(value.merchant) && value.merchant.trim() === '' && isPolicyExpenseChat) { - errors.merchant = 'common.error.fieldRequired'; - } - return errors; - }, - [isPolicyExpenseChat], - ); - - return ( - merchantInputRef.current && merchantInputRef.current.focus()} - testID={EditRequestMerchantPage.displayName} - > - - - - (merchantInputRef.current = e)} - /> - - - - ); -} - -EditRequestMerchantPage.propTypes = propTypes; -EditRequestMerchantPage.defaultProps = defaultProps; -EditRequestMerchantPage.displayName = 'EditRequestMerchantPage'; - -export default EditRequestMerchantPage; From 0abc91308b5bd675562a1689bfa795e904b9e5be Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Mon, 18 Mar 2024 19:49:33 +0700 Subject: [PATCH 06/61] merge main --- src/libs/Navigation/linkingConfig.ts | 506 --------------------------- 1 file changed, 506 deletions(-) delete mode 100644 src/libs/Navigation/linkingConfig.ts diff --git a/src/libs/Navigation/linkingConfig.ts b/src/libs/Navigation/linkingConfig.ts deleted file mode 100644 index d4e04d5402e2..000000000000 --- a/src/libs/Navigation/linkingConfig.ts +++ /dev/null @@ -1,506 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -import type {LinkingOptions} from '@react-navigation/native'; -import CONST from '@src/CONST'; -import NAVIGATORS from '@src/NAVIGATORS'; -import ROUTES from '@src/ROUTES'; -import SCREENS from '@src/SCREENS'; -import type {RootStackParamList} from './types'; - -const linkingConfig: LinkingOptions = { - prefixes: [ - 'app://-/', - 'new-expensify://', - 'https://www.expensify.cash', - 'https://staging.expensify.cash', - 'https://dev.new.expensify.com', - CONST.NEW_EXPENSIFY_URL, - CONST.STAGING_NEW_EXPENSIFY_URL, - ], - config: { - initialRouteName: SCREENS.HOME, - screens: { - // Main Routes - [SCREENS.VALIDATE_LOGIN]: ROUTES.VALIDATE_LOGIN, - [SCREENS.UNLINK_LOGIN]: ROUTES.UNLINK_LOGIN, - [SCREENS.TRANSITION_BETWEEN_APPS]: ROUTES.TRANSITION_BETWEEN_APPS, - [SCREENS.CONCIERGE]: ROUTES.CONCIERGE, - [SCREENS.SIGN_IN_WITH_APPLE_DESKTOP]: ROUTES.APPLE_SIGN_IN, - [SCREENS.SIGN_IN_WITH_GOOGLE_DESKTOP]: ROUTES.GOOGLE_SIGN_IN, - [SCREENS.SAML_SIGN_IN]: ROUTES.SAML_SIGN_IN, - [SCREENS.DESKTOP_SIGN_IN_REDIRECT]: ROUTES.DESKTOP_SIGN_IN_REDIRECT, - [SCREENS.REPORT_ATTACHMENTS]: ROUTES.REPORT_ATTACHMENTS.route, - [SCREENS.PROFILE_AVATAR]: ROUTES.PROFILE_AVATAR.route, - [SCREENS.WORKSPACE_AVATAR]: ROUTES.WORKSPACE_AVATAR.route, - [SCREENS.REPORT_AVATAR]: ROUTES.REPORT_AVATAR.route, - - // Sidebar - [SCREENS.HOME]: { - path: ROUTES.HOME, - }, - - [NAVIGATORS.CENTRAL_PANE_NAVIGATOR]: { - screens: { - [SCREENS.REPORT]: ROUTES.REPORT_WITH_ID.route, - }, - }, - [SCREENS.NOT_FOUND]: '*', - [NAVIGATORS.LEFT_MODAL_NAVIGATOR]: { - screens: { - [SCREENS.LEFT_MODAL.SEARCH]: { - screens: { - [SCREENS.SEARCH_ROOT]: ROUTES.SEARCH, - }, - }, - }, - }, - [NAVIGATORS.RIGHT_MODAL_NAVIGATOR]: { - screens: { - [SCREENS.RIGHT_MODAL.SETTINGS]: { - screens: { - [SCREENS.SETTINGS.ROOT]: { - path: ROUTES.SETTINGS, - }, - [SCREENS.SETTINGS.WORKSPACES]: { - path: ROUTES.SETTINGS_WORKSPACES, - exact: true, - }, - [SCREENS.SETTINGS.PREFERENCES.ROOT]: { - path: ROUTES.SETTINGS_PREFERENCES, - exact: true, - }, - [SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE]: { - path: ROUTES.SETTINGS_PRIORITY_MODE, - exact: true, - }, - [SCREENS.SETTINGS.PREFERENCES.LANGUAGE]: { - path: ROUTES.SETTINGS_LANGUAGE, - exact: true, - }, - [SCREENS.SETTINGS.PREFERENCES.THEME]: { - path: ROUTES.SETTINGS_THEME, - exact: true, - }, - [SCREENS.SETTINGS.CLOSE]: { - path: ROUTES.SETTINGS_CLOSE, - exact: true, - }, - [SCREENS.SETTINGS.SECURITY]: { - path: ROUTES.SETTINGS_SECURITY, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.ROOT]: { - path: ROUTES.SETTINGS_WALLET, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.DOMAIN_CARD]: { - path: ROUTES.SETTINGS_WALLET_DOMAINCARD.route, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.REPORT_VIRTUAL_CARD_FRAUD]: { - path: ROUTES.SETTINGS_REPORT_FRAUD.route, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.NAME]: { - path: ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_NAME.route, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.PHONE]: { - path: ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_PHONE.route, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.ADDRESS]: { - path: ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_ADDRESS.route, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.CONFIRM]: { - path: ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_CONFIRM.route, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: { - path: ROUTES.SETTINGS_ENABLE_PAYMENTS, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE]: { - path: ROUTES.SETTINGS_WALLET_TRANSFER_BALANCE, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.CHOOSE_TRANSFER_ACCOUNT]: { - path: ROUTES.SETTINGS_WALLET_CHOOSE_TRANSFER_ACCOUNT, - exact: true, - }, - [SCREENS.SETTINGS.REPORT_CARD_LOST_OR_DAMAGED]: { - path: ROUTES.SETTINGS_WALLET_REPORT_CARD_LOST_OR_DAMAGED.route, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.CARD_ACTIVATE]: { - path: ROUTES.SETTINGS_WALLET_CARD_ACTIVATE.route, - exact: true, - }, - [SCREENS.SETTINGS.WALLET.CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS]: { - path: ROUTES.SETTINGS_WALLET_CARD_DIGITAL_DETAILS_UPDATE_ADDRESS.route, - exact: true, - }, - [SCREENS.SETTINGS.ADD_DEBIT_CARD]: { - path: ROUTES.SETTINGS_ADD_DEBIT_CARD, - exact: true, - }, - [SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: { - path: ROUTES.SETTINGS_ADD_BANK_ACCOUNT, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.ROOT]: { - path: ROUTES.SETTINGS_PROFILE, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.PRONOUNS]: { - path: ROUTES.SETTINGS_PRONOUNS, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.DISPLAY_NAME]: { - path: ROUTES.SETTINGS_DISPLAY_NAME, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.TIMEZONE]: { - path: ROUTES.SETTINGS_TIMEZONE, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.TIMEZONE_SELECT]: { - path: ROUTES.SETTINGS_TIMEZONE_SELECT, - exact: true, - }, - [SCREENS.SETTINGS.ABOUT]: { - path: ROUTES.SETTINGS_ABOUT, - exact: true, - }, - [SCREENS.SETTINGS.APP_DOWNLOAD_LINKS]: { - path: ROUTES.SETTINGS_APP_DOWNLOAD_LINKS, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.CONTACT_METHODS]: { - path: ROUTES.SETTINGS_CONTACT_METHODS.route, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.CONTACT_METHOD_DETAILS]: { - path: ROUTES.SETTINGS_CONTACT_METHOD_DETAILS.route, - }, - [SCREENS.SETTINGS.LOUNGE_ACCESS]: { - path: ROUTES.SETTINGS_LOUNGE_ACCESS, - }, - [SCREENS.SETTINGS.PROFILE.NEW_CONTACT_METHOD]: { - path: ROUTES.SETTINGS_NEW_CONTACT_METHOD.route, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.PERSONAL_DETAILS.INITIAL]: { - path: ROUTES.SETTINGS_PERSONAL_DETAILS, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.PERSONAL_DETAILS.LEGAL_NAME]: { - path: ROUTES.SETTINGS_PERSONAL_DETAILS_LEGAL_NAME, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.PERSONAL_DETAILS.DATE_OF_BIRTH]: { - path: ROUTES.SETTINGS_PERSONAL_DETAILS_DATE_OF_BIRTH, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.PERSONAL_DETAILS.ADDRESS]: { - path: ROUTES.SETTINGS_PERSONAL_DETAILS_ADDRESS, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.PERSONAL_DETAILS.ADDRESS_COUNTRY]: { - path: ROUTES.SETTINGS_PERSONAL_DETAILS_ADDRESS_COUNTRY.route, - exact: true, - }, - [SCREENS.SETTINGS.TWO_FACTOR_AUTH]: { - path: ROUTES.SETTINGS_2FA.route, - exact: true, - }, - [SCREENS.SETTINGS.SHARE_CODE]: { - path: ROUTES.SETTINGS_SHARE_CODE, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.STATUS]: { - path: ROUTES.SETTINGS_STATUS, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.STATUS_CLEAR_AFTER]: { - path: ROUTES.SETTINGS_STATUS_CLEAR_AFTER, - }, - [SCREENS.SETTINGS.PROFILE.STATUS_CLEAR_AFTER_DATE]: { - path: ROUTES.SETTINGS_STATUS_CLEAR_AFTER_DATE, - }, - [SCREENS.SETTINGS.PROFILE.STATUS_CLEAR_AFTER_TIME]: { - path: ROUTES.SETTINGS_STATUS_CLEAR_AFTER_TIME, - }, - [SCREENS.WORKSPACE.INITIAL]: { - path: ROUTES.WORKSPACE_INITIAL.route, - }, - [SCREENS.WORKSPACE.SETTINGS]: { - path: ROUTES.WORKSPACE_SETTINGS.route, - }, - [SCREENS.WORKSPACE.CURRENCY]: { - path: ROUTES.WORKSPACE_SETTINGS_CURRENCY.route, - }, - [SCREENS.WORKSPACE.CARD]: { - path: ROUTES.WORKSPACE_CARD.route, - }, - [SCREENS.WORKSPACE.REIMBURSE]: { - path: ROUTES.WORKSPACE_REIMBURSE.route, - }, - [SCREENS.WORKSPACE.RATE_AND_UNIT]: { - path: ROUTES.WORKSPACE_RATE_AND_UNIT.route, - }, - [SCREENS.WORKSPACE.BILLS]: { - path: ROUTES.WORKSPACE_BILLS.route, - }, - [SCREENS.WORKSPACE.INVOICES]: { - path: ROUTES.WORKSPACE_INVOICES.route, - }, - [SCREENS.WORKSPACE.TRAVEL]: { - path: ROUTES.WORKSPACE_TRAVEL.route, - }, - [SCREENS.WORKSPACE.MEMBERS]: { - path: ROUTES.WORKSPACE_MEMBERS.route, - }, - [SCREENS.WORKSPACE.INVITE]: { - path: ROUTES.WORKSPACE_INVITE.route, - }, - [SCREENS.WORKSPACE.INVITE_MESSAGE]: { - path: ROUTES.WORKSPACE_INVITE_MESSAGE.route, - }, - [SCREENS.REIMBURSEMENT_ACCOUNT]: { - path: ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.route, - exact: true, - }, - [SCREENS.GET_ASSISTANCE]: { - path: ROUTES.GET_ASSISTANCE.route, - }, - [SCREENS.KEYBOARD_SHORTCUTS]: { - path: ROUTES.KEYBOARD_SHORTCUTS, - }, - }, - }, - [SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: { - screens: { - [SCREENS.PRIVATE_NOTES.LIST]: ROUTES.PRIVATE_NOTES_LIST.route, - [SCREENS.PRIVATE_NOTES.EDIT]: ROUTES.PRIVATE_NOTES_EDIT.route, - }, - }, - [SCREENS.RIGHT_MODAL.REPORT_DETAILS]: { - screens: { - [SCREENS.REPORT_DETAILS.ROOT]: ROUTES.REPORT_WITH_ID_DETAILS.route, - [SCREENS.REPORT_DETAILS.SHARE_CODE]: ROUTES.REPORT_WITH_ID_DETAILS_SHARE_CODE.route, - }, - }, - [SCREENS.RIGHT_MODAL.REPORT_SETTINGS]: { - screens: { - [SCREENS.REPORT_SETTINGS.ROOT]: { - path: ROUTES.REPORT_SETTINGS.route, - }, - [SCREENS.REPORT_SETTINGS.ROOM_NAME]: { - path: ROUTES.REPORT_SETTINGS_ROOM_NAME.route, - }, - [SCREENS.REPORT_SETTINGS.NOTIFICATION_PREFERENCES]: { - path: ROUTES.REPORT_SETTINGS_NOTIFICATION_PREFERENCES.route, - }, - [SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: { - path: ROUTES.REPORT_SETTINGS_WRITE_CAPABILITY.route, - }, - }, - }, - [SCREENS.RIGHT_MODAL.REPORT_WELCOME_MESSAGE]: { - screens: { - [SCREENS.REPORT_WELCOME_MESSAGE_ROOT]: ROUTES.REPORT_WELCOME_MESSAGE.route, - }, - }, - [SCREENS.RIGHT_MODAL.NEW_CHAT]: { - screens: { - [SCREENS.NEW_CHAT.ROOT]: { - path: ROUTES.NEW, - exact: true, - screens: { - [SCREENS.NEW_CHAT.NEW_CHAT]: { - path: ROUTES.NEW_CHAT, - exact: true, - }, - [SCREENS.NEW_CHAT.NEW_ROOM]: { - path: ROUTES.NEW_ROOM, - exact: true, - }, - }, - }, - }, - }, - [SCREENS.RIGHT_MODAL.NEW_TASK]: { - screens: { - [SCREENS.NEW_TASK.ROOT]: ROUTES.NEW_TASK, - [SCREENS.NEW_TASK.TASK_ASSIGNEE_SELECTOR]: ROUTES.NEW_TASK_ASSIGNEE, - [SCREENS.NEW_TASK.TASK_SHARE_DESTINATION_SELECTOR]: ROUTES.NEW_TASK_SHARE_DESTINATION, - [SCREENS.NEW_TASK.DETAILS]: ROUTES.NEW_TASK_DETAILS, - [SCREENS.NEW_TASK.TITLE]: ROUTES.NEW_TASK_TITLE, - [SCREENS.NEW_TASK.DESCRIPTION]: ROUTES.NEW_TASK_DESCRIPTION, - }, - }, - [SCREENS.RIGHT_MODAL.TEACHERS_UNITE]: { - screens: { - [SCREENS.SAVE_THE_WORLD.ROOT]: ROUTES.TEACHERS_UNITE, - [SCREENS.I_KNOW_A_TEACHER]: ROUTES.I_KNOW_A_TEACHER, - [SCREENS.INTRO_SCHOOL_PRINCIPAL]: ROUTES.INTRO_SCHOOL_PRINCIPAL, - [SCREENS.I_AM_A_TEACHER]: ROUTES.I_AM_A_TEACHER, - }, - }, - [SCREENS.RIGHT_MODAL.DETAILS]: { - screens: { - [SCREENS.DETAILS_ROOT]: ROUTES.DETAILS.route, - }, - }, - [SCREENS.RIGHT_MODAL.PROFILE]: { - screens: { - [SCREENS.PROFILE_ROOT]: ROUTES.PROFILE.route, - }, - }, - [SCREENS.RIGHT_MODAL.PARTICIPANTS]: { - screens: { - [SCREENS.REPORT_PARTICIPANTS_ROOT]: ROUTES.REPORT_PARTICIPANTS.route, - }, - }, - [SCREENS.RIGHT_MODAL.ROOM_INVITE]: { - screens: { - [SCREENS.ROOM_INVITE_ROOT]: ROUTES.ROOM_INVITE.route, - }, - }, - [SCREENS.RIGHT_MODAL.ROOM_MEMBERS]: { - screens: { - [SCREENS.ROOM_MEMBERS_ROOT]: ROUTES.ROOM_MEMBERS.route, - }, - }, - [SCREENS.RIGHT_MODAL.MONEY_REQUEST]: { - screens: { - [SCREENS.MONEY_REQUEST.START]: ROUTES.MONEY_REQUEST_START.route, - [SCREENS.MONEY_REQUEST.CREATE]: { - path: ROUTES.MONEY_REQUEST_CREATE.route, - exact: true, - screens: { - distance: { - path: ROUTES.MONEY_REQUEST_CREATE_TAB_DISTANCE.route, - exact: true, - }, - manual: { - path: ROUTES.MONEY_REQUEST_CREATE_TAB_MANUAL.route, - exact: true, - }, - scan: { - path: ROUTES.MONEY_REQUEST_CREATE_TAB_SCAN.route, - exact: true, - }, - }, - }, - [SCREENS.MONEY_REQUEST.STEP_AMOUNT]: ROUTES.MONEY_REQUEST_STEP_AMOUNT.route, - [SCREENS.MONEY_REQUEST.STEP_CATEGORY]: ROUTES.MONEY_REQUEST_STEP_CATEGORY.route, - [SCREENS.MONEY_REQUEST.STEP_CONFIRMATION]: ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.route, - [SCREENS.MONEY_REQUEST.STEP_CURRENCY]: ROUTES.MONEY_REQUEST_STEP_CURRENCY.route, - [SCREENS.MONEY_REQUEST.STEP_DATE]: ROUTES.MONEY_REQUEST_STEP_DATE.route, - [SCREENS.MONEY_REQUEST.STEP_DESCRIPTION]: ROUTES.MONEY_REQUEST_STEP_DESCRIPTION.route, - [SCREENS.MONEY_REQUEST.STEP_DISTANCE]: ROUTES.MONEY_REQUEST_STEP_DISTANCE.route, - [SCREENS.MONEY_REQUEST.STEP_MERCHANT]: ROUTES.MONEY_REQUEST_STEP_MERCHANT.route, - [SCREENS.MONEY_REQUEST.STEP_PARTICIPANTS]: ROUTES.MONEY_REQUEST_STEP_PARTICIPANTS.route, - [SCREENS.MONEY_REQUEST.STEP_SCAN]: ROUTES.MONEY_REQUEST_STEP_SCAN.route, - [SCREENS.MONEY_REQUEST.STEP_TAG]: ROUTES.MONEY_REQUEST_STEP_TAG.route, - [SCREENS.MONEY_REQUEST.STEP_WAYPOINT]: ROUTES.MONEY_REQUEST_STEP_WAYPOINT.route, - [SCREENS.MONEY_REQUEST.ROOT]: { - path: ROUTES.MONEY_REQUEST.route, - exact: true, - screens: { - [SCREENS.MONEY_REQUEST.MANUAL_TAB]: { - path: ROUTES.MONEY_REQUEST_MANUAL_TAB, - exact: true, - }, - [SCREENS.MONEY_REQUEST.SCAN_TAB]: { - path: ROUTES.MONEY_REQUEST_SCAN_TAB, - exact: true, - }, - [SCREENS.MONEY_REQUEST.DISTANCE_TAB]: { - path: ROUTES.MONEY_REQUEST_DISTANCE_TAB.route, - exact: true, - }, - }, - }, - [SCREENS.MONEY_REQUEST.AMOUNT]: ROUTES.MONEY_REQUEST_AMOUNT.route, - [SCREENS.MONEY_REQUEST.STEP_TAX_AMOUNT]: ROUTES.MONEY_REQUEST_STEP_TAX_AMOUNT.route, - [SCREENS.MONEY_REQUEST.STEP_TAX_RATE]: ROUTES.MONEY_REQUEST_STEP_TAX_RATE.route, - [SCREENS.MONEY_REQUEST.PARTICIPANTS]: ROUTES.MONEY_REQUEST_PARTICIPANTS.route, - [SCREENS.MONEY_REQUEST.DATE]: ROUTES.MONEY_REQUEST_DATE.route, - [SCREENS.MONEY_REQUEST.CURRENCY]: ROUTES.MONEY_REQUEST_CURRENCY.route, - [SCREENS.MONEY_REQUEST.DESCRIPTION]: ROUTES.MONEY_REQUEST_DESCRIPTION.route, - [SCREENS.MONEY_REQUEST.CATEGORY]: ROUTES.MONEY_REQUEST_CATEGORY.route, - [SCREENS.MONEY_REQUEST.TAG]: ROUTES.MONEY_REQUEST_TAG.route, - [SCREENS.MONEY_REQUEST.MERCHANT]: ROUTES.MONEY_REQUEST_MERCHANT.route, - [SCREENS.MONEY_REQUEST.RECEIPT]: ROUTES.MONEY_REQUEST_RECEIPT.route, - [SCREENS.MONEY_REQUEST.DISTANCE]: ROUTES.MONEY_REQUEST_DISTANCE.route, - [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: ROUTES.IOU_SEND_ENABLE_PAYMENTS, - [SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: ROUTES.IOU_SEND_ADD_BANK_ACCOUNT, - [SCREENS.IOU_SEND.ADD_DEBIT_CARD]: ROUTES.IOU_SEND_ADD_DEBIT_CARD, - }, - }, - [SCREENS.RIGHT_MODAL.SPLIT_DETAILS]: { - screens: { - [SCREENS.SPLIT_DETAILS.ROOT]: ROUTES.SPLIT_BILL_DETAILS.route, - [SCREENS.SPLIT_DETAILS.EDIT_REQUEST]: ROUTES.EDIT_SPLIT_BILL.route, - [SCREENS.SPLIT_DETAILS.EDIT_CURRENCY]: ROUTES.EDIT_SPLIT_BILL_CURRENCY.route, - }, - }, - [SCREENS.RIGHT_MODAL.TASK_DETAILS]: { - screens: { - [SCREENS.TASK.TITLE]: ROUTES.TASK_TITLE.route, - [SCREENS.TASK.DESCRIPTION]: ROUTES.TASK_DESCRIPTION.route, - [SCREENS.TASK.ASSIGNEE]: ROUTES.TASK_ASSIGNEE.route, - }, - }, - [SCREENS.RIGHT_MODAL.ADD_PERSONAL_BANK_ACCOUNT]: { - screens: { - [SCREENS.ADD_PERSONAL_BANK_ACCOUNT_ROOT]: ROUTES.BANK_ACCOUNT_PERSONAL, - }, - }, - [SCREENS.RIGHT_MODAL.ENABLE_PAYMENTS]: { - screens: { - [SCREENS.ENABLE_PAYMENTS_ROOT]: ROUTES.ENABLE_PAYMENTS, - }, - }, - [SCREENS.RIGHT_MODAL.WALLET_STATEMENT]: { - screens: { - [SCREENS.WALLET_STATEMENT_ROOT]: ROUTES.WALLET_STATEMENT_WITH_DATE, - }, - }, - [SCREENS.RIGHT_MODAL.FLAG_COMMENT]: { - screens: { - [SCREENS.FLAG_COMMENT_ROOT]: ROUTES.FLAG_COMMENT.route, - }, - }, - [SCREENS.RIGHT_MODAL.EDIT_REQUEST]: { - screens: { - [SCREENS.EDIT_REQUEST.ROOT]: ROUTES.EDIT_REQUEST.route, - [SCREENS.EDIT_REQUEST.CURRENCY]: ROUTES.EDIT_CURRENCY_REQUEST.route, - [SCREENS.EDIT_REQUEST.REPORT_FIELD]: ROUTES.EDIT_REPORT_FIELD_REQUEST.route, - }, - }, - [SCREENS.RIGHT_MODAL.SIGN_IN]: { - screens: { - [SCREENS.SIGN_IN_ROOT]: ROUTES.SIGN_IN_MODAL, - }, - }, - [SCREENS.RIGHT_MODAL.REFERRAL]: { - screens: { - [SCREENS.REFERRAL_DETAILS]: ROUTES.REFERRAL_DETAILS_MODAL.route, - }, - }, - ProcessMoneyRequestHold: { - screens: { - ProcessMoneyRequestHold_Root: ROUTES.PROCESS_MONEY_REQUEST_HOLD, - }, - }, - }, - }, - }, - }, -}; - -export default linkingConfig; From 544ee16a55777002c039028f5a6b8a6816a0ef2c Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Mon, 18 Mar 2024 17:20:25 +0100 Subject: [PATCH 07/61] Add getPolicyIDFromNavigationState method --- src/libs/Navigation/Navigation.ts | 11 ++++++++++- .../home/sidebar/SidebarScreen/BaseSidebarScreen.js | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index c55145a5d580..099996d7393a 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -13,13 +13,14 @@ import type {Report} from '@src/types/onyx'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import originalDismissModal from './dismissModal'; import originalDismissModalWithReport from './dismissModalWithReport'; +import getPolicyIDFromState from './getPolicyIDFromState'; import originalGetTopmostReportActionId from './getTopmostReportActionID'; import originalGetTopmostReportId from './getTopmostReportId'; import linkingConfig from './linkingConfig'; import linkTo from './linkTo'; import navigationRef from './navigationRef'; import switchPolicyID from './switchPolicyID'; -import type {NavigationStateRoute, State, StateOrRoute, SwitchPolicyIDParams} from './types'; +import type {NavigationStateRoute, RootStackParamList, State, StateOrRoute, SwitchPolicyIDParams} from './types'; let resolveNavigationIsReadyPromise: () => void; const navigationIsReadyPromise = new Promise((resolve) => { @@ -359,6 +360,13 @@ function navigateWithSwitchPolicyID(params: SwitchPolicyIDParams) { return switchPolicyID(navigationRef.current, params); } +/** + * Returns the currently selected policy ID stored in the navigation state. + */ +function getPolicyIDFromNavigationState() { + return getPolicyIDFromState(navigationRef.getRootState() as State); +} + export default { setShouldPopAllStateOnUP, navigate, @@ -379,6 +387,7 @@ export default { closeFullScreen, navigateWithSwitchPolicyID, resetToHome, + getPolicyIDFromNavigationState, }; export {navigationRef}; diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index 2c2d28a0edbc..9dafeb796fb2 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -1,10 +1,10 @@ import React, {useEffect} from 'react'; import {View} from 'react-native'; import ScreenWrapper from '@components/ScreenWrapper'; -import useActiveWorkspace from '@hooks/useActiveWorkspace'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Browser from '@libs/Browser'; import TopBar from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar'; +import Navigation from '@libs/Navigation/Navigation'; import Performance from '@libs/Performance'; import SidebarLinksData from '@pages/home/sidebar/SidebarLinksData'; import Timing from '@userActions/Timing'; @@ -21,7 +21,7 @@ const startTimer = () => { function BaseSidebarScreen(props) { const styles = useThemeStyles(); - const {activeWorkspaceID} = useActiveWorkspace(); + const activeWorkspaceID = Navigation.getPolicyIDFromNavigationState(); useEffect(() => { Performance.markStart(CONST.TIMING.SIDEBAR_LOADED); Timing.start(CONST.TIMING.SIDEBAR_LOADED, true); From 40cd298ea720e517bd60ea01ae549b48e649687a Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Fri, 22 Mar 2024 18:10:18 +0700 Subject: [PATCH 08/61] fix TS error --- src/libs/actions/IOU.ts | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 8b7f289da381..3a82ea42e965 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -4984,7 +4984,7 @@ function navigateToNextPage(iou: OnyxEntry, iouType: string, repo // If we're adding a receipt, that means the user came from the confirmation page and we need to navigate back to it. if (path.slice(1) === ROUTES.MONEY_REQUEST_RECEIPT.getRoute(iouType, report?.reportID)) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', report.reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType as ValueOf, '1', report?.reportID ?? '1')); return; } @@ -5000,23 +5000,12 @@ function navigateToNextPage(iou: OnyxEntry, iouType: string, repo : (chatReport?.participantAccountIDs ?? []).filter((accountID) => currentUserAccountID !== accountID).map((accountID) => ({accountID, selected: true})); setMoneyRequestParticipants(participants); } - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', report.reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType as ValueOf, '1', report.reportID)); return; } Navigation.navigate(ROUTES.MONEY_REQUEST_PARTICIPANTS.getRoute(iouType)); } -/** - * When the money request or split bill creation flow is initialized via FAB, the reportID is not passed as a navigation - * parameter. - * Gets a report id from the first participant of the IOU object stored in Onyx. - */ -function getIOUReportID(iou?: OnyxTypes.IOU, route?: MoneyRequestRoute): string { - // Disabling this line for safeness as nullish coalescing works only if the value is undefined or null - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - return route?.params.reportID || iou?.participants?.[0]?.reportID || ''; -} - /** * Put money request on HOLD */ @@ -5199,7 +5188,6 @@ export { updateMoneyRequestDescription, replaceReceipt, detachReceipt, - getIOUReportID, editMoneyRequest, putOnHold, unholdRequest, From d284a391048e8e2813c4f33d3677ea05581df87e Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Fri, 22 Mar 2024 18:14:18 +0700 Subject: [PATCH 09/61] fix TS error --- src/libs/actions/IOU.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 3a82ea42e965..e2ea7a8cbd10 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -63,8 +63,6 @@ import * as CachedPDFPaths from './CachedPDFPaths'; import * as Policy from './Policy'; import * as Report from './Report'; -type MoneyRequestRoute = StackScreenProps['route']; - type IOURequestType = ValueOf; type OneOnOneIOUReport = OnyxTypes.Report | undefined | null; From 40c5970c9013f8bfc010cfdfd6287ce6a21f6cc9 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Fri, 22 Mar 2024 18:15:00 +0700 Subject: [PATCH 10/61] fix lint --- src/libs/actions/IOU.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index e2ea7a8cbd10..94c454fba38e 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1,5 +1,4 @@ import type {ParamListBase, StackNavigationState} from '@react-navigation/native'; -import type {StackScreenProps} from '@react-navigation/stack'; import {format} from 'date-fns'; import fastMerge from 'expensify-common/lib/fastMerge'; import Str from 'expensify-common/lib/str'; @@ -45,11 +44,10 @@ import type {OptimisticChatReport, OptimisticCreatedReportAction, OptimisticIOUR import * as TransactionUtils from '@libs/TransactionUtils'; import * as UserUtils from '@libs/UserUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; -import type {MoneyRequestNavigatorParamList, NavigationPartialRoute} from '@navigation/types'; +import type {NavigationPartialRoute} from '@navigation/types'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import type {Participant, Split} from '@src/types/onyx/IOU'; import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; From eb11d74f2ca7fea0cbb2dab78a34a5bb495345da Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Fri, 22 Mar 2024 16:26:52 +0100 Subject: [PATCH 11/61] Move getPolicyIDFromNavigationState to PolicyUtils --- src/libs/Navigation/Navigation.ts | 11 +---------- src/libs/PolicyUtils.ts | 12 +++++++++++- .../home/sidebar/SidebarScreen/BaseSidebarScreen.js | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index f6d871724291..d57d0272738b 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -13,14 +13,13 @@ import type {Report} from '@src/types/onyx'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import originalDismissModal from './dismissModal'; import originalDismissModalWithReport from './dismissModalWithReport'; -import getPolicyIDFromState from './getPolicyIDFromState'; import originalGetTopmostReportActionId from './getTopmostReportActionID'; import originalGetTopmostReportId from './getTopmostReportId'; import linkingConfig from './linkingConfig'; import linkTo from './linkTo'; import navigationRef from './navigationRef'; import switchPolicyID from './switchPolicyID'; -import type {NavigationStateRoute, RootStackParamList, State, StateOrRoute, SwitchPolicyIDParams} from './types'; +import type {NavigationStateRoute, State, StateOrRoute, SwitchPolicyIDParams} from './types'; let resolveNavigationIsReadyPromise: () => void; const navigationIsReadyPromise = new Promise((resolve) => { @@ -360,13 +359,6 @@ function navigateWithSwitchPolicyID(params: SwitchPolicyIDParams) { return switchPolicyID(navigationRef.current, params); } -/** - * Returns the currently selected policy ID stored in the navigation state. - */ -function getPolicyIDFromNavigationState() { - return getPolicyIDFromState(navigationRef.getRootState() as State); -} - export default { setShouldPopAllStateOnUP, navigate, @@ -387,7 +379,6 @@ export default { closeFullScreen, navigateWithSwitchPolicyID, resetToHome, - getPolicyIDFromNavigationState, }; export {navigationRef}; diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 7717513d3f59..687f39fdf7c5 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -8,7 +8,9 @@ import type {PersonalDetailsList, Policy, PolicyCategories, PolicyMembers, Polic import type {PolicyFeatureName} from '@src/types/onyx/Policy'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import Navigation from './Navigation/Navigation'; +import getPolicyIDFromState from './Navigation/getPolicyIDFromState'; +import Navigation, {navigationRef} from './Navigation/Navigation'; +import type {RootStackParamList, State} from './Navigation/types'; type MemberEmailsToAccountIDs = Record; type UnitRate = {rate: number}; @@ -297,6 +299,13 @@ function isPolicyFeatureEnabled(policy: OnyxEntry | EmptyObject, feature return Boolean(policy?.[featureName]); } +/** + * Get the currently selected policy ID stored in the navigation state. + */ +function getPolicyIDFromNavigationState() { + return getPolicyIDFromState(navigationRef.getRootState() as State); +} + export { getActivePolicies, hasAccountingConnections, @@ -332,6 +341,7 @@ export { hasTaxRateError, getTaxByID, hasPolicyCategoriesError, + getPolicyIDFromNavigationState, }; export type {MemberEmailsToAccountIDs}; diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index 9dafeb796fb2..d34f821b4b9b 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -4,8 +4,8 @@ import ScreenWrapper from '@components/ScreenWrapper'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Browser from '@libs/Browser'; import TopBar from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar'; -import Navigation from '@libs/Navigation/Navigation'; import Performance from '@libs/Performance'; +import {getPolicyIDFromNavigationState} from '@libs/PolicyUtils'; import SidebarLinksData from '@pages/home/sidebar/SidebarLinksData'; import Timing from '@userActions/Timing'; import CONST from '@src/CONST'; @@ -21,7 +21,7 @@ const startTimer = () => { function BaseSidebarScreen(props) { const styles = useThemeStyles(); - const activeWorkspaceID = Navigation.getPolicyIDFromNavigationState(); + const activeWorkspaceID = getPolicyIDFromNavigationState(); useEffect(() => { Performance.markStart(CONST.TIMING.SIDEBAR_LOADED); Timing.start(CONST.TIMING.SIDEBAR_LOADED, true); From 927004f737e726f2cc055a0a2f90951eb8caed9b Mon Sep 17 00:00:00 2001 From: Rohan Sasne Date: Mon, 25 Mar 2024 08:21:40 +0530 Subject: [PATCH 12/61] Fix central pane change --- .../Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts index 95233bfed079..f45e47173335 100755 --- a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts @@ -19,6 +19,9 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial> = SCREENS.SETTINGS.PROFILE.ADDRESS, SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY, SCREENS.SETTINGS.SHARE_CODE, + SCREENS.SETTINGS.EXIT_SURVEY.REASON, + SCREENS.SETTINGS.EXIT_SURVEY.RESPONSE, + SCREENS.SETTINGS.EXIT_SURVEY.CONFIRM ], [SCREENS.SETTINGS.PREFERENCES.ROOT]: [SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE, SCREENS.SETTINGS.PREFERENCES.LANGUAGE, SCREENS.SETTINGS.PREFERENCES.THEME], [SCREENS.SETTINGS.WALLET.ROOT]: [ From 0dc5f633635c5798352e63df6da170987d675d6b Mon Sep 17 00:00:00 2001 From: Rohan Sasne Date: Mon, 25 Mar 2024 08:34:56 +0530 Subject: [PATCH 13/61] Fix Prettier --- .../Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts index f45e47173335..4ec955784d92 100755 --- a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts @@ -21,7 +21,7 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial> = SCREENS.SETTINGS.SHARE_CODE, SCREENS.SETTINGS.EXIT_SURVEY.REASON, SCREENS.SETTINGS.EXIT_SURVEY.RESPONSE, - SCREENS.SETTINGS.EXIT_SURVEY.CONFIRM + SCREENS.SETTINGS.EXIT_SURVEY.CONFIRM, ], [SCREENS.SETTINGS.PREFERENCES.ROOT]: [SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE, SCREENS.SETTINGS.PREFERENCES.LANGUAGE, SCREENS.SETTINGS.PREFERENCES.THEME], [SCREENS.SETTINGS.WALLET.ROOT]: [ From 7304fbe01ae399ab49cca48927c9f028c94937d5 Mon Sep 17 00:00:00 2001 From: gaber Date: Mon, 25 Mar 2024 21:16:50 +0200 Subject: [PATCH 14/61] update MentionUserRenderer.tsx display text --- .../HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx index 0327b6bc6f56..d3376a798a8b 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx @@ -59,8 +59,8 @@ function MentionUserRenderer({style, tnode, TDefaultRenderer, currentUserPersona if (!isEmpty(htmlAttribAccountID)) { const user = personalDetails[htmlAttribAccountID]; accountID = parseInt(htmlAttribAccountID, 10); - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - displayNameOrLogin = PersonalDetailsUtils.getDisplayNameOrDefault(user, LocalePhoneNumber.formatPhoneNumber(user?.login ?? '')); + displayNameOrLogin = LocalePhoneNumber.formatPhoneNumber(user?.login ?? '') || PersonalDetailsUtils.getDisplayNameOrDefault(user); + displayNameOrLogin = Str.removeSMSDomain(getMentionDisplayText(displayNameOrLogin, htmlAttributeAccountID, user?.login ?? '')); navigationRoute = ROUTES.PROFILE.getRoute(htmlAttribAccountID); } else if ('data' in tnodeClone && !isEmptyObject(tnodeClone.data)) { // We need to remove the LTR unicode and leading @ from data as it is not part of the login From eda996e5232c9d0a1dc6c8dc4a19af933a0cf3d0 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Tue, 26 Mar 2024 15:25:21 +0800 Subject: [PATCH 15/61] fix anchor text can't show both underline and line through on iOS --- .../HTMLRenderers/AnchorRenderer.tsx | 25 +++++++++++++++++-- src/styles/utils/textDecorationLine.ts | 4 +++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.tsx index 465a4f747bcb..d918007e5750 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.tsx +++ b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.tsx @@ -55,6 +55,9 @@ function AnchorRenderer({tnode, style, key}: AnchorRendererProps) { ); } + const hasStrikethroughStyle = 'textDecorationLine' in parentStyle && parentStyle.textDecorationLine === 'line-through'; + const textDecorationLineStyle = hasStrikethroughStyle ? styles.underlineLineThrough : {}; + return ( Link.openLink(attrHref, environmentURL, isAttachment) : undefined} > - + { + if (props.childTnode.tagName === 'br') { + return {'\n'}; + } + if (props.childTnode.type === 'text') { + return ( + + {props.childTnode.data} + + ); + } + return props.childElement; + }} + /> ); } diff --git a/src/styles/utils/textDecorationLine.ts b/src/styles/utils/textDecorationLine.ts index e5f079150e78..5e830cbf08c1 100644 --- a/src/styles/utils/textDecorationLine.ts +++ b/src/styles/utils/textDecorationLine.ts @@ -5,4 +5,8 @@ export default { textDecorationLine: 'line-through', textDecorationStyle: 'solid', }, + underlineLineThrough: { + textDecorationLine: 'underline line-through', + textDecorationStyle: 'solid', + }, } satisfies Record; From 073a059ed7c3eaa457c5c7f48d0e6b6b9a7e1a78 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 26 Mar 2024 22:35:53 +0700 Subject: [PATCH 16/61] update route --- src/ROUTES.ts | 4 ++-- src/libs/actions/IOU.ts | 4 ++-- src/pages/iou/request/step/IOURequestStepAmount.js | 2 +- src/pages/iou/request/step/IOURequestStepCurrency.js | 2 +- src/pages/iou/request/step/IOURequestStepDistance.js | 2 +- src/pages/iou/request/step/IOURequestStepParticipants.js | 2 +- src/pages/iou/request/step/IOURequestStepScan/index.js | 2 +- src/pages/iou/request/step/IOURequestStepScan/index.native.js | 2 +- src/pages/iou/request/step/IOURequestStepTaxAmountPage.js | 2 +- .../MoneyRequestParticipantsPage.js | 2 +- src/pages/iou/steps/NewRequestAmountPage.js | 4 ++-- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 6d3f78864fa5..4e8b746cee70 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -306,8 +306,8 @@ const ROUTES = { `create/${iouType}/start/${transactionID}/${reportID}` as const, }, MONEY_REQUEST_STEP_CONFIRMATION: { - route: 'create/:iouType/confirmation/:transactionID/:reportID', - getRoute: (iouType: ValueOf, transactionID: string, reportID: string) => `create/${iouType}/confirmation/${transactionID}/${reportID}` as const, + route: ':action/:iouType/confirmation/:transactionID/:reportID', + getRoute: (action: ValueOf, iouType: ValueOf, transactionID: string, reportID: string) => `${action}/${iouType}/confirmation/${transactionID}/${reportID}` as const, }, MONEY_REQUEST_STEP_AMOUNT: { route: 'create/:iouType/amount/:transactionID/:reportID', diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 94c454fba38e..85d82e54fa71 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -4980,7 +4980,7 @@ function navigateToNextPage(iou: OnyxEntry, iouType: string, repo // If we're adding a receipt, that means the user came from the confirmation page and we need to navigate back to it. if (path.slice(1) === ROUTES.MONEY_REQUEST_RECEIPT.getRoute(iouType, report?.reportID)) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType as ValueOf, '1', report?.reportID ?? '1')); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, '1', report?.reportID ?? '1')); return; } @@ -4996,7 +4996,7 @@ function navigateToNextPage(iou: OnyxEntry, iouType: string, repo : (chatReport?.participantAccountIDs ?? []).filter((accountID) => currentUserAccountID !== accountID).map((accountID) => ({accountID, selected: true})); setMoneyRequestParticipants(participants); } - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType as ValueOf, '1', report.reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, '1', report.reportID)); return; } Navigation.navigate(ROUTES.MONEY_REQUEST_PARTICIPANTS.getRoute(iouType)); diff --git a/src/pages/iou/request/step/IOURequestStepAmount.js b/src/pages/iou/request/step/IOURequestStepAmount.js index 9fdd2bea24f4..781bcbda0dbb 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.js +++ b/src/pages/iou/request/step/IOURequestStepAmount.js @@ -145,7 +145,7 @@ function IOURequestStepAmount({ // to the confirm step. if (report.reportID) { IOU.setMoneyRequestParticipantsFromReport(transactionID, report); - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, transactionID, reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)); return; } diff --git a/src/pages/iou/request/step/IOURequestStepCurrency.js b/src/pages/iou/request/step/IOURequestStepCurrency.js index 43e4e9bf0eaa..4ce5c483bde7 100644 --- a/src/pages/iou/request/step/IOURequestStepCurrency.js +++ b/src/pages/iou/request/step/IOURequestStepCurrency.js @@ -66,7 +66,7 @@ function IOURequestStepCurrency({ // are only able to handle one backTo param at a time and the user needs to go back to the amount page before going back // to the confirmation page if (pageIndex === 'confirm') { - const routeToAmountPageWithConfirmationAsBackTo = getUrlWithBackToParam(backTo, `/${ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, transactionID, reportID)}`); + const routeToAmountPageWithConfirmationAsBackTo = getUrlWithBackToParam(backTo, `/${ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)}`); Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo); return; } diff --git a/src/pages/iou/request/step/IOURequestStepDistance.js b/src/pages/iou/request/step/IOURequestStepDistance.js index dad610cbc636..302494d1f8b5 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.js +++ b/src/pages/iou/request/step/IOURequestStepDistance.js @@ -135,7 +135,7 @@ function IOURequestStepDistance({ // to the confirm step. if (report.reportID) { IOU.setMoneyRequestParticipantsFromReport(transactionID, report); - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, transactionID, reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)); return; } diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.js b/src/pages/iou/request/step/IOURequestStepParticipants.js index 5ca465d8fb78..7ccbdb18ee03 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.js +++ b/src/pages/iou/request/step/IOURequestStepParticipants.js @@ -128,7 +128,7 @@ function IOURequestStepParticipants({ IOU.setMoneyRequestTag(transactionID, ''); IOU.setMoneyRequestCategory(transactionID, ''); - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(nextStepIOUType, transactionID, selectedReportID.current || reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, nextStepIOUType, transactionID, selectedReportID.current || reportID)); }, [iouType, transactionID, reportID], ); diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.js b/src/pages/iou/request/step/IOURequestStepScan/index.js index 6bf517c30eb0..d2fc54ffbe4c 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.js +++ b/src/pages/iou/request/step/IOURequestStepScan/index.js @@ -187,7 +187,7 @@ function IOURequestStepScan({ // If the transaction was created from the + menu from the composer inside of a chat, the participants can automatically // be added to the transaction (taken from the chat report participants) and then the person is taken to the confirmation step. IOU.setMoneyRequestParticipantsFromReport(transactionID, report); - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, transactionID, reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)); }, [iouType, report, reportID, transactionID, isFromGlobalCreate, backTo]); const updateScanAndNavigate = useCallback( diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.js b/src/pages/iou/request/step/IOURequestStepScan/index.native.js index 03eb12fc3b03..7c57c7483fe7 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.js +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.js @@ -195,7 +195,7 @@ function IOURequestStepScan({ // If the transaction was created from the + menu from the composer inside of a chat, the participants can automatically // be added to the transaction (taken from the chat report participants) and then the person is taken to the confirmation step. IOU.setMoneyRequestParticipantsFromReport(transactionID, report); - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, transactionID, reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)); }, [iouType, report, reportID, transactionID, isFromGlobalCreate, backTo]); const updateScanAndNavigate = useCallback( diff --git a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.js b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.js index 7a75e9f48805..1c3e4197a146 100644 --- a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.js +++ b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.js @@ -133,7 +133,7 @@ function IOURequestStepTaxAmountPage({ if (report.reportID) { // TODO: Is this really needed at all? IOU.setMoneyRequestParticipantsFromReport(transactionID, report); - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, transactionID, reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)); return; } diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js index 9b8ed32fc197..b5d11faac6c4 100644 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsPage.js @@ -87,7 +87,7 @@ function MoneyRequestParticipantsPage({iou, selectedTab, route, transaction}) { const navigateToConfirmationStep = (moneyRequestType) => { IOU.setMoneyRequestId(moneyRequestType); - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(moneyRequestType, lodashGet(transaction, 'transactionID', 1), reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, moneyRequestType, lodashGet(transaction, 'transactionID', 1), reportID)); }; const navigateBack = useCallback((forceFallback = false) => { diff --git a/src/pages/iou/steps/NewRequestAmountPage.js b/src/pages/iou/steps/NewRequestAmountPage.js index 007a63bdb713..f4a38d23c861 100644 --- a/src/pages/iou/steps/NewRequestAmountPage.js +++ b/src/pages/iou/steps/NewRequestAmountPage.js @@ -113,7 +113,7 @@ function NewRequestAmountPage({route, iou, report, selectedTab}) { }, [iou.participants, iou.amount, iou.id, isEditing, iouType, reportID, isDistanceRequestTab]); const navigateBack = () => { - Navigation.goBack(isEditing ? ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID) : ROUTES.HOME); + Navigation.goBack(isEditing ? ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, '1', reportID) : ROUTES.HOME); }; const navigateToCurrencySelectionPage = () => { @@ -134,7 +134,7 @@ function NewRequestAmountPage({route, iou, report, selectedTab}) { IOU.setMoneyRequestCurrency(currency); if (isEditing) { - Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, '1', reportID)); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, '1', reportID)); return; } From 8594d01bd4564ab30b8dd9576680ef7abbdccc10 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 26 Mar 2024 23:48:07 +0700 Subject: [PATCH 17/61] fix lint --- src/pages/iou/request/step/IOURequestStepCurrency.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/iou/request/step/IOURequestStepCurrency.js b/src/pages/iou/request/step/IOURequestStepCurrency.js index 4ce5c483bde7..7e3d5a1b7079 100644 --- a/src/pages/iou/request/step/IOURequestStepCurrency.js +++ b/src/pages/iou/request/step/IOURequestStepCurrency.js @@ -14,6 +14,7 @@ import Navigation from '@libs/Navigation/Navigation'; import * as IOU from '@userActions/IOU'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES, {getUrlWithBackToParam} from '@src/ROUTES'; +import CONST from '@src/CONST'; import IOURequestStepRoutePropTypes from './IOURequestStepRoutePropTypes'; import StepScreenWrapper from './StepScreenWrapper'; import withFullTransactionOrNotFound from './withFullTransactionOrNotFound'; From d835235478e61c1ace6bfaf15cb10d37736dc6cc Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 26 Mar 2024 23:56:32 +0700 Subject: [PATCH 18/61] lint fix --- src/ROUTES.ts | 3 ++- src/pages/iou/request/step/IOURequestStepCurrency.js | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index e6dc082c60c8..06182f944979 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -307,7 +307,8 @@ const ROUTES = { }, MONEY_REQUEST_STEP_CONFIRMATION: { route: ':action/:iouType/confirmation/:transactionID/:reportID', - getRoute: (action: ValueOf, iouType: ValueOf, transactionID: string, reportID: string) => `${action}/${iouType}/confirmation/${transactionID}/${reportID}` as const, + getRoute: (action: ValueOf, iouType: ValueOf, transactionID: string, reportID: string) => + `${action}/${iouType}/confirmation/${transactionID}/${reportID}` as const, }, MONEY_REQUEST_STEP_AMOUNT: { route: 'create/:iouType/amount/:transactionID/:reportID', diff --git a/src/pages/iou/request/step/IOURequestStepCurrency.js b/src/pages/iou/request/step/IOURequestStepCurrency.js index 7e3d5a1b7079..f6a39dfbf216 100644 --- a/src/pages/iou/request/step/IOURequestStepCurrency.js +++ b/src/pages/iou/request/step/IOURequestStepCurrency.js @@ -12,9 +12,9 @@ import compose from '@libs/compose'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as IOU from '@userActions/IOU'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES, {getUrlWithBackToParam} from '@src/ROUTES'; -import CONST from '@src/CONST'; import IOURequestStepRoutePropTypes from './IOURequestStepRoutePropTypes'; import StepScreenWrapper from './StepScreenWrapper'; import withFullTransactionOrNotFound from './withFullTransactionOrNotFound'; @@ -67,7 +67,10 @@ function IOURequestStepCurrency({ // are only able to handle one backTo param at a time and the user needs to go back to the amount page before going back // to the confirmation page if (pageIndex === 'confirm') { - const routeToAmountPageWithConfirmationAsBackTo = getUrlWithBackToParam(backTo, `/${ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)}`); + const routeToAmountPageWithConfirmationAsBackTo = getUrlWithBackToParam( + backTo, + `/${ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)}`, + ); Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo); return; } From d65a8f306201d12577c65d04f50754003130b377 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 27 Mar 2024 13:58:25 +0800 Subject: [PATCH 19/61] don't optimistically add the violation if it's a partial transaction --- src/libs/actions/IOU.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index b67e44fcf5ad..51656e2ea405 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -807,16 +807,18 @@ function buildOnyxDataForMoneyRequest( if (!policy || !PolicyUtils.isPaidGroupPolicy(policy)) { return [optimisticData, successData, failureData]; } + const isPartialTransaction = TransactionUtils.isMerchantMissing(transaction) && TransactionUtils.isAmountMissing(transaction); + if (!isPartialTransaction) { + const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(transaction, [], !!policy.requiresTag, policyTagList ?? {}, !!policy.requiresCategory, policyCategories ?? {}); - const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(transaction, [], !!policy.requiresTag, policyTagList ?? {}, !!policy.requiresCategory, policyCategories ?? {}); - - if (violationsOnyxData) { - optimisticData.push(violationsOnyxData); - failureData.push({ - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`, - value: [], - }); + if (violationsOnyxData) { + optimisticData.push(violationsOnyxData); + failureData.push({ + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`, + value: [], + }); + } } return [optimisticData, successData, failureData]; @@ -1698,7 +1700,8 @@ function getUpdateMoneyRequestParams( }); } - if (policy && PolicyUtils.isPaidGroupPolicy(policy) && updatedTransaction) { + const isPartialTransaction = TransactionUtils.isMerchantMissing(updatedTransaction) && TransactionUtils.isAmountMissing(updatedTransaction); + if (policy && PolicyUtils.isPaidGroupPolicy(policy) && updatedTransaction && !isPartialTransaction) { const currentTransactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? []; optimisticData.push( ViolationsUtils.getViolationsOnyxData( From f9fc96d8a2a857834c1a82561c70250ddd78b600 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 27 Mar 2024 18:31:45 +0800 Subject: [PATCH 20/61] move the partial transaciton check to getViolationsOnyxData --- src/libs/Violations/ViolationsUtils.ts | 8 +++- src/libs/actions/IOU.ts | 66 +++++++++++++------------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index fe2e5af537a7..be8fe79445dc 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -2,6 +2,7 @@ import reject from 'lodash/reject'; import Onyx from 'react-native-onyx'; import type {OnyxUpdate} from 'react-native-onyx'; import type {Phrase, PhraseParameters} from '@libs/Localize'; +import * as TransactionUtils from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -119,7 +120,12 @@ const ViolationsUtils = { policyTagList: PolicyTagList, policyRequiresCategories: boolean, policyCategories: PolicyCategories, - ): OnyxUpdate { + ): OnyxUpdate | null { + const isPartialTransaction = TransactionUtils.isMerchantMissing(updatedTransaction) && TransactionUtils.isAmountMissing(updatedTransaction); + if (isPartialTransaction) { + return null; + } + let newTransactionViolations = [...transactionViolations]; // Calculate client-side category violations diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 51656e2ea405..f6bd73afd082 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -807,18 +807,16 @@ function buildOnyxDataForMoneyRequest( if (!policy || !PolicyUtils.isPaidGroupPolicy(policy)) { return [optimisticData, successData, failureData]; } - const isPartialTransaction = TransactionUtils.isMerchantMissing(transaction) && TransactionUtils.isAmountMissing(transaction); - if (!isPartialTransaction) { - const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(transaction, [], !!policy.requiresTag, policyTagList ?? {}, !!policy.requiresCategory, policyCategories ?? {}); - if (violationsOnyxData) { - optimisticData.push(violationsOnyxData); - failureData.push({ - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`, - value: [], - }); - } + const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(transaction, [], !!policy.requiresTag, policyTagList ?? {}, !!policy.requiresCategory, policyCategories ?? {}); + + if (violationsOnyxData) { + optimisticData.push(violationsOnyxData); + failureData.push({ + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`, + value: [], + }); } return [optimisticData, successData, failureData]; @@ -1700,24 +1698,24 @@ function getUpdateMoneyRequestParams( }); } - const isPartialTransaction = TransactionUtils.isMerchantMissing(updatedTransaction) && TransactionUtils.isAmountMissing(updatedTransaction); - if (policy && PolicyUtils.isPaidGroupPolicy(policy) && updatedTransaction && !isPartialTransaction) { + if (policy && PolicyUtils.isPaidGroupPolicy(policy) && updatedTransaction) { const currentTransactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? []; - optimisticData.push( - ViolationsUtils.getViolationsOnyxData( - updatedTransaction, - currentTransactionViolations, - !!policy.requiresTag, - policyTagList ?? {}, - !!policy.requiresCategory, - policyCategories ?? {}, - ), + const updatedViolationsOnyxData = ViolationsUtils.getViolationsOnyxData( + updatedTransaction, + currentTransactionViolations, + !!policy.requiresTag, + policyTagList ?? {}, + !!policy.requiresCategory, + policyCategories ?? {}, ); - failureData.push({ - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, - value: currentTransactionViolations, - }); + if (updatedViolationsOnyxData) { + optimisticData.push(updatedViolationsOnyxData); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, + value: currentTransactionViolations, + }); + } } // Reset the transaction thread to its original state @@ -3508,12 +3506,14 @@ function editRegularMoneyRequest( !!policy.requiresCategory, policyCategories, ); - optimisticData.push(updatedViolationsOnyxData); - failureData.push({ - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, - value: currentTransactionViolations, - }); + if (updatedViolationsOnyxData) { + optimisticData.push(updatedViolationsOnyxData); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, + value: currentTransactionViolations, + }); + } } // STEP 6: Call the API endpoint From bdcdc471543de25c3107e3e5c9c2996b21e60436 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 27 Mar 2024 18:37:25 +0800 Subject: [PATCH 21/61] null safety --- tests/unit/ViolationUtilsTest.ts | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/unit/ViolationUtilsTest.ts b/tests/unit/ViolationUtilsTest.ts index 354a90802077..4c9a2c344363 100644 --- a/tests/unit/ViolationUtilsTest.ts +++ b/tests/unit/ViolationUtilsTest.ts @@ -57,7 +57,7 @@ describe('getViolationsOnyxData', () => { {name: 'receiptRequired', type: 'violation'}, ]; const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(expect.arrayContaining(transactionViolations)); + expect(result?.value).toEqual(expect.arrayContaining(transactionViolations)); }); describe('policyRequiresCategories', () => { @@ -70,18 +70,18 @@ describe('getViolationsOnyxData', () => { it('should add missingCategory violation if no category is included', () => { transaction.category = undefined; const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); + expect(result?.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); }); it('should add categoryOutOfPolicy violation when category is not in policy', () => { transaction.category = 'Bananas'; const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); + expect(result?.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); }); it('should not include a categoryOutOfPolicy violation when category is in policy', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).not.toContainEqual(categoryOutOfPolicyViolation); + expect(result?.value).not.toContainEqual(categoryOutOfPolicyViolation); }); it('should add categoryOutOfPolicy violation to existing violations if they exist', () => { @@ -93,7 +93,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); + expect(result?.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); }); it('should add missingCategory violation to existing violations if they exist', () => { @@ -105,7 +105,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); + expect(result?.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); }); }); @@ -117,8 +117,8 @@ describe('getViolationsOnyxData', () => { it('should not add any violations when categories are not required', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).not.toContainEqual([categoryOutOfPolicyViolation]); - expect(result.value).not.toContainEqual([missingCategoryViolation]); + expect(result?.value).not.toContainEqual([categoryOutOfPolicyViolation]); + expect(result?.value).not.toContainEqual([missingCategoryViolation]); }); }); @@ -142,7 +142,7 @@ describe('getViolationsOnyxData', () => { it("shouldn't update the transactionViolations if the policy requires tags and the transaction has a tag from the policy", () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(transactionViolations); + expect(result?.value).toEqual(transactionViolations); }); it('should add a missingTag violation if none is provided and policy requires tags', () => { @@ -150,7 +150,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation}])); + expect(result?.value).toEqual(expect.arrayContaining([{...missingTagViolation}])); }); it('should add a tagOutOfPolicy violation when policy requires tags and tag is not in the policy', () => { @@ -158,7 +158,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual([]); + expect(result?.value).toEqual([]); }); it('should add tagOutOfPolicy violation to existing violations if transaction has tag that is not in the policy', () => { @@ -170,7 +170,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(expect.arrayContaining([{...tagOutOfPolicyViolation}, ...transactionViolations])); + expect(result?.value).toEqual(expect.arrayContaining([{...tagOutOfPolicyViolation}, ...transactionViolations])); }); it('should add missingTag violation to existing violations if transaction does not have a tag', () => { @@ -182,7 +182,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation}, ...transactionViolations])); + expect(result?.value).toEqual(expect.arrayContaining([{...missingTagViolation}, ...transactionViolations])); }); }); @@ -194,8 +194,8 @@ describe('getViolationsOnyxData', () => { it('should not add any violations when tags are not required', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).not.toContainEqual([tagOutOfPolicyViolation]); - expect(result.value).not.toContainEqual([missingTagViolation]); + expect(result?.value).not.toContainEqual([tagOutOfPolicyViolation]); + expect(result?.value).not.toContainEqual([missingTagViolation]); }); }); describe('policy has multi level tags', () => { @@ -248,31 +248,31 @@ describe('getViolationsOnyxData', () => { // Test case where transaction has no tags let result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual([someTagLevelsRequiredViolation]); + expect(result?.value).toEqual([someTagLevelsRequiredViolation]); // Test case where transaction has 1 tag transaction.tag = 'Accounting'; someTagLevelsRequiredViolation.data = {errorIndexes: [1, 2]}; result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual([someTagLevelsRequiredViolation]); + expect(result?.value).toEqual([someTagLevelsRequiredViolation]); // Test case where transaction has 2 tags transaction.tag = 'Accounting::Project1'; someTagLevelsRequiredViolation.data = {errorIndexes: [1]}; result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual([someTagLevelsRequiredViolation]); + expect(result?.value).toEqual([someTagLevelsRequiredViolation]); // Test case where transaction has all tags transaction.tag = 'Accounting:Africa:Project1'; result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual([]); + expect(result?.value).toEqual([]); }); it('should return tagOutOfPolicy when a tag is not enabled in the policy but is set in the transaction', () => { policyTags.Department.tags.Accounting.enabled = false; transaction.tag = 'Accounting:Africa:Project1'; const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); const violation = {...tagOutOfPolicyViolation, data: {tagName: 'Department'}}; - expect(result.value).toEqual([violation]); + expect(result?.value).toEqual([violation]); }); }); }); From 39b8c46885695e70983ea14d0e4177835d0c9f80 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 27 Mar 2024 18:39:36 +0800 Subject: [PATCH 22/61] add test --- tests/unit/ViolationUtilsTest.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/unit/ViolationUtilsTest.ts b/tests/unit/ViolationUtilsTest.ts index 4c9a2c344363..7da8352cdb53 100644 --- a/tests/unit/ViolationUtilsTest.ts +++ b/tests/unit/ViolationUtilsTest.ts @@ -60,6 +60,16 @@ describe('getViolationsOnyxData', () => { expect(result?.value).toEqual(expect.arrayContaining(transactionViolations)); }); + it('should not add violation when the transaction is partial', () => { + const partialTransaction = {...transaction, amount: 0, merchant: ''}; + transactionViolations = [ + {name: 'duplicatedTransaction', type: 'violation'}, + {name: 'receiptRequired', type: 'violation'}, + ]; + const result = ViolationsUtils.getViolationsOnyxData(partialTransaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); + expect(result).toBeNull(); + }); + describe('policyRequiresCategories', () => { beforeEach(() => { policyRequiresCategories = true; From d2b282228a3f901094c4835df4f3c43d92ed3205 Mon Sep 17 00:00:00 2001 From: Andrii Bondarenko Date: Wed, 27 Mar 2024 21:27:04 +0200 Subject: [PATCH 23/61] nested quote for editing message --- package-lock.json | 25 +++++++++++++------------ package.json | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61d6a27821cd..2c6f56889ac4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#615f4a8662cd1abea9fdeee4d04847197c5e36ae", + "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#1247a822328011083a13abc769ba1911c3586338", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.10.1", @@ -23087,9 +23087,9 @@ } }, "node_modules/classnames": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.4.0.tgz", - "integrity": "sha512-lWxiIlphgAhTLN657pwU/ofFxsUTOWc2CRIFeoV5st0MGRJHStUnWIUJgDHxjUO/F0mXzGufXIM4Lfu/8h+MpA==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.0.tgz", + "integrity": "sha512-FQuRlyKinxrb5gwJlfVASbSrDlikDJ07426TrfPsdGLvtochowmkbnSFdQGJ2aoXrSetq5KqGV9emvWpy+91xA==" }, "node_modules/clean-css": { "version": "5.3.2", @@ -27370,20 +27370,20 @@ }, "node_modules/expensify-common": { "version": "1.0.0", - "resolved": "git+ssh://git@github.com/Expensify/expensify-common.git#615f4a8662cd1abea9fdeee4d04847197c5e36ae", - "integrity": "sha512-k/SmW3EBR+gxFkJP/59LJsmBKjnKR07XS30yk/GkQ0lIfyYkNmFJ0dWm/S/54ezFweezR7MDaQ3zGc45Mb/U5A==", + "resolved": "git+ssh://git@github.com/Expensify/expensify-common.git#1247a822328011083a13abc769ba1911c3586338", + "integrity": "sha512-YqFwbL3B5XzdQ+4wmZqWcdAbRerGvP0ZvcJV2YTHETxlZdjc39AZ2gviaJhqmz8E4kTQIfgO6ii3n4bWSYKt5A==", "license": "MIT", "dependencies": { - "classnames": "2.4.0", + "classnames": "2.5.0", "clipboard": "2.0.11", - "html-entities": "^2.4.0", + "html-entities": "^2.5.2", "jquery": "3.6.0", "localforage": "^1.10.0", "lodash": "4.17.21", "prop-types": "15.8.1", "react": "16.12.0", "react-dom": "16.12.0", - "semver": "^7.5.2", + "semver": "^7.6.0", "simply-deferred": "git+https://github.com/Expensify/simply-deferred.git#77a08a95754660c7bd6e0b6979fdf84e8e831bf5", "ua-parser-js": "^1.0.37", "underscore": "1.13.6" @@ -29528,7 +29528,9 @@ } }, "node_modules/html-entities": { - "version": "2.4.0", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", "funding": [ { "type": "github", @@ -29538,8 +29540,7 @@ "type": "patreon", "url": "https://patreon.com/mdevils" } - ], - "license": "MIT" + ] }, "node_modules/html-escaper": { "version": "2.0.2", diff --git a/package.json b/package.json index 92a6b9cde5e1..68268f737c7d 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#615f4a8662cd1abea9fdeee4d04847197c5e36ae", + "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#1247a822328011083a13abc769ba1911c3586338", "expo": "^50.0.3", "expo-av": "~13.10.4", "expo-image": "1.10.1", From cdecb00c71b616277d3cb1562d4bb57c0b4b7207 Mon Sep 17 00:00:00 2001 From: Matt Allen Date: Wed, 27 Mar 2024 17:20:28 -0700 Subject: [PATCH 24/61] Update HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md Added at the end Please include your GitHub username and a link to the PRs you've authored that have been merged. ie. https://github.com/Expensify/App/pulls?q=is%3Apr+author%3Aparasharrajat+is%3Amerged --- contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md b/contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md index 1e950bbf1a63..932dcc8d5e20 100644 --- a/contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md +++ b/contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md @@ -24,4 +24,4 @@ C+ are contributors who are experienced at working with Expensify and have gaine ## How to join? -Email contributors@expensify.com and include "C+ Team Application" in the subject line if you’re interested in joining. +Email contributors@expensify.com and include "C+ Team Application" in the subject line if you’re interested in joining. Please include your GitHub username and a link to the PRs you've authored that have been merged. ie. https://github.com/Expensify/App/pulls?q=is%3Apr+author%3Aparasharrajat+is%3Amerged From 8be26fc4de122876da04d41ab30d84ec0695f2c4 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Thu, 28 Mar 2024 10:17:02 +0700 Subject: [PATCH 25/61] add param and using CONST --- src/libs/Navigation/types.ts | 1 + src/libs/actions/IOU.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index de1ed96579ce..dd41bec40d6e 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -334,6 +334,7 @@ type MoneyRequestNavigatorParamList = { reportID: string; }; [SCREENS.MONEY_REQUEST.CURRENCY]: { + action: ValueOf; iouType: string; reportID: string; currency: string; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 5b009cfe8a7f..8db9dc698bfa 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5006,7 +5006,7 @@ function navigateToNextPage(iou: OnyxEntry, iouType: string, repo // If we're adding a receipt, that means the user came from the confirmation page and we need to navigate back to it. if (path.slice(1) === ROUTES.MONEY_REQUEST_RECEIPT.getRoute(iouType, report?.reportID)) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, '1', report?.reportID ?? '1')); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, CONST.IOU.OPTIMISTIC_TRANSACTION_ID, report?.reportID ?? '1')); return; } @@ -5022,7 +5022,7 @@ function navigateToNextPage(iou: OnyxEntry, iouType: string, repo : (chatReport?.participantAccountIDs ?? []).filter((accountID) => currentUserAccountID !== accountID).map((accountID) => ({accountID, selected: true})); setMoneyRequestParticipants(participants); } - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, '1', report.reportID)); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, CONST.IOU.OPTIMISTIC_TRANSACTION_ID, report.reportID)); return; } Navigation.navigate(ROUTES.MONEY_REQUEST_PARTICIPANTS.getRoute(iouType)); From 2c9efa0dca63e63600452a45891bc3f01ec0e74f Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 28 Mar 2024 11:22:01 +0800 Subject: [PATCH 26/61] update partial merchant condition --- src/libs/Violations/ViolationsUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index be8fe79445dc..c707b9d45451 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -121,7 +121,7 @@ const ViolationsUtils = { policyRequiresCategories: boolean, policyCategories: PolicyCategories, ): OnyxUpdate | null { - const isPartialTransaction = TransactionUtils.isMerchantMissing(updatedTransaction) && TransactionUtils.isAmountMissing(updatedTransaction); + const isPartialTransaction = TransactionUtils.isPartialMerchant(TransactionUtils.getMerchant(updatedTransaction)) && TransactionUtils.isAmountMissing(updatedTransaction); if (isPartialTransaction) { return null; } From 3a5827ff56cd0622f093e5195019e8ca6cc5c88d Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 28 Mar 2024 11:26:20 +0800 Subject: [PATCH 27/61] fix test case --- tests/unit/ViolationUtilsTest.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/ViolationUtilsTest.ts b/tests/unit/ViolationUtilsTest.ts index 7da8352cdb53..10c08266a1e2 100644 --- a/tests/unit/ViolationUtilsTest.ts +++ b/tests/unit/ViolationUtilsTest.ts @@ -1,6 +1,7 @@ import {beforeEach} from '@jest/globals'; import Onyx from 'react-native-onyx'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PolicyCategories, PolicyTagList, Transaction, TransactionViolation} from '@src/types/onyx'; @@ -61,7 +62,7 @@ describe('getViolationsOnyxData', () => { }); it('should not add violation when the transaction is partial', () => { - const partialTransaction = {...transaction, amount: 0, merchant: ''}; + const partialTransaction = {...transaction, amount: 0, merchant: CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT}; transactionViolations = [ {name: 'duplicatedTransaction', type: 'violation'}, {name: 'receiptRequired', type: 'violation'}, From 13770a7117c5297b63f1ab12c2e675fb790634ea Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Thu, 28 Mar 2024 10:35:40 +0700 Subject: [PATCH 28/61] lint fix --- src/libs/actions/IOU.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index f5220e758ff3..446c0ce30b43 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -4999,7 +4999,9 @@ function navigateToNextPage(iou: OnyxEntry, iouType: string, repo // If we're adding a receipt, that means the user came from the confirmation page and we need to navigate back to it. if (path.slice(1) === ROUTES.MONEY_REQUEST_RECEIPT.getRoute(iouType, report?.reportID)) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, CONST.IOU.OPTIMISTIC_TRANSACTION_ID, report?.reportID ?? '1')); + Navigation.navigate( + ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, CONST.IOU.OPTIMISTIC_TRANSACTION_ID, report?.reportID ?? '1'), + ); return; } @@ -5015,7 +5017,9 @@ function navigateToNextPage(iou: OnyxEntry, iouType: string, repo : (chatReport?.participantAccountIDs ?? []).filter((accountID) => currentUserAccountID !== accountID).map((accountID) => ({accountID, selected: true})); setMoneyRequestParticipants(participants); } - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, CONST.IOU.OPTIMISTIC_TRANSACTION_ID, report.reportID)); + Navigation.navigate( + ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType as ValueOf, CONST.IOU.OPTIMISTIC_TRANSACTION_ID, report.reportID), + ); return; } Navigation.navigate(ROUTES.MONEY_REQUEST_PARTICIPANTS.getRoute(iouType)); From 0ef11c2c606b7c9fb74eb8136c93f5313d65c4cc Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Thu, 28 Mar 2024 14:40:02 +0700 Subject: [PATCH 29/61] fix type --- src/libs/Navigation/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index c6a3e04b0eb2..fc82b2f0dea5 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -342,12 +342,12 @@ type MoneyRequestNavigatorParamList = { reportID: string; }; [SCREENS.MONEY_REQUEST.STEP_CONFIRMATION]: { + action: ValueOf; iouType: string; transactionID: string; reportID: string; }; [SCREENS.MONEY_REQUEST.CURRENCY]: { - action: ValueOf; iouType: string; reportID: string; currency: string; From a32c7ee49b9fe7f524f552a4b8d3dd3e35d01097 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 28 Mar 2024 18:50:52 +0800 Subject: [PATCH 30/61] create withTransitionEnd hook --- src/components/withTransitionEnd.tsx | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/components/withTransitionEnd.tsx diff --git a/src/components/withTransitionEnd.tsx b/src/components/withTransitionEnd.tsx new file mode 100644 index 000000000000..0047b60efcc5 --- /dev/null +++ b/src/components/withTransitionEnd.tsx @@ -0,0 +1,39 @@ +import {useNavigation} from '@react-navigation/native'; +import type {StackNavigationProp} from '@react-navigation/stack'; +import type {ComponentType, ForwardedRef, RefAttributes} from 'react'; +import React, {useEffect, useState} from 'react'; +import getComponentDisplayName from '@libs/getComponentDisplayName'; +import type {RootStackParamList} from '@libs/Navigation/types'; + +type WithTransitionEndProps = {didScreenTransitionEnd: boolean}; + +export default function (WrappedComponent: ComponentType>): React.ComponentType> { + function WithTransitionEnd(props: TProps, ref: ForwardedRef) { + const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false); + const navigation = useNavigation>(); + + useEffect(() => { + const unsubscribeTransitionEnd = navigation.addListener('transitionEnd', () => { + setDidScreenTransitionEnd(true); + }); + + return unsubscribeTransitionEnd; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + + ); + } + + WithTransitionEnd.displayName = `WithTransitionEnd(${getComponentDisplayName(WrappedComponent)})`; + + return WithTransitionEnd; +} + +export type {WithTransitionEndProps}; From bb40f856185258c5fc16561754d28ae6ebcef8aa Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 28 Mar 2024 18:51:09 +0800 Subject: [PATCH 31/61] use didScreenTransitionEnd from withTransitionEnd HOC --- src/pages/RoomInvitePage.tsx | 37 +++++--------- src/pages/tasks/TaskAssigneeSelectorModal.tsx | 44 ++++++++-------- src/pages/workspace/WorkspaceInvitePage.tsx | 51 ++++++++----------- 3 files changed, 56 insertions(+), 76 deletions(-) diff --git a/src/pages/RoomInvitePage.tsx b/src/pages/RoomInvitePage.tsx index d0ea55a923e7..35c4759cdaad 100644 --- a/src/pages/RoomInvitePage.tsx +++ b/src/pages/RoomInvitePage.tsx @@ -1,5 +1,3 @@ -import {useNavigation} from '@react-navigation/native'; -import type {StackNavigationProp} from '@react-navigation/stack'; import Str from 'expensify-common/lib/str'; import React, {useCallback, useEffect, useMemo, useState} from 'react'; import type {SectionListData} from 'react-native'; @@ -13,12 +11,13 @@ import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import type {Section} from '@components/SelectionList/types'; import UserListItem from '@components/SelectionList/UserListItem'; +import withTransitionEnd from '@components/withTransitionEnd'; +import type {WithTransitionEndProps} from '@components/withTransitionEnd'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as LoginUtils from '@libs/LoginUtils'; import Navigation from '@libs/Navigation/Navigation'; -import type {RootStackParamList} from '@libs/Navigation/types'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; @@ -39,19 +38,17 @@ type RoomInvitePageOnyxProps = { personalDetails: OnyxEntry; }; -type RoomInvitePageProps = RoomInvitePageOnyxProps & WithReportOrNotFoundProps; +type RoomInvitePageProps = RoomInvitePageOnyxProps & WithReportOrNotFoundProps & WithTransitionEndProps; type Sections = Array>>; -function RoomInvitePage({betas, personalDetails, report, policies}: RoomInvitePageProps) { +function RoomInvitePage({betas, personalDetails, report, policies, didScreenTransitionEnd}: RoomInvitePageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const [searchTerm, setSearchTerm] = useState(''); const [selectedOptions, setSelectedOptions] = useState([]); const [invitePersonalDetails, setInvitePersonalDetails] = useState([]); const [userToInvite, setUserToInvite] = useState(null); - const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false); - const navigation: StackNavigationProp = useNavigation(); useEffect(() => { setSearchTerm(SearchInputManager.searchInput); @@ -88,18 +85,6 @@ function RoomInvitePage({betas, personalDetails, report, policies}: RoomInvitePa // eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want to recalculate when selectedOptions change }, [personalDetails, betas, searchTerm, excludedUsers]); - useEffect(() => { - const unsubscribeTransitionEnd = navigation.addListener('transitionEnd', () => { - setDidScreenTransitionEnd(true); - }); - - return () => { - unsubscribeTransitionEnd(); - }; - // Rule disabled because this effect is only for component did mount & will component unmount lifecycle event - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const sections = useMemo(() => { const sectionsArr: Sections = []; let indexOffset = 0; @@ -266,10 +251,12 @@ function RoomInvitePage({betas, personalDetails, report, policies}: RoomInvitePa RoomInvitePage.displayName = 'RoomInvitePage'; -export default withReportOrNotFound()( - withOnyx({ - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, - })(RoomInvitePage), +export default withTransitionEnd( + withReportOrNotFound()( + withOnyx({ + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + })(RoomInvitePage), + ), ); diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.tsx b/src/pages/tasks/TaskAssigneeSelectorModal.tsx index 0ffb33b7590b..a8ae93dd53c9 100644 --- a/src/pages/tasks/TaskAssigneeSelectorModal.tsx +++ b/src/pages/tasks/TaskAssigneeSelectorModal.tsx @@ -14,6 +14,8 @@ import type {ListItem} from '@components/SelectionList/types'; import UserListItem from '@components/SelectionList/UserListItem'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; +import withTransitionEnd from '@components/withTransitionEnd'; +import type {WithTransitionEndProps} from '@components/withTransitionEnd'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; @@ -41,7 +43,7 @@ type UseOptions = { reports: OnyxCollection; }; -type TaskAssigneeSelectorModalProps = TaskAssigneeSelectorModalOnyxProps & WithCurrentUserPersonalDetailsProps; +type TaskAssigneeSelectorModalProps = TaskAssigneeSelectorModalOnyxProps & WithCurrentUserPersonalDetailsProps & WithTransitionEndProps; function useOptions({reports}: UseOptions) { const allPersonalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; @@ -90,7 +92,7 @@ function useOptions({reports}: UseOptions) { return {...options, isLoading, searchValue, debouncedSearchValue, setSearchValue}; } -function TaskAssigneeSelectorModal({reports, task}: TaskAssigneeSelectorModalProps) { +function TaskAssigneeSelectorModal({reports, task, didScreenTransitionEnd}: TaskAssigneeSelectorModalProps) { const styles = useThemeStyles(); const route = useRoute>(); const {translate} = useLocalize(); @@ -212,26 +214,24 @@ function TaskAssigneeSelectorModal({reports, task}: TaskAssigneeSelectorModalPro includeSafeAreaPaddingBottom={false} testID={TaskAssigneeSelectorModal.displayName} > - {({didScreenTransitionEnd}) => ( - - + + + - - - - - )} + + ); } @@ -247,4 +247,4 @@ const TaskAssigneeSelectorModalWithOnyx = withOnyx; }; -type WorkspaceInvitePageProps = WithPolicyAndFullscreenLoadingProps & WorkspaceInvitePageOnyxProps & StackScreenProps; +type WorkspaceInvitePageProps = WithPolicyAndFullscreenLoadingProps & + WithTransitionEndProps & + WorkspaceInvitePageOnyxProps & + StackScreenProps; function WorkspaceInvitePage({ route, @@ -59,6 +63,7 @@ function WorkspaceInvitePage({ invitedEmailsToAccountIDsDraft, policy, isLoadingReportData = true, + didScreenTransitionEnd, }: WorkspaceInvitePageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -66,8 +71,6 @@ function WorkspaceInvitePage({ const [selectedOptions, setSelectedOptions] = useState([]); const [personalDetails, setPersonalDetails] = useState([]); const [usersToInvite, setUsersToInvite] = useState([]); - const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false); - const navigation = useNavigation>(); const openWorkspaceInvitePage = () => { const policyMemberEmailsToAccountIDs = PolicyUtils.getMemberAccountIDsForWorkspace(policyMembers, personalDetailsProp); Policy.openWorkspaceInvitePage(route.params.policyID, Object.keys(policyMemberEmailsToAccountIDs)); @@ -86,18 +89,6 @@ function WorkspaceInvitePage({ // eslint-disable-next-line react-hooks/exhaustive-deps -- policyID changes remount the component }, []); - useEffect(() => { - const unsubscribeTransitionEnd = navigation.addListener('transitionEnd', () => { - setDidScreenTransitionEnd(true); - }); - - return () => { - unsubscribeTransitionEnd(); - }; - // Rule disabled because this effect is only for component did mount & will component unmount lifecycle event - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - useNetwork({onReconnect: openWorkspaceInvitePage}); const excludedUsers = useMemo(() => PolicyUtils.getIneligibleInvitees(policyMembers, personalDetailsProp), [policyMembers, personalDetailsProp]); @@ -342,16 +333,18 @@ function WorkspaceInvitePage({ WorkspaceInvitePage.displayName = 'WorkspaceInvitePage'; -export default withPolicyAndFullscreenLoading( - withOnyx({ - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, - betas: { - key: ONYXKEYS.BETAS, - }, - invitedEmailsToAccountIDsDraft: { - key: ({route}) => `${ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT}${route.params.policyID.toString()}`, - }, - })(WorkspaceInvitePage), +export default withTransitionEnd( + withPolicyAndFullscreenLoading( + withOnyx({ + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + betas: { + key: ONYXKEYS.BETAS, + }, + invitedEmailsToAccountIDsDraft: { + key: ({route}) => `${ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT}${route.params.policyID.toString()}`, + }, + })(WorkspaceInvitePage), + ), ); From 77c05c9b02ebbda60f78786afab7b9ffb9832b29 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 28 Mar 2024 19:01:07 +0800 Subject: [PATCH 32/61] add missing forwardRef --- src/components/withTransitionEnd.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/withTransitionEnd.tsx b/src/components/withTransitionEnd.tsx index 0047b60efcc5..b00e0a9f4f34 100644 --- a/src/components/withTransitionEnd.tsx +++ b/src/components/withTransitionEnd.tsx @@ -33,7 +33,7 @@ export default function (WrappedComponent: ComponentType Date: Thu, 28 Mar 2024 21:46:25 +0200 Subject: [PATCH 33/61] clean MentionUserRenderer.tsx mentionDisplayText --- .../HTMLRenderers/MentionUserRenderer.tsx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx index d3376a798a8b..0c7c82534bbb 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.tsx @@ -35,12 +35,12 @@ function MentionUserRenderer({style, tnode, TDefaultRenderer, currentUserPersona const htmlAttributeAccountID = tnode.attributes.accountid; let accountID: number; - let displayNameOrLogin: string; + let mentionDisplayText: string; let navigationRoute: Route; const tnodeClone = cloneDeep(tnode); - const getMentionDisplayText = (displayText: string, userAccountID: string, userLogin = '') => { + const getShortMentionIfFound = (displayText: string, userAccountID: string, userLogin = '') => { // If the userAccountID does not exist, this is an email-based mention so the displayText must be an email. // If the userAccountID exists but userLogin is different from displayText, this means the displayText is either user display name, Hidden, or phone number, in which case we should return it as is. if (userAccountID && userLogin !== displayText) { @@ -59,18 +59,18 @@ function MentionUserRenderer({style, tnode, TDefaultRenderer, currentUserPersona if (!isEmpty(htmlAttribAccountID)) { const user = personalDetails[htmlAttribAccountID]; accountID = parseInt(htmlAttribAccountID, 10); - displayNameOrLogin = LocalePhoneNumber.formatPhoneNumber(user?.login ?? '') || PersonalDetailsUtils.getDisplayNameOrDefault(user); - displayNameOrLogin = Str.removeSMSDomain(getMentionDisplayText(displayNameOrLogin, htmlAttributeAccountID, user?.login ?? '')); + mentionDisplayText = LocalePhoneNumber.formatPhoneNumber(user?.login ?? '') || PersonalDetailsUtils.getDisplayNameOrDefault(user); + mentionDisplayText = getShortMentionIfFound(mentionDisplayText, htmlAttributeAccountID, user?.login ?? ''); navigationRoute = ROUTES.PROFILE.getRoute(htmlAttribAccountID); } else if ('data' in tnodeClone && !isEmptyObject(tnodeClone.data)) { // We need to remove the LTR unicode and leading @ from data as it is not part of the login - displayNameOrLogin = tnodeClone.data.replace(CONST.UNICODE.LTR, '').slice(1); + mentionDisplayText = tnodeClone.data.replace(CONST.UNICODE.LTR, '').slice(1); // We need to replace tnode.data here because we will pass it to TNodeChildrenRenderer below - asMutable(tnodeClone).data = tnodeClone.data.replace(displayNameOrLogin, Str.removeSMSDomain(getMentionDisplayText(displayNameOrLogin, htmlAttributeAccountID))); + asMutable(tnodeClone).data = tnodeClone.data.replace(mentionDisplayText, Str.removeSMSDomain(getShortMentionIfFound(mentionDisplayText, htmlAttributeAccountID))); - accountID = PersonalDetailsUtils.getAccountIDsByLogins([displayNameOrLogin])?.[0]; - navigationRoute = ROUTES.DETAILS.getRoute(displayNameOrLogin); - displayNameOrLogin = Str.removeSMSDomain(displayNameOrLogin); + accountID = PersonalDetailsUtils.getAccountIDsByLogins([mentionDisplayText])?.[0]; + navigationRoute = ROUTES.DETAILS.getRoute(mentionDisplayText); + mentionDisplayText = Str.removeSMSDomain(mentionDisplayText); } else { // If neither an account ID or email is provided, don't render anything return null; @@ -97,7 +97,7 @@ function MentionUserRenderer({style, tnode, TDefaultRenderer, currentUserPersona - {htmlAttribAccountID ? `@${displayNameOrLogin}` : } + {htmlAttribAccountID ? `@${mentionDisplayText}` : } From a574a3915e87b3b21658327042fcc27201ddc44a Mon Sep 17 00:00:00 2001 From: GandalfGwaihir Date: Fri, 29 Mar 2024 05:51:59 +0530 Subject: [PATCH 34/61] introduce new translations --- src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index c3ad6d82d6b2..8fd1f89443b1 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -516,7 +516,7 @@ export default { asCopilot: 'as copilot for', }, mentionSuggestions: { - hereAlternateText: 'Notify everyone online in this room', + hereAlternateText: 'Notify everyone in this conversation', }, newMessages: 'New messages', reportTypingIndicator: { diff --git a/src/languages/es.ts b/src/languages/es.ts index 78b80adb16d4..18b5958fabe6 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -512,7 +512,7 @@ export default { asCopilot: 'como copiloto de', }, mentionSuggestions: { - hereAlternateText: 'Notificar a todos los que estén en linea de esta sala', + hereAlternateText: 'Notificar a todos en esta conversación', }, newMessages: 'Mensajes nuevos', reportTypingIndicator: { From 349c11d21f996a4dd61a4964d4fa6873906e541a Mon Sep 17 00:00:00 2001 From: GandalfGwaihir Date: Fri, 29 Mar 2024 06:08:58 +0530 Subject: [PATCH 35/61] fix screens --- .../Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts index 4ec955784d92..95233bfed079 100755 --- a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts @@ -19,9 +19,6 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial> = SCREENS.SETTINGS.PROFILE.ADDRESS, SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY, SCREENS.SETTINGS.SHARE_CODE, - SCREENS.SETTINGS.EXIT_SURVEY.REASON, - SCREENS.SETTINGS.EXIT_SURVEY.RESPONSE, - SCREENS.SETTINGS.EXIT_SURVEY.CONFIRM, ], [SCREENS.SETTINGS.PREFERENCES.ROOT]: [SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE, SCREENS.SETTINGS.PREFERENCES.LANGUAGE, SCREENS.SETTINGS.PREFERENCES.THEME], [SCREENS.SETTINGS.WALLET.ROOT]: [ From 0612ffd05ba26b5d6c346cd9a99ecf556090f69c Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Fri, 29 Mar 2024 15:09:51 +0800 Subject: [PATCH 36/61] return current violation if it's a partial transaction --- src/libs/Violations/ViolationsUtils.ts | 8 +++-- src/libs/actions/IOU.ts | 43 ++++++++++++-------------- tests/unit/ViolationUtilsTest.ts | 42 ++++++++++++------------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index c707b9d45451..0d24c3bd2757 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -120,10 +120,14 @@ const ViolationsUtils = { policyTagList: PolicyTagList, policyRequiresCategories: boolean, policyCategories: PolicyCategories, - ): OnyxUpdate | null { + ): OnyxUpdate { const isPartialTransaction = TransactionUtils.isPartialMerchant(TransactionUtils.getMerchant(updatedTransaction)) && TransactionUtils.isAmountMissing(updatedTransaction); if (isPartialTransaction) { - return null; + return { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${updatedTransaction.transactionID}`, + value: transactionViolations, + }; } let newTransactionViolations = [...transactionViolations]; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index f6bd73afd082..b67e44fcf5ad 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1700,22 +1700,21 @@ function getUpdateMoneyRequestParams( if (policy && PolicyUtils.isPaidGroupPolicy(policy) && updatedTransaction) { const currentTransactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? []; - const updatedViolationsOnyxData = ViolationsUtils.getViolationsOnyxData( - updatedTransaction, - currentTransactionViolations, - !!policy.requiresTag, - policyTagList ?? {}, - !!policy.requiresCategory, - policyCategories ?? {}, + optimisticData.push( + ViolationsUtils.getViolationsOnyxData( + updatedTransaction, + currentTransactionViolations, + !!policy.requiresTag, + policyTagList ?? {}, + !!policy.requiresCategory, + policyCategories ?? {}, + ), ); - if (updatedViolationsOnyxData) { - optimisticData.push(updatedViolationsOnyxData); - failureData.push({ - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, - value: currentTransactionViolations, - }); - } + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, + value: currentTransactionViolations, + }); } // Reset the transaction thread to its original state @@ -3506,14 +3505,12 @@ function editRegularMoneyRequest( !!policy.requiresCategory, policyCategories, ); - if (updatedViolationsOnyxData) { - optimisticData.push(updatedViolationsOnyxData); - failureData.push({ - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, - value: currentTransactionViolations, - }); - } + optimisticData.push(updatedViolationsOnyxData); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, + value: currentTransactionViolations, + }); } // STEP 6: Call the API endpoint diff --git a/tests/unit/ViolationUtilsTest.ts b/tests/unit/ViolationUtilsTest.ts index 10c08266a1e2..08d7e8cd3d08 100644 --- a/tests/unit/ViolationUtilsTest.ts +++ b/tests/unit/ViolationUtilsTest.ts @@ -58,7 +58,7 @@ describe('getViolationsOnyxData', () => { {name: 'receiptRequired', type: 'violation'}, ]; const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(expect.arrayContaining(transactionViolations)); + expect(result.value).toEqual(expect.arrayContaining(transactionViolations)); }); it('should not add violation when the transaction is partial', () => { @@ -68,7 +68,7 @@ describe('getViolationsOnyxData', () => { {name: 'receiptRequired', type: 'violation'}, ]; const result = ViolationsUtils.getViolationsOnyxData(partialTransaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result).toBeNull(); + expect(result.value).toEqual(transactionViolations); }); describe('policyRequiresCategories', () => { @@ -81,18 +81,18 @@ describe('getViolationsOnyxData', () => { it('should add missingCategory violation if no category is included', () => { transaction.category = undefined; const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); + expect(result.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); }); it('should add categoryOutOfPolicy violation when category is not in policy', () => { transaction.category = 'Bananas'; const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); + expect(result.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); }); it('should not include a categoryOutOfPolicy violation when category is in policy', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).not.toContainEqual(categoryOutOfPolicyViolation); + expect(result.value).not.toContainEqual(categoryOutOfPolicyViolation); }); it('should add categoryOutOfPolicy violation to existing violations if they exist', () => { @@ -104,7 +104,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); + expect(result.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); }); it('should add missingCategory violation to existing violations if they exist', () => { @@ -116,7 +116,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); + expect(result.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); }); }); @@ -128,8 +128,8 @@ describe('getViolationsOnyxData', () => { it('should not add any violations when categories are not required', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).not.toContainEqual([categoryOutOfPolicyViolation]); - expect(result?.value).not.toContainEqual([missingCategoryViolation]); + expect(result.value).not.toContainEqual([categoryOutOfPolicyViolation]); + expect(result.value).not.toContainEqual([missingCategoryViolation]); }); }); @@ -153,7 +153,7 @@ describe('getViolationsOnyxData', () => { it("shouldn't update the transactionViolations if the policy requires tags and the transaction has a tag from the policy", () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(transactionViolations); + expect(result.value).toEqual(transactionViolations); }); it('should add a missingTag violation if none is provided and policy requires tags', () => { @@ -161,7 +161,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(expect.arrayContaining([{...missingTagViolation}])); + expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation}])); }); it('should add a tagOutOfPolicy violation when policy requires tags and tag is not in the policy', () => { @@ -169,7 +169,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual([]); + expect(result.value).toEqual([]); }); it('should add tagOutOfPolicy violation to existing violations if transaction has tag that is not in the policy', () => { @@ -181,7 +181,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(expect.arrayContaining([{...tagOutOfPolicyViolation}, ...transactionViolations])); + expect(result.value).toEqual(expect.arrayContaining([{...tagOutOfPolicyViolation}, ...transactionViolations])); }); it('should add missingTag violation to existing violations if transaction does not have a tag', () => { @@ -193,7 +193,7 @@ describe('getViolationsOnyxData', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual(expect.arrayContaining([{...missingTagViolation}, ...transactionViolations])); + expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation}, ...transactionViolations])); }); }); @@ -205,8 +205,8 @@ describe('getViolationsOnyxData', () => { it('should not add any violations when tags are not required', () => { const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).not.toContainEqual([tagOutOfPolicyViolation]); - expect(result?.value).not.toContainEqual([missingTagViolation]); + expect(result.value).not.toContainEqual([tagOutOfPolicyViolation]); + expect(result.value).not.toContainEqual([missingTagViolation]); }); }); describe('policy has multi level tags', () => { @@ -259,31 +259,31 @@ describe('getViolationsOnyxData', () => { // Test case where transaction has no tags let result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual([someTagLevelsRequiredViolation]); + expect(result.value).toEqual([someTagLevelsRequiredViolation]); // Test case where transaction has 1 tag transaction.tag = 'Accounting'; someTagLevelsRequiredViolation.data = {errorIndexes: [1, 2]}; result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual([someTagLevelsRequiredViolation]); + expect(result.value).toEqual([someTagLevelsRequiredViolation]); // Test case where transaction has 2 tags transaction.tag = 'Accounting::Project1'; someTagLevelsRequiredViolation.data = {errorIndexes: [1]}; result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual([someTagLevelsRequiredViolation]); + expect(result.value).toEqual([someTagLevelsRequiredViolation]); // Test case where transaction has all tags transaction.tag = 'Accounting:Africa:Project1'; result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result?.value).toEqual([]); + expect(result.value).toEqual([]); }); it('should return tagOutOfPolicy when a tag is not enabled in the policy but is set in the transaction', () => { policyTags.Department.tags.Accounting.enabled = false; transaction.tag = 'Accounting:Africa:Project1'; const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); const violation = {...tagOutOfPolicyViolation, data: {tagName: 'Department'}}; - expect(result?.value).toEqual([violation]); + expect(result.value).toEqual([violation]); }); }); }); From 1416897ee1ef4900c794fa8a39300ad832801933 Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Fri, 29 Mar 2024 14:50:32 +0530 Subject: [PATCH 37/61] fix: Description/Merchant does not show in request preview. Signed-off-by: Krishna Gupta --- src/components/ReportActionItem/ReportPreview.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 8b95474bf2fc..33ce01212b2f 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -127,6 +127,7 @@ function ReportPreview({ const isApproved = ReportUtils.isReportApproved(iouReport); const canAllowSettlement = ReportUtils.hasUpdatedTotal(iouReport); + const allTransactions = TransactionUtils.getAllReportTransactions(iouReportID); const transactionsWithReceipts = ReportUtils.getTransactionsWithReceipts(iouReportID); const numberOfScanningReceipts = transactionsWithReceipts.filter((transaction) => TransactionUtils.isReceiptBeingScanned(transaction)).length; const numberOfPendingRequests = transactionsWithReceipts.filter((transaction) => TransactionUtils.isPending(transaction) && TransactionUtils.isCardTransaction(transaction)).length; @@ -138,14 +139,16 @@ function ReportPreview({ const lastThreeTransactionsWithReceipts = transactionsWithReceipts.slice(-3); const lastThreeReceipts = lastThreeTransactionsWithReceipts.map((transaction) => ReceiptUtils.getThumbnailAndImageURIs(transaction)); - let formattedMerchant = numberOfRequests === 1 && hasReceipts ? TransactionUtils.getMerchant(transactionsWithReceipts[0]) : null; + let formattedMerchant = numberOfRequests === 1 ? TransactionUtils.getMerchant(allTransactions[0]) : null; + const formattedDescription = numberOfRequests === 1 ? TransactionUtils.getDescription(allTransactions[0]) : null; + if (TransactionUtils.isPartialMerchant(formattedMerchant ?? '')) { formattedMerchant = null; } const previewSubtitle = // Formatted merchant can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - formattedMerchant || + (formattedMerchant ?? formattedDescription) || translate('iou.requestCount', { count: numberOfRequests - numberOfScanningReceipts - numberOfPendingRequests, scanningReceipts: numberOfScanningReceipts, @@ -228,7 +231,8 @@ function ReportPreview({ In this case, we don't want to show the merchant because it says: "Pending route...", which is already displayed in the amount field. */ const shouldShowSingleRequestMerchant = numberOfRequests === 1 && !!formattedMerchant && !(hasOnlyTransactionsWithPendingRoutes && !totalDisplaySpend); - const shouldShowSubtitle = !isScanning && (shouldShowSingleRequestMerchant || numberOfRequests > 1); + const shouldShowSingleRequestDescription = numberOfRequests === 1 && !!formattedDescription && !shouldShowSingleRequestMerchant; + const shouldShowSubtitle = !isScanning && (shouldShowSingleRequestMerchant || shouldShowSingleRequestDescription || numberOfRequests > 1); return ( Date: Fri, 29 Mar 2024 18:21:46 +0800 Subject: [PATCH 38/61] get the latest pending action of member --- src/pages/ReportParticipantsPage.tsx | 2 +- src/pages/RoomMembersPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/ReportParticipantsPage.tsx b/src/pages/ReportParticipantsPage.tsx index a2b2f094ac26..fa5f2b0947c5 100755 --- a/src/pages/ReportParticipantsPage.tsx +++ b/src/pages/ReportParticipantsPage.tsx @@ -50,7 +50,7 @@ const getAllParticipants = ( !!userPersonalDetail?.login && !CONST.RESTRICTED_ACCOUNT_IDS.includes(accountID) ? LocalePhoneNumber.formatPhoneNumber(userPersonalDetail.login) : translate('common.hidden'); const displayName = PersonalDetailsUtils.getDisplayNameOrDefault(userPersonalDetail); - const pendingChatMember = report?.pendingChatMembers?.find((member) => member.accountID === accountID.toString()); + const pendingChatMember = report?.pendingChatMembers?.findLast((member) => member.accountID === accountID.toString()); return { alternateText: userLogin, pendingAction: pendingChatMember?.pendingAction, diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 6cdcc6e06b95..220323e3ad85 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -198,7 +198,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { return; } } - const pendingChatMember = report?.pendingChatMembers?.find((member) => member.accountID === accountID.toString()); + const pendingChatMember = report?.pendingChatMembers?.findLast((member) => member.accountID === accountID.toString()); result.push({ keyForList: String(accountID), From c096e2b0578fda03b3f48609f6c449b1970653e3 Mon Sep 17 00:00:00 2001 From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:00:16 +0530 Subject: [PATCH 39/61] Video playback speed change should not move to next video --- src/components/VideoPopoverMenu/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/VideoPopoverMenu/index.tsx b/src/components/VideoPopoverMenu/index.tsx index aad6364f91df..23f3447cf495 100644 --- a/src/components/VideoPopoverMenu/index.tsx +++ b/src/components/VideoPopoverMenu/index.tsx @@ -35,7 +35,6 @@ function VideoPopoverMenu({ anchorPosition={anchorPosition} menuItems={menuItems} anchorRef={videoPlayerMenuRef} - withoutOverlay /> ); } From ca12bc8810f87297a0fb650a0cd8d6889e145fac Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 06:58:32 -1000 Subject: [PATCH 40/61] Pass the chatType --- src/libs/API/parameters/StartSplitBillParams.ts | 1 + src/libs/actions/IOU.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libs/API/parameters/StartSplitBillParams.ts b/src/libs/API/parameters/StartSplitBillParams.ts index 30d21697ac67..623f291eb691 100644 --- a/src/libs/API/parameters/StartSplitBillParams.ts +++ b/src/libs/API/parameters/StartSplitBillParams.ts @@ -12,6 +12,7 @@ type StartSplitBillParams = { isFromGroupDM: boolean; createdReportActionID?: string; billable: boolean; + chatType?: string; }; export default StartSplitBillParams; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 33cd660b65f9..2d494c763503 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3047,6 +3047,7 @@ function startSplitBill( isFromGroupDM: !existingSplitChatReport, billable, ...(existingSplitChatReport ? {} : {createdReportActionID: splitChatCreatedReportAction.reportActionID}), + chatType: splitChatReport?.chatType, }; API.write(WRITE_COMMANDS.START_SPLIT_BILL, parameters, {optimisticData, successData, failureData}); From 744a59fc88c183a2b20153fb29004d453a198b05 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 07:52:20 -1000 Subject: [PATCH 41/61] Refactor duplicate logic to get or create split chat report --- src/libs/actions/IOU.ts | 61 +++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 2d494c763503..6ba3500a27ae 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2280,31 +2280,7 @@ function createSplitsAndOnyxData( const currentUserEmailForIOUSplit = PhoneNumber.addSMSDomainIfPhoneNumber(currentUserLogin); const participantAccountIDs = participants.map((participant) => Number(participant.accountID)); - const existingChatReportID = existingSplitChatReportID || participants[0].reportID; - let existingSplitChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`]; - if (!existingSplitChatReport) { - existingSplitChatReport = participants.length < 2 ? ReportUtils.getChatByParticipants(participantAccountIDs) : null; - } - let newChat: ReportUtils.OptimisticChatReport | EmptyObject = {}; - const allParticipantsAccountIDs = [...participantAccountIDs, currentUserAccountID]; - if (!existingSplitChatReport && participants.length > 1) { - newChat = ReportUtils.buildOptimisticChatReport( - allParticipantsAccountIDs, - '', - CONST.REPORT.CHAT_TYPE.GROUP, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, - ); - } - if (isEmptyObject(newChat)) { - newChat = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); - } - const splitChatReport = existingSplitChatReport ?? newChat; + const {splitChatReport, existingSplitChatReport} = getOrCreateSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID); const isOwnPolicyExpenseChat = !!splitChatReport.isOwnPolicyExpenseChat; const splitTransaction = TransactionUtils.buildOptimisticTransaction( @@ -2647,6 +2623,35 @@ function createSplitsAndOnyxData( }; } +function getOrCreateSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { + const existingChatReportID = existingSplitChatReportID || participants[0].reportID; + let existingSplitChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`]; + if (!existingSplitChatReport) { + existingSplitChatReport = participants.length < 2 ? ReportUtils.getChatByParticipants(participantAccountIDs) : null; + } + let newChat: ReportUtils.OptimisticChatReport | EmptyObject = {}; + const allParticipantsAccountIDs = [...participantAccountIDs, currentUserAccountID]; + if (!existingSplitChatReport && participants.length > 1) { + newChat = ReportUtils.buildOptimisticChatReport( + allParticipantsAccountIDs, + '', + CONST.REPORT.CHAT_TYPE.GROUP, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN + ); + } + if (isEmptyObject(newChat)) { + newChat = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); + } + const splitChatReport = existingSplitChatReport ?? newChat; + return { splitChatReport, existingSplitChatReport }; +} + /** * @param amount - always in smallest currency unit * @param existingSplitChatReportID - Either a group DM or a workspace chat @@ -2785,11 +2790,7 @@ function startSplitBill( ) { const currentUserEmailForIOUSplit = PhoneNumber.addSMSDomainIfPhoneNumber(currentUserLogin); const participantAccountIDs = participants.map((participant) => Number(participant.accountID)); - const existingSplitChatReport = - existingSplitChatReportID || participants[0].reportID - ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingSplitChatReportID || participants[0].reportID}`] - : ReportUtils.getChatByParticipants(participantAccountIDs); - const splitChatReport = existingSplitChatReport ?? ReportUtils.buildOptimisticChatReport(participantAccountIDs); + const {splitChatReport, existingSplitChatReport} = getOrCreateSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID); const isOwnPolicyExpenseChat = !!splitChatReport.isOwnPolicyExpenseChat; const {name: filename, source, state = CONST.IOU.RECEIPT_STATE.SCANREADY} = receipt; From 2ff25d1c86cd77008ed384ae76d696b43115f358 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 07:54:24 -1000 Subject: [PATCH 42/61] run prettier --- src/libs/actions/IOU.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 6ba3500a27ae..0f325d001fcc 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2642,14 +2642,14 @@ function getOrCreateSplitChatReport(existingSplitChatReportID: string, participa undefined, undefined, undefined, - CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN + CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, ); } if (isEmptyObject(newChat)) { newChat = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); } const splitChatReport = existingSplitChatReport ?? newChat; - return { splitChatReport, existingSplitChatReport }; + return {splitChatReport, existingSplitChatReport}; } /** From db186982229cd670360c41ef4e24fde8c42956a6 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 07:56:49 -1000 Subject: [PATCH 43/61] give better name since we dont actually create any report just optimistic one --- src/libs/actions/IOU.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 0f325d001fcc..9ee90a5090f0 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2280,7 +2280,7 @@ function createSplitsAndOnyxData( const currentUserEmailForIOUSplit = PhoneNumber.addSMSDomainIfPhoneNumber(currentUserLogin); const participantAccountIDs = participants.map((participant) => Number(participant.accountID)); - const {splitChatReport, existingSplitChatReport} = getOrCreateSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID); + const {splitChatReport, existingSplitChatReport} = getOrCreateOptimisticSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID); const isOwnPolicyExpenseChat = !!splitChatReport.isOwnPolicyExpenseChat; const splitTransaction = TransactionUtils.buildOptimisticTransaction( @@ -2623,7 +2623,7 @@ function createSplitsAndOnyxData( }; } -function getOrCreateSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { +function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { const existingChatReportID = existingSplitChatReportID || participants[0].reportID; let existingSplitChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`]; if (!existingSplitChatReport) { @@ -2790,7 +2790,7 @@ function startSplitBill( ) { const currentUserEmailForIOUSplit = PhoneNumber.addSMSDomainIfPhoneNumber(currentUserLogin); const participantAccountIDs = participants.map((participant) => Number(participant.accountID)); - const {splitChatReport, existingSplitChatReport} = getOrCreateSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID); + const {splitChatReport, existingSplitChatReport} = getOrCreateOptimisticSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID); const isOwnPolicyExpenseChat = !!splitChatReport.isOwnPolicyExpenseChat; const {name: filename, source, state = CONST.IOU.RECEIPT_STATE.SCANREADY} = receipt; From aec400275cb82f264843eb1cacd0ad111dd4ba3c Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 08:04:17 -1000 Subject: [PATCH 44/61] Fix avatar leading to not found page --- src/components/RoomHeaderAvatars.tsx | 7 ++++++- src/pages/ReportDetailsPage.tsx | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/RoomHeaderAvatars.tsx b/src/components/RoomHeaderAvatars.tsx index 9298062aa6f9..c23108adc0ea 100644 --- a/src/components/RoomHeaderAvatars.tsx +++ b/src/components/RoomHeaderAvatars.tsx @@ -13,10 +13,15 @@ import Text from './Text'; type RoomHeaderAvatarsProps = { icons: Icon[]; reportID: string; + isGroupChat?: boolean; }; -function RoomHeaderAvatars({icons, reportID}: RoomHeaderAvatarsProps) { +function RoomHeaderAvatars({icons, reportID, isGroupChat}: RoomHeaderAvatarsProps) { const navigateToAvatarPage = (icon: Icon) => { + if (isGroupChat) { + return; + } + if (icon.type === CONST.ICON_TYPE_WORKSPACE) { Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(reportID)); return; diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 80563fcf7b1b..ccfe329419e3 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -218,6 +218,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD )} From c3892b1f003fd6a8e14a5cf0274bf0cc078f0363 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 08:27:10 -1000 Subject: [PATCH 45/61] Fix lint --- src/libs/actions/IOU.ts | 58 ++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 9ee90a5090f0..30892bef5760 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2248,6 +2248,35 @@ function trackExpense( Report.notifyNewAction(activeReportID, payeeAccountID); } +function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { + const existingChatReportID = existingSplitChatReportID || participants[0].reportID; + let existingSplitChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`]; + if (!existingSplitChatReport) { + existingSplitChatReport = participants.length < 2 ? ReportUtils.getChatByParticipants(participantAccountIDs) : null; + } + let newChat: ReportUtils.OptimisticChatReport | EmptyObject = {}; + const allParticipantsAccountIDs = [...participantAccountIDs, currentUserAccountID]; + if (!existingSplitChatReport && participants.length > 1) { + newChat = ReportUtils.buildOptimisticChatReport( + allParticipantsAccountIDs, + '', + CONST.REPORT.CHAT_TYPE.GROUP, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + ); + } + if (isEmptyObject(newChat)) { + newChat = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); + } + const splitChatReport = existingSplitChatReport ?? newChat; + return {splitChatReport, existingSplitChatReport}; +} + /** * Build the Onyx data and IOU split necessary for splitting a bill with 3+ users. * 1. Build the optimistic Onyx data for the group chat, i.e. chatReport and iouReportAction creating the former if it doesn't yet exist. @@ -2623,35 +2652,6 @@ function createSplitsAndOnyxData( }; } -function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { - const existingChatReportID = existingSplitChatReportID || participants[0].reportID; - let existingSplitChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`]; - if (!existingSplitChatReport) { - existingSplitChatReport = participants.length < 2 ? ReportUtils.getChatByParticipants(participantAccountIDs) : null; - } - let newChat: ReportUtils.OptimisticChatReport | EmptyObject = {}; - const allParticipantsAccountIDs = [...participantAccountIDs, currentUserAccountID]; - if (!existingSplitChatReport && participants.length > 1) { - newChat = ReportUtils.buildOptimisticChatReport( - allParticipantsAccountIDs, - '', - CONST.REPORT.CHAT_TYPE.GROUP, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, - ); - } - if (isEmptyObject(newChat)) { - newChat = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); - } - const splitChatReport = existingSplitChatReport ?? newChat; - return {splitChatReport, existingSplitChatReport}; -} - /** * @param amount - always in smallest currency unit * @param existingSplitChatReportID - Either a group DM or a workspace chat From d94613008dec9177cf32679aab88482a4c038a2e Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 12:19:01 -1000 Subject: [PATCH 46/61] Fix workspace avatar issue --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index b7c835d692ca..82ece08ef09c 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1193,7 +1193,7 @@ function hasOnlyTransactionsWithPendingRoutes(iouReportID: string | undefined): * If the report is a thread and has a chat type set, it is a workspace chat. */ function isWorkspaceThread(report: OnyxEntry): boolean { - return isThread(report) && isChatReport(report) && !!getChatType(report); + return isThread(report) && isChatReport(report) && !isGroupChat(report) && !!getChatType(report); } /** From 2de1bb225e1dfbe8ddca5af662bad4395aed5a1a Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 12:57:42 -1000 Subject: [PATCH 47/61] Fix issue for future threads as well --- src/CONST.ts | 3 +++ src/libs/ReportUtils.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index 0fa1c64be44d..f8a15351ee32 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -59,6 +59,9 @@ const cardActiveStates: number[] = [2, 3, 4, 7]; const CONST = { MERGED_ACCOUNT_PREFIX: 'MERGED_', DEFAULT_POLICY_ROOM_CHAT_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL], + + // Note: Group excluded as it is not tied to any Workspace + WORKSPACE_ROOM_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL, chatTypes.POLICY_ROOM, chatTypes.POLICY_EXPENSE_CHAT, chatTypes.SELF_DM], ANDROID_PACKAGE_NAME, ANIMATED_TRANSITION: 300, ANIMATED_TRANSITION_FROM_VALUE: 100, diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 82ece08ef09c..72eea831350c 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1193,7 +1193,7 @@ function hasOnlyTransactionsWithPendingRoutes(iouReportID: string | undefined): * If the report is a thread and has a chat type set, it is a workspace chat. */ function isWorkspaceThread(report: OnyxEntry): boolean { - return isThread(report) && isChatReport(report) && !isGroupChat(report) && !!getChatType(report); + return isThread(report) && isChatReport(report) && CONST.WORKSPACE_ROOM_TYPES.includes(getChatType(report)); } /** From a4225b8acd157bdb3548f9ea8afa79177b53011c Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 12:59:28 -1000 Subject: [PATCH 48/61] also self DM --- src/CONST.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index f8a15351ee32..f4c7ecb5215a 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -60,8 +60,8 @@ const CONST = { MERGED_ACCOUNT_PREFIX: 'MERGED_', DEFAULT_POLICY_ROOM_CHAT_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL], - // Note: Group excluded as it is not tied to any Workspace - WORKSPACE_ROOM_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL, chatTypes.POLICY_ROOM, chatTypes.POLICY_EXPENSE_CHAT, chatTypes.SELF_DM], + // Note: Group and Self-DM excluded as these are not tied to a Workspace + WORKSPACE_ROOM_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL, chatTypes.POLICY_ROOM, chatTypes.POLICY_EXPENSE_CHAT], ANDROID_PACKAGE_NAME, ANIMATED_TRANSITION: 300, ANIMATED_TRANSITION_FROM_VALUE: 100, From 54ae619460300cad448d1f153deee9daa9308cc2 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 13:05:08 -1000 Subject: [PATCH 49/61] Fix ts --- src/libs/ReportUtils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 72eea831350c..6ff941771f94 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1193,7 +1193,8 @@ function hasOnlyTransactionsWithPendingRoutes(iouReportID: string | undefined): * If the report is a thread and has a chat type set, it is a workspace chat. */ function isWorkspaceThread(report: OnyxEntry): boolean { - return isThread(report) && isChatReport(report) && CONST.WORKSPACE_ROOM_TYPES.includes(getChatType(report)); + const chatType = getChatType(report) ?? ''; + return isThread(report) && isChatReport(report) && CONST.WORKSPACE_ROOM_TYPES.includes(chatType); } /** From cdc85349708da77bdda048af686cd6b9ebb8ca2a Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 13:18:33 -1000 Subject: [PATCH 50/61] typescript. is it smart? sometimes. --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 6ff941771f94..479569b35bc8 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1194,7 +1194,7 @@ function hasOnlyTransactionsWithPendingRoutes(iouReportID: string | undefined): */ function isWorkspaceThread(report: OnyxEntry): boolean { const chatType = getChatType(report) ?? ''; - return isThread(report) && isChatReport(report) && CONST.WORKSPACE_ROOM_TYPES.includes(chatType); + return isThread(report) && isChatReport(report) && typeof chatType === 'string' && CONST.WORKSPACE_ROOM_TYPES.includes(chatType); } /** From 8eced8e9f73f89b086b62e26ddd6ad4dff16eaf3 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 13:22:39 -1000 Subject: [PATCH 51/61] Use some instead to fool typescript --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 479569b35bc8..9ca43d67e0d3 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1194,7 +1194,7 @@ function hasOnlyTransactionsWithPendingRoutes(iouReportID: string | undefined): */ function isWorkspaceThread(report: OnyxEntry): boolean { const chatType = getChatType(report) ?? ''; - return isThread(report) && isChatReport(report) && typeof chatType === 'string' && CONST.WORKSPACE_ROOM_TYPES.includes(chatType); + return isThread(report) && isChatReport(report) && CONST.WORKSPACE_ROOM_TYPES.some(type => chatType === type); } /** From cc757f0c4ce23e9e7b651dea13b456a84619aaee Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Sat, 30 Mar 2024 04:56:38 +0530 Subject: [PATCH 52/61] update according to suggestions. Signed-off-by: Krishna Gupta --- src/components/ReportActionItem/ReportPreview.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 33ce01212b2f..2581359b4543 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -225,14 +225,14 @@ function ReportPreview({ /* Show subtitle if at least one of the money requests is not being smart scanned, and either: - There is more than one money request – in this case, the "X requests, Y scanning" subtitle is shown; - - There is only one money request, it has a receipt and is not being smart scanned – in this case, the request merchant is shown; + - There is only one money request, it has a receipt and is not being smart scanned – in this case, the request merchant or description is shown; * There is an edge case when there is only one distance request with a pending route and amount = 0. - In this case, we don't want to show the merchant because it says: "Pending route...", which is already displayed in the amount field. + In this case, we don't want to show the merchant or description because it says: "Pending route...", which is already displayed in the amount field. */ - const shouldShowSingleRequestMerchant = numberOfRequests === 1 && !!formattedMerchant && !(hasOnlyTransactionsWithPendingRoutes && !totalDisplaySpend); - const shouldShowSingleRequestDescription = numberOfRequests === 1 && !!formattedDescription && !shouldShowSingleRequestMerchant; - const shouldShowSubtitle = !isScanning && (shouldShowSingleRequestMerchant || shouldShowSingleRequestDescription || numberOfRequests > 1); + const shouldShowSingleRequestMerchantOrDescription = + numberOfRequests === 1 && (!!formattedMerchant || !!formattedDescription) && !(hasOnlyTransactionsWithPendingRoutes && !totalDisplaySpend); + const shouldShowSubtitle = !isScanning && (shouldShowSingleRequestMerchantOrDescription || numberOfRequests > 1); return ( Date: Fri, 29 Mar 2024 13:32:41 -1000 Subject: [PATCH 53/61] Remove null coalesce since we are using some --- src/libs/ReportUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 9ca43d67e0d3..11dd86a32ed3 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1193,8 +1193,8 @@ function hasOnlyTransactionsWithPendingRoutes(iouReportID: string | undefined): * If the report is a thread and has a chat type set, it is a workspace chat. */ function isWorkspaceThread(report: OnyxEntry): boolean { - const chatType = getChatType(report) ?? ''; - return isThread(report) && isChatReport(report) && CONST.WORKSPACE_ROOM_TYPES.some(type => chatType === type); + const chatType = getChatType(report); + return isThread(report) && isChatReport(report) && CONST.WORKSPACE_ROOM_TYPES.some((type) => chatType === type); } /** From 04cfc03ba3e0e7ca59f9e370613a8471bb244910 Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Fri, 29 Mar 2024 16:39:21 -1000 Subject: [PATCH 54/61] Clean up logic for creating Group Chats --- src/libs/actions/IOU.ts | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 30892bef5760..4702b7a18958 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2249,15 +2249,30 @@ function trackExpense( } function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { + // The existing chat report could be passed as reportID or exist on the sole "participant" (in this case a report option) const existingChatReportID = existingSplitChatReportID || participants[0].reportID; + + // Check if the report is available locally if we do have one let existingSplitChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`]; - if (!existingSplitChatReport) { - existingSplitChatReport = participants.length < 2 ? ReportUtils.getChatByParticipants(participantAccountIDs) : null; + + // If we do not have one locally then we will search for a chat with the same participants (only for 1:1 chats). + const shouldGetOrCreateOneOneDM = participants.length < 2; + if (!existingSplitChatReport && shouldGetOrCreateOneOneDM) { + existingSplitChatReport = ReportUtils.getChatByParticipants(participantAccountIDs); + } + + // We found an existing chat report we are done... + if (existingSplitChatReport) { + // Yes, these are the same, but give the caller a way to identify if we created a new report or not + return {existingSplitChatReport, splitChatReport: existingSplitChatReport}; } - let newChat: ReportUtils.OptimisticChatReport | EmptyObject = {}; + + // No existing chat by this point we need to create it const allParticipantsAccountIDs = [...participantAccountIDs, currentUserAccountID]; - if (!existingSplitChatReport && participants.length > 1) { - newChat = ReportUtils.buildOptimisticChatReport( + + // Create a Group Chat if we have multiple participants + if (participants.length > 1) { + const splitChatReport = ReportUtils.buildOptimisticChatReport( allParticipantsAccountIDs, '', CONST.REPORT.CHAT_TYPE.GROUP, @@ -2269,12 +2284,12 @@ function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, undefined, CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, ); + return {existingSplitChatReport: null, splitChatReport}; } - if (isEmptyObject(newChat)) { - newChat = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); - } - const splitChatReport = existingSplitChatReport ?? newChat; - return {splitChatReport, existingSplitChatReport}; + + // Otherwise, create a new 1:1 chat report + const splitChatReport = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); + return {existingSplitChatReport: null, splitChatReport}; } /** From 21ca2908711377c0f09096c128393b81bada7270 Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Sat, 30 Mar 2024 08:57:23 +0530 Subject: [PATCH 55/61] fix: Task - No error of exceeding limit when changing title of existing task & system message posted. Signed-off-by: Krishna Gupta --- src/pages/tasks/TaskTitlePage.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pages/tasks/TaskTitlePage.tsx b/src/pages/tasks/TaskTitlePage.tsx index 009983beac3e..99558efaeb03 100644 --- a/src/pages/tasks/TaskTitlePage.tsx +++ b/src/pages/tasks/TaskTitlePage.tsx @@ -12,6 +12,7 @@ import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalD import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import withReportOrNotFound from '@pages/home/report/withReportOrNotFound'; @@ -32,7 +33,9 @@ function TaskTitlePage({report, currentUserPersonalDetails}: TaskTitlePageProps) const errors: FormInputErrors = {}; if (!title) { - errors.title = 'newTaskPage.pleaseEnterTaskName'; + ErrorUtils.addErrorMessage(errors, INPUT_IDS.TITLE, 'newTaskPage.pleaseEnterTaskName'); + } else if (title.length > CONST.TITLE_CHARACTER_LIMIT) { + ErrorUtils.addErrorMessage(errors, INPUT_IDS.TITLE, ['common.error.characterLimitExceedCounter', {length: title.length, limit: CONST.TITLE_CHARACTER_LIMIT}]); } return errors; From 471895feeed895ea0c79ba818ecd43039eead80a Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 30 Mar 2024 13:41:28 +0800 Subject: [PATCH 56/61] renaming --- ...ansitionEnd.tsx => withNavigationTransitionEnd.tsx} | 10 +++++----- src/pages/RoomInvitePage.tsx | 8 ++++---- src/pages/tasks/TaskAssigneeSelectorModal.tsx | 8 ++++---- src/pages/workspace/WorkspaceInvitePage.tsx | 8 ++++---- 4 files changed, 17 insertions(+), 17 deletions(-) rename src/components/{withTransitionEnd.tsx => withNavigationTransitionEnd.tsx} (76%) diff --git a/src/components/withTransitionEnd.tsx b/src/components/withNavigationTransitionEnd.tsx similarity index 76% rename from src/components/withTransitionEnd.tsx rename to src/components/withNavigationTransitionEnd.tsx index b00e0a9f4f34..417d8828c1e4 100644 --- a/src/components/withTransitionEnd.tsx +++ b/src/components/withNavigationTransitionEnd.tsx @@ -5,10 +5,10 @@ import React, {useEffect, useState} from 'react'; import getComponentDisplayName from '@libs/getComponentDisplayName'; import type {RootStackParamList} from '@libs/Navigation/types'; -type WithTransitionEndProps = {didScreenTransitionEnd: boolean}; +type WithNavigationTransitionEndProps = {didScreenTransitionEnd: boolean}; export default function (WrappedComponent: ComponentType>): React.ComponentType> { - function WithTransitionEnd(props: TProps, ref: ForwardedRef) { + function WithNavigationTransitionEnd(props: TProps, ref: ForwardedRef) { const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false); const navigation = useNavigation>(); @@ -31,9 +31,9 @@ export default function (WrappedComponent: ComponentType; }; -type RoomInvitePageProps = RoomInvitePageOnyxProps & WithReportOrNotFoundProps & WithTransitionEndProps; +type RoomInvitePageProps = RoomInvitePageOnyxProps & WithReportOrNotFoundProps & WithNavigationTransitionEndProps; type Sections = Array>>; @@ -245,7 +245,7 @@ function RoomInvitePage({betas, personalDetails, report, policies, didScreenTran RoomInvitePage.displayName = 'RoomInvitePage'; -export default withTransitionEnd( +export default withNavigationTransitionEnd( withReportOrNotFound()( withOnyx({ personalDetails: { diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.tsx b/src/pages/tasks/TaskAssigneeSelectorModal.tsx index f293c5ff03c4..bb199ddc905f 100644 --- a/src/pages/tasks/TaskAssigneeSelectorModal.tsx +++ b/src/pages/tasks/TaskAssigneeSelectorModal.tsx @@ -14,8 +14,8 @@ import type {ListItem} from '@components/SelectionList/types'; import UserListItem from '@components/SelectionList/UserListItem'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; -import withTransitionEnd from '@components/withTransitionEnd'; -import type {WithTransitionEndProps} from '@components/withTransitionEnd'; +import withNavigationTransitionEnd from '@components/withNavigationTransitionEnd'; +import type {WithNavigationTransitionEndProps} from '@components/withNavigationTransitionEnd'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; @@ -43,7 +43,7 @@ type UseOptions = { reports: OnyxCollection; }; -type TaskAssigneeSelectorModalProps = TaskAssigneeSelectorModalOnyxProps & WithCurrentUserPersonalDetailsProps & WithTransitionEndProps; +type TaskAssigneeSelectorModalProps = TaskAssigneeSelectorModalOnyxProps & WithCurrentUserPersonalDetailsProps & WithNavigationTransitionEndProps; function useOptions({reports}: UseOptions) { const allPersonalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; @@ -241,4 +241,4 @@ const TaskAssigneeSelectorModalWithOnyx = withOnyx; @@ -327,7 +327,7 @@ function WorkspaceInvitePage({ WorkspaceInvitePage.displayName = 'WorkspaceInvitePage'; -export default withTransitionEnd( +export default withNavigationTransitionEnd( withPolicyAndFullscreenLoading( withOnyx({ personalDetails: { From 9e7f5b790a84b8c359dab6e31c6428690ce6ace7 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 30 Mar 2024 13:56:20 +0800 Subject: [PATCH 57/61] update test --- tests/unit/ViolationUtilsTest.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/unit/ViolationUtilsTest.ts b/tests/unit/ViolationUtilsTest.ts index e112f2908590..8389086f8720 100644 --- a/tests/unit/ViolationUtilsTest.ts +++ b/tests/unit/ViolationUtilsTest.ts @@ -61,16 +61,6 @@ describe('getViolationsOnyxData', () => { expect(result.value).toEqual(expect.arrayContaining(transactionViolations)); }); - it('should not add violation when the transaction is partial', () => { - const partialTransaction = {...transaction, amount: 0, merchant: CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT}; - transactionViolations = [ - {name: 'duplicatedTransaction', type: 'violation'}, - {name: 'receiptRequired', type: 'violation'}, - ]; - const result = ViolationsUtils.getViolationsOnyxData(partialTransaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); - expect(result.value).toEqual(transactionViolations); - }); - describe('policyRequiresCategories', () => { beforeEach(() => { policyRequiresCategories = true; @@ -95,6 +85,12 @@ describe('getViolationsOnyxData', () => { expect(result.value).not.toContainEqual(categoryOutOfPolicyViolation); }); + it('should not add a category violation when the transaction is partial', () => { + const partialTransaction = {...transaction, amount: 0, merchant: CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, category: undefined}; + const result = ViolationsUtils.getViolationsOnyxData(partialTransaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); + expect(result.value).not.toContainEqual(missingCategoryViolation); + }); + it('should add categoryOutOfPolicy violation to existing violations if they exist', () => { transaction.category = 'Bananas'; transactionViolations = [ @@ -172,6 +168,12 @@ describe('getViolationsOnyxData', () => { expect(result.value).toEqual([]); }); + it('should not add a tag violation when the transaction is partial', () => { + const partialTransaction = {...transaction, amount: 0, merchant: CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, tag: undefined}; + const result = ViolationsUtils.getViolationsOnyxData(partialTransaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); + expect(result.value).not.toContainEqual(missingTagViolation); + }); + it('should add tagOutOfPolicy violation to existing violations if transaction has tag that is not in the policy', () => { transaction.tag = 'Bananas'; transactionViolations = [ From 37a9a6a888efae02094d54856d175a26043cf11b Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 30 Mar 2024 14:04:47 +0800 Subject: [PATCH 58/61] prettier --- src/libs/Violations/ViolationsUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index d3c1e6e19cd0..83f3b2fcc154 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -2,8 +2,8 @@ import reject from 'lodash/reject'; import Onyx from 'react-native-onyx'; import type {OnyxUpdate} from 'react-native-onyx'; import type {Phrase, PhraseParameters} from '@libs/Localize'; -import * as TransactionUtils from '@libs/TransactionUtils'; import {getSortedTagKeys} from '@libs/PolicyUtils'; +import * as TransactionUtils from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; From 3ca25eeccbfe4cef6c3ab4837ea05b42f96c9955 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 30 Mar 2024 15:17:52 +0800 Subject: [PATCH 59/61] fix removed user isn't strikethrough-ed --- src/components/OptionRow.tsx | 22 +++++++++++----------- src/libs/actions/Policy.ts | 5 ----- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/components/OptionRow.tsx b/src/components/OptionRow.tsx index c72cdd1fd898..90ccff47b2b9 100644 --- a/src/components/OptionRow.tsx +++ b/src/components/OptionRow.tsx @@ -154,14 +154,14 @@ function OptionRow({ } return ( - - - {(hovered) => ( + + {(hovered) => ( + )} - )} - - + + )} + ); } diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 0c6bd7682add..3c34e823ac9a 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -780,15 +780,12 @@ function removeOptimisticAnnounceRoomMembers(policyID: string, accountIDs: numbe } if (announceReport?.participantAccountIDs) { - const remainUsers = announceReport.participantAccountIDs.filter((e) => !accountIDs.includes(e)); const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, announceReport?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); announceRoomMembers.onyxOptimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport.reportID}`, value: { - participantAccountIDs: [...remainUsers], - visibleChatMemberAccountIDs: [...remainUsers], pendingChatMembers, }, }); @@ -797,8 +794,6 @@ function removeOptimisticAnnounceRoomMembers(policyID: string, accountIDs: numbe onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport.reportID}`, value: { - participantAccountIDs: announceReport.participantAccountIDs, - visibleChatMemberAccountIDs: announceReport.visibleChatMemberAccountIDs, pendingChatMembers: announceReport?.pendingChatMembers ?? null, }, }); From 990b6d3815af91f2a087af79010b0340398b5a92 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Mon, 1 Apr 2024 10:02:10 +0700 Subject: [PATCH 60/61] merge main --- src/pages/iou/steps/NewRequestAmountPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/steps/NewRequestAmountPage.tsx b/src/pages/iou/steps/NewRequestAmountPage.tsx index 685098c47afa..0528af502e99 100644 --- a/src/pages/iou/steps/NewRequestAmountPage.tsx +++ b/src/pages/iou/steps/NewRequestAmountPage.tsx @@ -77,7 +77,7 @@ function NewRequestAmountPage({route, iou, report, selectedTab}: NewRequestAmoun if (!iou?.id) { return; } - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, report?.reportID), true); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, '1', reportID), true); return; } const moneyRequestID = `${iouType}${reportID}`; @@ -87,7 +87,7 @@ function NewRequestAmountPage({route, iou, report, selectedTab}: NewRequestAmoun } if (!isDistanceRequestTab && (!iou?.participants?.length || iou?.amount === 0 || shouldReset)) { - Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, report?.reportID), true); + Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, '1', reportID), true); } } From e183469e0669dac9347cfb0720a0b754132741a8 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Mon, 1 Apr 2024 10:45:27 +0530 Subject: [PATCH 61/61] display link as inline code --- contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md b/contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md index 932dcc8d5e20..f2a2efca1f5f 100644 --- a/contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md +++ b/contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md @@ -24,4 +24,4 @@ C+ are contributors who are experienced at working with Expensify and have gaine ## How to join? -Email contributors@expensify.com and include "C+ Team Application" in the subject line if you’re interested in joining. Please include your GitHub username and a link to the PRs you've authored that have been merged. ie. https://github.com/Expensify/App/pulls?q=is%3Apr+author%3Aparasharrajat+is%3Amerged +Email contributors@expensify.com and include "C+ Team Application" in the subject line if you’re interested in joining. Please include your GitHub username and a link to the PRs you've authored that have been merged. ie. `https://github.com/Expensify/App/pulls?q=is%3Apr+author%3Aparasharrajat+is%3Amerged`