From 68d480ddc07f37d0644c9bfe4d42f62abf195093 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 17 Apr 2024 14:31:32 +0200 Subject: [PATCH 01/28] Display rter violation in MoneyRequestHeader & ReportPreview --- src/components/MoneyRequestHeader.tsx | 66 ++++++++++++------- .../ReportActionItem/ReportPreview.tsx | 21 +++++- src/languages/en.ts | 2 + src/languages/es.ts | 2 + src/libs/TransactionUtils.ts | 24 ++++++- src/types/onyx/TransactionViolation.ts | 1 + 6 files changed, 88 insertions(+), 28 deletions(-) diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 2f80cf3c6e59f..a7511b44f049e 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -1,7 +1,7 @@ import React, {useCallback, useEffect, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -16,7 +16,7 @@ import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Policy, Report, ReportAction, ReportActions, Session, Transaction} from '@src/types/onyx'; +import type {Policy, Report, ReportAction, ReportActions, Session, Transaction, TransactionViolations} from '@src/types/onyx'; import type {OriginalMessageIOU} from '@src/types/onyx/OriginalMessage'; import ConfirmModal from './ConfirmModal'; import HeaderWithBackButton from './HeaderWithBackButton'; @@ -37,6 +37,9 @@ type MoneyRequestHeaderOnyxProps = { /** All the data for the transaction */ transaction: OnyxEntry; + /** The violations of the transaction */ + transactionViolations: OnyxCollection; + /** All report actions */ // eslint-disable-next-line react/no-unused-prop-types parentReportActions: OnyxEntry; @@ -56,7 +59,7 @@ type MoneyRequestHeaderProps = MoneyRequestHeaderOnyxProps & { parentReportAction: OnyxEntry; }; -function MoneyRequestHeader({session, parentReport, report, parentReportAction, transaction, shownHoldUseExplanation = false, policy}: MoneyRequestHeaderProps) { +function MoneyRequestHeader({session, parentReport, report, parentReportAction, transactionViolations, transaction, shownHoldUseExplanation = false, policy}: MoneyRequestHeaderProps) { const styles = useThemeStyles(); const theme = useTheme(); const {translate} = useLocalize(); @@ -86,9 +89,6 @@ function MoneyRequestHeader({session, parentReport, report, parentReportAction, setIsDeleteModalVisible(false); }, [parentReport?.reportID, parentReportAction, setIsDeleteModalVisible]); - const isScanning = TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction); - const isPending = TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction); - const isDeletedParentAction = ReportActionsUtils.isDeletedAction(parentReportAction); const canHoldOrUnholdRequest = !isSettled && !isApproved && !isDeletedParentAction; @@ -106,6 +106,21 @@ function MoneyRequestHeader({session, parentReport, report, parentReportAction, } }; + const getPendingType = () => { + if (TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction)) { + return {pendingType: 'PENDING', pendingTitle: translate('iou.pending'), pendingDescription: translate('iou.transactionPendingText')}; + } + if (TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction)) { + return {pendingType: 'SCANNING', pendingTitle: ReceiptScan, pendingDescription: translate('iou.receiptScanInProgressDescription')}; + } + if (TransactionUtils.hasPendingRTERViolation(TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { + return {pendingType: 'RTER', pendingTitle: Expensicons.Hourglass, pendingDescription: translate('iou.pendingMatchWithCreditCardDescription')}; + } + return {}; + }; + + const {pendingType, pendingTitle, pendingDescription} = getPendingType(); + useEffect(() => { if (canDeleteRequest) { return; @@ -170,7 +185,7 @@ function MoneyRequestHeader({session, parentReport, report, parentReportAction, <> Navigation.goBack(undefined, false, true)} /> - {isPending && ( - - )} - {isScanning && ( + {pendingType && ( + typeof pendingTitle === 'string' ? ( + pendingTitle + ) : ( + + ) } - description={translate('iou.receiptScanInProgressDescription')} + description={pendingDescription} shouldShowBorderBottom /> )} @@ -230,7 +242,7 @@ function MoneyRequestHeader({session, parentReport, report, parentReportAction, MoneyRequestHeader.displayName = 'MoneyRequestHeader'; -const MoneyRequestHeaderWithTransaction = withOnyx>({ +const MoneyRequestHeaderWithTransaction = withOnyx>({ transaction: { key: ({report, parentReportActions}) => { const parentReportAction = (report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : {}) as ReportAction & OriginalMessageIOU; @@ -241,9 +253,15 @@ const MoneyRequestHeaderWithTransaction = withOnyx, Omit>({ +export default withOnyx< + Omit, + Omit +>({ session: { key: ONYXKEYS.SESSION, }, diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 190343e48abd0..98f4cae7dee44 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -26,6 +26,7 @@ import * as ReportActionUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import type {ContextMenuAnchor} from '@pages/home/report/ContextMenu/ReportActionContextMenu'; +import variables from '@styles/variables'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; @@ -140,6 +141,8 @@ function ReportPreview({ const hasErrors = hasMissingSmartscanFields || (canUseViolations && ReportUtils.hasViolations(iouReportID, transactionViolations)) || ReportUtils.hasActionsWithErrors(iouReportID); const lastThreeTransactionsWithReceipts = transactionsWithReceipts.slice(-3); const lastThreeReceipts = lastThreeTransactionsWithReceipts.map((transaction) => ReceiptUtils.getThumbnailAndImageURIs(transaction)); + const showRTERViolationMessage = + allTransactions.length === 1 && TransactionUtils.hasPendingUI(allTransactions[0], TransactionUtils.getTransactionViolations(allTransactions[0].transactionID, transactionViolations)); let formattedMerchant = numberOfRequests === 1 ? TransactionUtils.getMerchant(allTransactions[0]) : null; const formattedDescription = numberOfRequests === 1 ? TransactionUtils.getDescription(allTransactions[0]) : null; @@ -148,7 +151,7 @@ function ReportPreview({ formattedMerchant = null; } - const shouldShowSubmitButton = isOpenExpenseReport && reimbursableSpend !== 0; + const shouldShowSubmitButton = isOpenExpenseReport && reimbursableSpend !== 0 && !showRTERViolationMessage; const shouldDisableSubmitButton = shouldShowSubmitButton && !ReportUtils.isAllowedToSubmitDraftExpenseReport(iouReport); // The submit button should be success green colour only if the user is submitter and the policy does not have Scheduled Submit turned on @@ -235,6 +238,9 @@ function ReportPreview({ const parsedSubtitle = new ExpensiMark().replace(formattedDescription ?? moneyRequestComment); return {isSupportTextHtml: !!parsedSubtitle, supportText: parsedSubtitle ? `${parsedSubtitle}` : ''}; } + // if (true) { + // return {isSupportTextHtml: false, supportText: 'ABC'}; + // } return { isSupportTextHtml: false, supportText: translate('iou.requestCount', { @@ -318,6 +324,19 @@ function ReportPreview({ )} + {showRTERViolationMessage && ( + + + + {translate('iou.pendingMatchWithCreditCard')} + + + )} {shouldShowSettlementButton && ( diff --git a/src/languages/en.ts b/src/languages/en.ts index 314f4f990a490..5667b3fc83e70 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -633,6 +633,8 @@ export default { canceled: 'Canceled', posted: 'Posted', deleteReceipt: 'Delete receipt', + pendingMatchWithCreditCard: 'Receipt pending match with credit card.', + pendingMatchWithCreditCardDescription: 'Receipt pending match with credit card. Marks as cash to ignore and request payment.', routePending: 'Route pending...', receiptScanning: 'Receipt scanning…', receiptScanInProgress: 'Receipt scan in progress.', diff --git a/src/languages/es.ts b/src/languages/es.ts index 387f2b4c1841c..4366d61425aa6 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -629,6 +629,8 @@ export default { canceled: 'Canceló', posted: 'Contabilizado', deleteReceipt: 'Eliminar recibo', + pendingMatchWithCreditCard: 'Recibo pendiente de conciliar con la tarjeta de crédito.', + pendingMatchWithCreditCardDescription: 'Recibo pendiente de conciliar con tarjeta de crédito. Marcar como efectivo para ignorar y solicitar pago.', routePending: 'Ruta pendiente...', receiptScanning: 'Escaneo en curso…', receiptScanInProgress: 'Escaneo en curso…', diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 89b89ff7b584c..a54fa66191a4a 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -5,7 +5,7 @@ import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {RecentWaypoint, Report, TaxRate, TaxRates, TaxRatesWithDefault, Transaction, TransactionViolation} from '@src/types/onyx'; +import type {RecentWaypoint, Report, TaxRate, TaxRates, TaxRatesWithDefault, Transaction, TransactionViolation, TransactionViolations} from '@src/types/onyx'; import type {Comment, Receipt, TransactionChanges, TransactionPendingFieldsKey, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {IOURequestType} from './actions/IOU'; @@ -514,6 +514,22 @@ function hasMissingSmartscanFields(transaction: OnyxEntry): boolean return Boolean(transaction && !isDistanceRequest(transaction) && !isReceiptBeingScanned(transaction) && areRequiredFieldsEmpty(transaction)); } +/** + * Check if there is pending rter violation in transactionViolations. + */ +function hasPendingRTERViolation(transactionViolations?: TransactionViolations | null): boolean { + return Boolean( + transactionViolations?.some((transactionViolation: TransactionViolation) => transactionViolation.name === CONST.VIOLATIONS.RTER && transactionViolation.data?.pendingPattern), + ); +} + +/** + * Check if the transaction is pending or has a pending rter violation. + */ +function hasPendingUI(transaction: OnyxEntry, transactionViolations?: TransactionViolations | null): boolean { + return Boolean(isReceiptBeingScanned(transaction) || isPending(transaction) || (transaction && hasPendingRTERViolation(transactionViolations))); +} + /** * Check if the transaction has a defined route */ @@ -605,13 +621,13 @@ function isOnHold(transaction: OnyxEntry): boolean { /** * Checks if any violations for the provided transaction are of type 'violation' */ -function hasViolation(transactionID: string, transactionViolations: OnyxCollection): boolean { +function hasViolation(transactionID: string, transactionViolations: OnyxCollection): boolean { return Boolean( transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID]?.some((violation: TransactionViolation) => violation.type === CONST.VIOLATION_TYPES.VIOLATION), ); } -function getTransactionViolations(transactionID: string, transactionViolations: OnyxCollection): TransactionViolation[] | null { +function getTransactionViolations(transactionID: string, transactionViolations: OnyxCollection | null): TransactionViolations | null { return transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID] ?? null; } @@ -698,6 +714,8 @@ export { isCreatedMissing, areRequiredFieldsEmpty, hasMissingSmartscanFields, + hasPendingRTERViolation, + hasPendingUI, getWaypointIndex, waypointHasValidAddress, getRecentTransactions, diff --git a/src/types/onyx/TransactionViolation.ts b/src/types/onyx/TransactionViolation.ts index 28de4582bd5e5..ab2037ff336ab 100644 --- a/src/types/onyx/TransactionViolation.ts +++ b/src/types/onyx/TransactionViolation.ts @@ -29,6 +29,7 @@ type TransactionViolation = { tagListIndex?: number; tagListName?: string; errorIndexes?: number[]; + pendingPattern?: boolean; }; }; From 3409d9cfcfb71aefbfa985ac0834f7b4115ba88b Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 17 Apr 2024 16:36:57 +0200 Subject: [PATCH 02/28] Display rter violations in MoneyReportHeader --- src/components/MoneyReportHeader.tsx | 29 +++++++++++++++++++++++++--- src/libs/TransactionUtils.ts | 24 ++++++++++++++++++----- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 14227d6a20510..b68cbd4641374 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -3,6 +3,7 @@ import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; +import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as CurrencyUtils from '@libs/CurrencyUtils'; @@ -10,6 +11,8 @@ import * as HeaderUtils from '@libs/HeaderUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import * as TransactionUtils from '@libs/TransactionUtils'; +import variables from '@styles/variables'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -20,8 +23,10 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject'; import Button from './Button'; import ConfirmModal from './ConfirmModal'; import HeaderWithBackButton from './HeaderWithBackButton'; +import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import MoneyReportHeaderStatusBar from './MoneyReportHeaderStatusBar'; +import MoneyRequestHeaderStatusBar from './MoneyRequestHeaderStatusBar'; import ProcessMoneyReportHoldMenu from './ProcessMoneyReportHoldMenu'; import SettlementButton from './SettlementButton'; @@ -56,6 +61,7 @@ type MoneyReportHeaderProps = MoneyReportHeaderOnyxProps & { function MoneyReportHeader({session, policy, chatReport, nextStep, report: moneyRequestReport, transactionThreadReport, reportActions}: MoneyReportHeaderProps) { const styles = useThemeStyles(); + const theme = useTheme(); const [isDeleteRequestModalVisible, setIsDeleteRequestModalVisible] = useState(false); const {translate} = useLocalize(); const {windowWidth, isSmallScreenWidth} = useWindowDimensions(); @@ -83,6 +89,9 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money const isDraft = ReportUtils.isOpenExpenseReport(moneyRequestReport); const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false); + const transactionIDs = TransactionUtils.getAllReportTransactions(chatReport?.reportID).map((transaction) => transaction.transactionID); + const haveAllPendingRTERViolation = TransactionUtils.haveAllPendingRTERViolation(transactionIDs); + const cancelPayment = useCallback(() => { if (!chatReport) { return; @@ -97,9 +106,9 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money const shouldDisableApproveButton = shouldShowApproveButton && !ReportUtils.isAllowedToApproveExpenseReport(moneyRequestReport); - const shouldShowSettlementButton = shouldShowPayButton || shouldShowApproveButton; + const shouldShowSettlementButton = (shouldShowPayButton || shouldShowApproveButton) && !haveAllPendingRTERViolation; - const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0; + const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !haveAllPendingRTERViolation; const shouldDisableSubmitButton = shouldShowSubmitButton && !ReportUtils.isAllowedToSubmitDraftExpenseReport(moneyRequestReport); const isFromPaidPolicy = policyType === CONST.POLICY.TYPE.TEAM || policyType === CONST.POLICY.TYPE.CORPORATE; const shouldShowNextStep = !ReportUtils.isClosedExpenseReportWithNoExpenses(moneyRequestReport) && isFromPaidPolicy && !!nextStep?.message?.length; @@ -188,7 +197,7 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money shouldShowBackButton={isSmallScreenWidth} onBackButtonPress={() => Navigation.goBack(undefined, false, true)} // Shows border if no buttons or next steps are showing below the header - shouldShowBorderBottom={!(shouldShowAnyButton && isSmallScreenWidth) && !(shouldShowNextStep && !isSmallScreenWidth)} + shouldShowBorderBottom={!(shouldShowAnyButton && isSmallScreenWidth) && !(shouldShowNextStep && !isSmallScreenWidth) && !haveAllPendingRTERViolation} shouldShowThreeDotsButton threeDotsMenuItems={threeDotsMenuItems} threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)} @@ -226,6 +235,20 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money )} + {haveAllPendingRTERViolation && ( + + } + description={translate('iou.pendingMatchWithCreditCardDescription')} + shouldShowBorderBottom + /> + )} {shouldShowSettlementButton && isSmallScreenWidth && ( diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index a54fa66191a4a..df21a992a0474 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -16,7 +16,6 @@ import * as NumberUtils from './NumberUtils'; import {getCleanedTagName} from './PolicyUtils'; let allTransactions: OnyxCollection = {}; - Onyx.connect({ key: ONYXKEYS.COLLECTION.TRANSACTION, waitForCollectionCallback: true, @@ -28,6 +27,13 @@ Onyx.connect({ }, }); +let allTransactionViolations: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, + waitForCollectionCallback: true, + callback: (value) => (allTransactionViolations = value), +}); + let allReports: OnyxCollection; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT, @@ -514,6 +520,10 @@ function hasMissingSmartscanFields(transaction: OnyxEntry): boolean return Boolean(transaction && !isDistanceRequest(transaction) && !isReceiptBeingScanned(transaction) && areRequiredFieldsEmpty(transaction)); } +function getTransactionViolations(transactionID: string, transactionViolations: OnyxCollection | null): TransactionViolations | null { + return transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID] ?? null; +} + /** * Check if there is pending rter violation in transactionViolations. */ @@ -523,6 +533,13 @@ function hasPendingRTERViolation(transactionViolations?: TransactionViolations | ); } +/** + * Check if there is pending rter violation in transactionViolations. + */ +function haveAllPendingRTERViolation(transactionIds: string[]): boolean { + return transactionIds.map((transactionId) => hasPendingRTERViolation(getTransactionViolations(transactionId, allTransactionViolations))).every((value) => value); +} + /** * Check if the transaction is pending or has a pending rter violation. */ @@ -627,10 +644,6 @@ function hasViolation(transactionID: string, transactionViolations: OnyxCollecti ); } -function getTransactionViolations(transactionID: string, transactionViolations: OnyxCollection | null): TransactionViolations | null { - return transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID] ?? null; -} - /** * this is the formulae to calculate tax */ @@ -715,6 +728,7 @@ export { areRequiredFieldsEmpty, hasMissingSmartscanFields, hasPendingRTERViolation, + haveAllPendingRTERViolation, hasPendingUI, getWaypointIndex, waypointHasValidAddress, From 5275089ec8167f03667de8e53ecef56532a492ee Mon Sep 17 00:00:00 2001 From: smelaa Date: Thu, 18 Apr 2024 14:33:15 +0200 Subject: [PATCH 03/28] Fix util function --- src/libs/TransactionUtils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 44ccd387e670a..3f374d46a6de4 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -535,7 +535,8 @@ function hasPendingRTERViolation(transactionViolations?: TransactionViolations | * Check if there is pending rter violation in transactionViolations. */ function haveAllPendingRTERViolation(transactionIds: string[]): boolean { - return transactionIds.map((transactionId) => hasPendingRTERViolation(getTransactionViolations(transactionId, allTransactionViolations))).every((value) => value); + const transactionsWithRTERViolations = transactionIds.map((transactionId) => hasPendingRTERViolation(getTransactionViolations(transactionId, allTransactionViolations))); + return transactionsWithRTERViolations.length !== 0 && transactionsWithRTERViolations.every((value) => value === true); } /** From 046dbc2d40d1c88603b2f6eb2c408b42e0a0b283 Mon Sep 17 00:00:00 2001 From: smelaa Date: Thu, 18 Apr 2024 16:14:20 +0200 Subject: [PATCH 04/28] Add rter violation information to MoneyRequestPreviewContent header --- .../MoneyRequestPreviewContent.tsx | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 9a7549b9aac6a..a3a8bfd131c34 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -4,6 +4,7 @@ import lodashSortBy from 'lodash/sortBy'; import React from 'react'; import {View} from 'react-native'; import type {GestureResponderEvent} from 'react-native'; +import type {SvgProps} from 'react-native-svg'; import ConfirmedRoute from '@components/ConfirmedRoute'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -134,7 +135,11 @@ function MoneyRequestPreviewContent({ showContextMenuForReport(event, contextMenuAnchor, reportID, action, checkIfContextMenuActive); }; - const getPreviewHeaderText = (): string => { + const getPreviewHeaderTextAndIcon: () => {headerMessage: string; headerIcon?: React.FC} = () => { + if (TransactionUtils.hasPendingUI(transaction, TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { + return {headerMessage: translate('iou.pendingMatchWithCreditCard'), headerIcon: Expensicons.Hourglass}; + } + let message = translate('iou.cash'); if (isDistanceRequest) { @@ -149,13 +154,13 @@ function MoneyRequestPreviewContent({ message = translate('iou.card'); if (TransactionUtils.isPending(transaction)) { message += ` ${CONST.DOT_SEPARATOR} ${translate('iou.pending')}`; - return message; + return {headerMessage: message}; } } if (isSettled && !iouReport?.isCancelledIOU && !isPartialHold) { message += ` ${CONST.DOT_SEPARATOR} ${getSettledMessage()}`; - return message; + return {headerMessage: message}; } if (shouldShowRBR && transaction) { @@ -166,7 +171,8 @@ function MoneyRequestPreviewContent({ const isTooLong = violationsCount > 1 || violationMessage.length > 15; const hasViolationsAndFieldErrors = violationsCount > 0 && hasFieldErrors; - return `${message} ${CONST.DOT_SEPARATOR} ${isTooLong || hasViolationsAndFieldErrors ? translate('violations.reviewRequired') : violationMessage}`; + message = `${message} ${CONST.DOT_SEPARATOR} ${isTooLong || hasViolationsAndFieldErrors ? translate('violations.reviewRequired') : violationMessage}`; + return {headerMessage: message, headerIcon: undefined}; } const isMerchantMissing = TransactionUtils.isMerchantMissing(transaction); @@ -189,9 +195,11 @@ function MoneyRequestPreviewContent({ } else if (!(isSettled && !isSettlementOrApprovalPartial) && isOnHold) { message += ` ${CONST.DOT_SEPARATOR} ${translate('iou.hold')}`; } - return message; + return {headerMessage: message}; }; + const {headerMessage, headerIcon} = getPreviewHeaderTextAndIcon(); + const getDisplayAmountText = (): string => { if (isScanning) { return translate('iou.receiptScanning'); @@ -249,7 +257,15 @@ function MoneyRequestPreviewContent({ - {getPreviewHeaderText()} + {headerIcon && ( + + )} + {headerMessage} {!isSettled && shouldShowRBR && ( Date: Wed, 24 Apr 2024 13:27:06 +0200 Subject: [PATCH 05/28] Mocking data --- src/components/MoneyReportHeader.tsx | 2 +- src/components/ReportActionItem/ReportPreview.tsx | 5 +---- src/pages/home/report/ReportActionsList.tsx | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 07c78623fce89..027bb0f0d28c2 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -89,7 +89,7 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money const isDraft = ReportUtils.isOpenExpenseReport(moneyRequestReport); const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false); - const transactionIDs = TransactionUtils.getAllReportTransactions(chatReport?.reportID).map((transaction) => transaction.transactionID); + const transactionIDs = TransactionUtils.getAllReportTransactions(moneyRequestReport?.reportID).map((transaction) => transaction.transactionID); const haveAllPendingRTERViolation = TransactionUtils.haveAllPendingRTERViolation(transactionIDs); const cancelPayment = useCallback(() => { diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 4d89e728aae60..f43dd429394f2 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -213,7 +213,7 @@ function ReportPreview({ const shouldDisableApproveButton = shouldShowApproveButton && !ReportUtils.isAllowedToApproveExpenseReport(iouReport); - const shouldShowSettlementButton = shouldShowPayButton || shouldShowApproveButton; + const shouldShowSettlementButton = (shouldShowPayButton || shouldShowApproveButton) && !showRTERViolationMessage; const shouldPromptUserToAddBankAccount = ReportUtils.hasMissingPaymentMethod(userWallet, iouReportID); const shouldShowRBR = !iouSettled && hasErrors; @@ -238,9 +238,6 @@ function ReportPreview({ const parsedSubtitle = new ExpensiMark().replace(formattedDescription ?? moneyRequestComment); return {isSupportTextHtml: !!parsedSubtitle, supportText: parsedSubtitle ? `${parsedSubtitle}` : ''}; } - // if (true) { - // return {isSupportTextHtml: false, supportText: 'ABC'}; - // } return { isSupportTextHtml: false, supportText: translate('iou.expenseCount', { diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 4c7346e1355c2..849783944f276 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -27,6 +27,7 @@ import type {CentralPaneNavigatorParamList} from '@navigation/types'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; 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'; @@ -191,7 +192,19 @@ function ReportActionsList({ const hasFooterRendered = useRef(false); const lastVisibleActionCreatedRef = useRef(report.lastVisibleActionCreated); const lastReadTimeRef = useRef(report.lastReadTime); - Onyx.merge('transactions_8811441407757684730', {cardID: 1, merchant: 'Google', hasEReceipt: true, status: 'Pending'}); + //Single MoneyRequest + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}6196867412357270168`, {cardID: 1, merchant: 'single MoneyRequest test'}); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}6196867412357270168`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); + //Multiple MoneyRequests test + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}1304796714991934480`, {cardID: 1, merchant: 'multiple MoneyRequests test 1'}); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}1304796714991934480`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}6286508495235425496`, {cardID: 1, merchant: 'multiple MoneyRequests test 2'}); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}6286508495235425496`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}2150079702326626524`, {cardID: 1, merchant: 'multiple MoneyRequests test 3'}); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}2150079702326626524`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); + //One-Expense Chat test + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}2438117170083649063`, {cardID: 1, merchant: 'One-Expense Chat test'}); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}2438117170083649063`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); const sortedVisibleReportActions = useMemo( () => From 07d3bc51810bc5b695e1e93a1800dcc81bc76e7c Mon Sep 17 00:00:00 2001 From: smelaa Date: Fri, 26 Apr 2024 14:24:02 +0200 Subject: [PATCH 06/28] Disable eslint on mocking data --- src/pages/home/report/ReportActionsList.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 0d9c5d31253fc..4b217668802b8 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -190,18 +190,28 @@ function ReportActionsList({ const hasFooterRendered = useRef(false); const lastVisibleActionCreatedRef = useRef(report.lastVisibleActionCreated); const lastReadTimeRef = useRef(report.lastReadTime); - //Single MoneyRequest + // Single MoneyRequest + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}6196867412357270168`, {cardID: 1, merchant: 'single MoneyRequest test'}); + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}6196867412357270168`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); - //Multiple MoneyRequests test + // Multiple MoneyRequests test + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}1304796714991934480`, {cardID: 1, merchant: 'multiple MoneyRequests test 1'}); + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}1304796714991934480`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}6286508495235425496`, {cardID: 1, merchant: 'multiple MoneyRequests test 2'}); + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}6286508495235425496`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}2150079702326626524`, {cardID: 1, merchant: 'multiple MoneyRequests test 3'}); + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}2150079702326626524`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); - //One-Expense Chat test + // One-Expense Chat test + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}2438117170083649063`, {cardID: 1, merchant: 'One-Expense Chat test'}); + // eslint-disable-next-line rulesdir/prefer-actions-set-data Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}2438117170083649063`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); const sortedVisibleReportActions = useMemo( From c20119d9036d22a680771b1dcaa8a890a05f9919 Mon Sep 17 00:00:00 2001 From: smelaa Date: Mon, 29 Apr 2024 14:39:45 +0200 Subject: [PATCH 07/28] Move message from header to footer --- .../MoneyRequestPreviewContent.tsx | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 7b6c0122003cf..71b735d8e7440 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -98,6 +98,7 @@ function MoneyRequestPreviewContent({ const isCardTransaction = TransactionUtils.isCardTransaction(transaction); const isSettled = ReportUtils.isSettled(iouReport?.reportID); const isDeleted = action?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; + const hasPendingUI = TransactionUtils.hasPendingUI(transaction, TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations)); const shouldShowRBR = hasViolations || hasFieldErrors || (!(isSettled && !isSettlementOrApprovalPartial) && !(ReportUtils.isReportApproved(iouReport) && !isSettlementOrApprovalPartial) && isOnHold); @@ -135,11 +136,7 @@ function MoneyRequestPreviewContent({ showContextMenuForReport(event, contextMenuAnchor, reportID, action, checkIfContextMenuActive); }; - const getPreviewHeaderTextAndIcon: () => {headerMessage: string; headerIcon?: React.FC} = () => { - if (TransactionUtils.hasPendingUI(transaction, TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { - return {headerMessage: translate('iou.pendingMatchWithCreditCard'), headerIcon: Expensicons.Hourglass}; - } - + const getPreviewHeaderText = (): string => { let message = translate('iou.cash'); if (isDistanceRequest) { @@ -154,13 +151,13 @@ function MoneyRequestPreviewContent({ message = translate('iou.card'); if (TransactionUtils.isPending(transaction)) { message += ` ${CONST.DOT_SEPARATOR} ${translate('iou.pending')}`; - return {headerMessage: message}; + return message; } } if (isSettled && !iouReport?.isCancelledIOU && !isPartialHold) { message += ` ${CONST.DOT_SEPARATOR} ${getSettledMessage()}`; - return {headerMessage: message}; + return message; } if (shouldShowRBR && transaction) { @@ -171,8 +168,7 @@ function MoneyRequestPreviewContent({ const isTooLong = violationsCount > 1 || violationMessage.length > 15; const hasViolationsAndFieldErrors = violationsCount > 0 && hasFieldErrors; - message = `${message} ${CONST.DOT_SEPARATOR} ${isTooLong || hasViolationsAndFieldErrors ? translate('violations.reviewRequired') : violationMessage}`; - return {headerMessage: message, headerIcon: undefined}; + return `${message} ${CONST.DOT_SEPARATOR} ${isTooLong || hasViolationsAndFieldErrors ? translate('violations.reviewRequired') : violationMessage}`; } const isMerchantMissing = TransactionUtils.isMerchantMissing(transaction); @@ -195,11 +191,9 @@ function MoneyRequestPreviewContent({ } else if (!(isSettled && !isSettlementOrApprovalPartial) && isOnHold) { message += ` ${CONST.DOT_SEPARATOR} ${translate('iou.hold')}`; } - return {headerMessage: message}; + return message; }; - const {headerMessage, headerIcon} = getPreviewHeaderTextAndIcon(); - const getDisplayAmountText = (): string => { if (isScanning) { return translate('iou.receiptScanning'); @@ -257,15 +251,7 @@ function MoneyRequestPreviewContent({ - {headerIcon && ( - - )} - {headerMessage} + {getPreviewHeaderText()} {!isSettled && shouldShowRBR && ( {translate('iou.receiptScanInProgress')} )} + {!isScanning && hasPendingUI && ( + + + + {translate('iou.pendingMatchWithCreditCard')} + + + )} From 8f00196a080820628bbca9fd9b9d1f258625164e Mon Sep 17 00:00:00 2001 From: smelaa Date: Mon, 29 Apr 2024 14:54:02 +0200 Subject: [PATCH 08/28] Fix eslint error --- .../MoneyRequestPreview/MoneyRequestPreviewContent.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 71b735d8e7440..fd5dc69f618a3 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -4,7 +4,6 @@ import lodashSortBy from 'lodash/sortBy'; import React from 'react'; import {View} from 'react-native'; import type {GestureResponderEvent} from 'react-native'; -import type {SvgProps} from 'react-native-svg'; import ConfirmedRoute from '@components/ConfirmedRoute'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; From 7a89a590fc6c037611c84efb07478564e5fae4a2 Mon Sep 17 00:00:00 2001 From: smelaa Date: Mon, 6 May 2024 15:23:08 +0200 Subject: [PATCH 09/28] Styling fixes --- src/components/MoneyReportHeader.tsx | 5 +++-- src/components/MoneyRequestHeader.tsx | 5 +++-- .../MoneyRequestPreview/MoneyRequestPreviewContent.tsx | 1 + src/components/ReportActionItem/ReportPreview.tsx | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 8067c38b873bf..2cd1d91d59fb5 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -252,9 +252,10 @@ function MoneyReportHeader({ title={ } description={translate('iou.pendingMatchWithCreditCardDescription')} diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 52c0da5d63c94..7a38d2403a65a 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -219,9 +219,10 @@ function MoneyRequestHeader({ ) : ( ) } diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index fd5dc69f618a3..790bc9b0db538 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -333,6 +333,7 @@ function MoneyRequestPreviewContent({ height={variables.iconSizeExtraSmall} width={variables.iconSizeExtraSmall} fill={theme.textSupporting} + additionalStyles={[styles.mr1]} /> {translate('iou.pendingMatchWithCreditCard')} diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 9b1e2eef50d7d..ecad6aa542283 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -328,6 +328,7 @@ function ReportPreview({ height={variables.iconSizeExtraSmall} width={variables.iconSizeExtraSmall} fill={theme.textSupporting} + additionalStyles={[styles.mr1]} /> {translate('iou.pendingMatchWithCreditCard')} From c47e30bd2e72819a4817879b1338b01b3384f1d1 Mon Sep 17 00:00:00 2001 From: smelaa Date: Mon, 6 May 2024 16:58:57 +0200 Subject: [PATCH 10/28] Fixes after merging with main --- src/components/MoneyRequestHeader.tsx | 8 +++++++- src/components/MoneyRequestHeaderStatusBar.tsx | 14 +++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 7a4a3f34fbf13..b1aadd61b2780 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -100,6 +100,8 @@ function MoneyRequestHeader({ setIsDeleteModalVisible(false); }, [parentReport?.reportID, parentReportAction, setIsDeleteModalVisible]); + const isScanning = TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction); + const isDeletedParentAction = ReportActionsUtils.isDeletedAction(parentReportAction); const canHoldOrUnholdRequest = !isSettled && !isApproved && !isDeletedParentAction; @@ -121,12 +123,15 @@ function MoneyRequestHeader({ if (TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction)) { return {pendingType: 'PENDING', pendingTitle: translate('iou.pending'), pendingDescription: translate('iou.transactionPendingText')}; } - if (TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction)) { + if (isScanning) { return {pendingType: 'SCANNING', pendingTitle: ReceiptScan, pendingDescription: translate('iou.receiptScanInProgressDescription')}; } if (TransactionUtils.hasPendingRTERViolation(TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { return {pendingType: 'RTER', pendingTitle: Expensicons.Hourglass, pendingDescription: translate('iou.pendingMatchWithCreditCardDescription')}; } + if (isOnHold) { + return {pendingType: 'HOLD', pendingTitle: translate('iou.hold'), pendingDescription: translate('iou.expenseOnHold')}; + } return {}; }; @@ -227,6 +232,7 @@ function MoneyRequestHeader({ } description={pendingDescription} shouldShowBorderBottom + danger={isOnHold} /> )} diff --git a/src/components/MoneyRequestHeaderStatusBar.tsx b/src/components/MoneyRequestHeaderStatusBar.tsx index 40214aaaf382b..1e4c19a61f035 100644 --- a/src/components/MoneyRequestHeaderStatusBar.tsx +++ b/src/components/MoneyRequestHeaderStatusBar.tsx @@ -25,11 +25,15 @@ function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom return ( - + {typeof title === 'string' ? ( + + ) : ( + {title} + )} {description} From 81d200e182074400de2d6462ba45bf04cc464636 Mon Sep 17 00:00:00 2001 From: smelaa Date: Tue, 7 May 2024 10:11:34 +0200 Subject: [PATCH 11/28] Styling --- src/components/MoneyReportHeader.tsx | 2 +- src/components/MoneyRequestHeader.tsx | 14 +++++++++----- src/components/MoneyRequestHeaderStatusBar.tsx | 11 +++++++---- .../MoneyRequestPreviewContent.tsx | 1 - src/components/ReportActionItem/ReportPreview.tsx | 1 - 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 6d7ec7c1d4cef..f58b571cb8169 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -255,11 +255,11 @@ function MoneyReportHeader({ height={variables.iconSizeSmall} width={variables.iconSizeSmall} fill={theme.textSupporting} - additionalStyles={[styles.mr2]} /> } description={translate('iou.pendingMatchWithCreditCardDescription')} shouldShowBorderBottom + additionalViewStyle={[styles.mr2]} /> )} diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index b1aadd61b2780..d19a4e4ac8fdb 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -129,9 +129,6 @@ function MoneyRequestHeader({ if (TransactionUtils.hasPendingRTERViolation(TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { return {pendingType: 'RTER', pendingTitle: Expensicons.Hourglass, pendingDescription: translate('iou.pendingMatchWithCreditCardDescription')}; } - if (isOnHold) { - return {pendingType: 'HOLD', pendingTitle: translate('iou.hold'), pendingDescription: translate('iou.expenseOnHold')}; - } return {}; }; @@ -226,13 +223,20 @@ function MoneyRequestHeader({ height={variables.iconSizeSmall} width={variables.iconSizeSmall} fill={theme.textSupporting} - additionalStyles={[styles.mr2]} /> ) } description={pendingDescription} + shouldShowBorderBottom={!isOnHold} + additionalViewStyle={[styles.mr2]} + /> + )} + {isOnHold && ( + )} diff --git a/src/components/MoneyRequestHeaderStatusBar.tsx b/src/components/MoneyRequestHeaderStatusBar.tsx index 1e4c19a61f035..16152fa531231 100644 --- a/src/components/MoneyRequestHeaderStatusBar.tsx +++ b/src/components/MoneyRequestHeaderStatusBar.tsx @@ -1,6 +1,6 @@ import type {ReactNode} from 'react'; import React from 'react'; -import {View} from 'react-native'; +import {StyleProp, View, ViewStyle} from 'react-native'; import useThemeStyles from '@hooks/useThemeStyles'; import Badge from './Badge'; import Text from './Text'; @@ -17,14 +17,17 @@ type MoneyRequestHeaderStatusBarProps = { /** Whether we should use the danger theme color */ danger?: boolean; + + /** Additional style for the banner */ + additionalViewStyle?: StyleProp; }; -function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom, danger = false}: MoneyRequestHeaderStatusBarProps) { +function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom, danger = false, additionalViewStyle}: MoneyRequestHeaderStatusBarProps) { const styles = useThemeStyles(); const borderBottomStyle = shouldShowBorderBottom ? styles.borderBottom : {}; return ( - + {typeof title === 'string' ? ( ) : ( - {title} + {title} )} diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 4a0de338392fc..118f1b2aeb9c9 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -334,7 +334,6 @@ function MoneyRequestPreviewContent({ height={variables.iconSizeExtraSmall} width={variables.iconSizeExtraSmall} fill={theme.textSupporting} - additionalStyles={[styles.mr1]} /> {translate('iou.pendingMatchWithCreditCard')} diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 2d9b6d8b362c7..90c22f3863f62 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -320,7 +320,6 @@ function ReportPreview({ height={variables.iconSizeExtraSmall} width={variables.iconSizeExtraSmall} fill={theme.textSupporting} - additionalStyles={[styles.mr1]} /> {translate('iou.pendingMatchWithCreditCard')} From 8d72c93cab4a5f3f90ad81fa48740b900d44ce82 Mon Sep 17 00:00:00 2001 From: smelaa Date: Tue, 7 May 2024 10:40:47 +0200 Subject: [PATCH 12/28] Eslint --- src/components/MoneyRequestHeaderStatusBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MoneyRequestHeaderStatusBar.tsx b/src/components/MoneyRequestHeaderStatusBar.tsx index b295dfe4783e4..31d7cbf22733b 100644 --- a/src/components/MoneyRequestHeaderStatusBar.tsx +++ b/src/components/MoneyRequestHeaderStatusBar.tsx @@ -39,7 +39,7 @@ function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom styles.headerStatusBarContainer, ]} > - + {typeof title === 'string' ? ( Date: Tue, 7 May 2024 10:54:12 +0200 Subject: [PATCH 13/28] Eslint --- src/components/MoneyRequestHeaderStatusBar.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/MoneyRequestHeaderStatusBar.tsx b/src/components/MoneyRequestHeaderStatusBar.tsx index 31d7cbf22733b..7a8259e92863a 100644 --- a/src/components/MoneyRequestHeaderStatusBar.tsx +++ b/src/components/MoneyRequestHeaderStatusBar.tsx @@ -1,6 +1,7 @@ import type {ReactNode} from 'react'; import React from 'react'; -import {StyleProp, View, ViewStyle} from 'react-native'; +import type {StyleProp, ViewStyle} from 'react-native'; +import {View} from 'react-native'; import useThemeStyles from '@hooks/useThemeStyles'; import Badge from './Badge'; import Text from './Text'; From c4cdb4bef11b8bfad2c47b00b5861f77285d0fdb Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 8 May 2024 10:32:41 +0200 Subject: [PATCH 14/28] Addressing review comments --- src/components/MoneyReportHeader.tsx | 10 +++--- src/components/MoneyRequestHeader.tsx | 50 ++++++++++++++++++--------- src/libs/TransactionUtils.ts | 14 +++++--- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 68fb0f12733b7..1880184aff017 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -105,7 +105,7 @@ function MoneyReportHeader({ const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false); const transactionIDs = TransactionUtils.getAllReportTransactions(moneyRequestReport?.reportID).map((transaction) => transaction.transactionID); - const haveAllPendingRTERViolation = TransactionUtils.haveAllPendingRTERViolation(transactionIDs); + const hasAllPendingRTERViolation = TransactionUtils.hasAllPendingRTERViolation(transactionIDs); const cancelPayment = useCallback(() => { if (!chatReport) { @@ -121,9 +121,9 @@ function MoneyReportHeader({ const shouldDisableApproveButton = shouldShowApproveButton && !ReportUtils.isAllowedToApproveExpenseReport(moneyRequestReport); - const shouldShowSettlementButton = !ReportUtils.isInvoiceReport(moneyRequestReport) && (shouldShowPayButton || shouldShowApproveButton) && !haveAllPendingRTERViolation; + const shouldShowSettlementButton = !ReportUtils.isInvoiceReport(moneyRequestReport) && (shouldShowPayButton || shouldShowApproveButton) && !hasAllPendingRTERViolation; - const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !haveAllPendingRTERViolation; + const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !hasAllPendingRTERViolation; const shouldDisableSubmitButton = shouldShowSubmitButton && !ReportUtils.isAllowedToSubmitDraftExpenseReport(moneyRequestReport); const isFromPaidPolicy = policyType === CONST.POLICY.TYPE.TEAM || policyType === CONST.POLICY.TYPE.CORPORATE; const shouldShowNextStep = !ReportUtils.isClosedExpenseReportWithNoExpenses(moneyRequestReport) && isFromPaidPolicy && !!nextStep?.message?.length; @@ -212,7 +212,7 @@ function MoneyReportHeader({ shouldShowBackButton={shouldUseNarrowLayout} onBackButtonPress={onBackButtonPress} // Shows border if no buttons or next steps are showing below the header - shouldShowBorderBottom={!(shouldShowAnyButton && shouldUseNarrowLayout) && !(shouldShowNextStep && !shouldUseNarrowLayout) && !haveAllPendingRTERViolation} + shouldShowBorderBottom={!(shouldShowAnyButton && shouldUseNarrowLayout) && !(shouldShowNextStep && !shouldUseNarrowLayout) && !hasAllPendingRTERViolation} shouldShowThreeDotsButton threeDotsMenuItems={threeDotsMenuItems} threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)} @@ -250,7 +250,7 @@ function MoneyReportHeader({ )} - {haveAllPendingRTERViolation && ( + {hasAllPendingRTERViolation && ( { if (TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction)) { - return {pendingType: 'PENDING', pendingTitle: translate('iou.pending'), pendingDescription: translate('iou.transactionPendingText')}; + return 'PENDING'; } if (isScanning) { - return {pendingType: 'SCANNING', pendingTitle: ReceiptScan, pendingDescription: translate('iou.receiptScanInProgressDescription')}; + return 'SCANNING'; } if (TransactionUtils.hasPendingRTERViolation(TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { - return {pendingType: 'RTER', pendingTitle: Expensicons.Hourglass, pendingDescription: translate('iou.pendingMatchWithCreditCardDescription')}; + return 'RTER'; } - return {}; }; - const {pendingType, pendingTitle, pendingDescription} = getPendingType(); + const pendingType = getPendingType(); useEffect(() => { if (canDeleteRequest) { @@ -217,21 +216,38 @@ function MoneyRequestHeader({ shouldShowBackButton={shouldUseNarrowLayout} onBackButtonPress={onBackButtonPress} /> - {pendingType && ( + {pendingType === 'PENDING' && ( + + )} + {pendingType === 'SCANNING' && ( + + } + description={translate('iou.receiptScanInProgressDescription')} + shouldShowBorderBottom={!isOnHold} + /> + )} + {pendingType === 'RTER' && ( - ) + } - description={pendingDescription} + description={translate('iou.pendingMatchWithCreditCardDescription')} shouldShowBorderBottom={!isOnHold} additionalViewStyle={[styles.mr2]} /> diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index dba6ae5178dd7..8edfad9b456f7 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -508,6 +508,9 @@ function hasMissingSmartscanFields(transaction: OnyxEntry): boolean return Boolean(transaction && !isDistanceRequest(transaction) && !isReceiptBeingScanned(transaction) && areRequiredFieldsEmpty(transaction)); } +/** + * Get all transaction violations of the transaction with given tranactionID. + */ function getTransactionViolations(transactionID: string, transactionViolations: OnyxCollection | null): TransactionViolations | null { return transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID] ?? null; } @@ -522,10 +525,13 @@ function hasPendingRTERViolation(transactionViolations?: TransactionViolations | } /** - * Check if there is pending rter violation in transactionViolations. + * Check if there is pending rter violation in all transactionViolations with given transactionIDs. */ -function haveAllPendingRTERViolation(transactionIds: string[]): boolean { - const transactionsWithRTERViolations = transactionIds.map((transactionId) => hasPendingRTERViolation(getTransactionViolations(transactionId, allTransactionViolations))); +function hasAllPendingRTERViolation(transactionIds: string[]): boolean { + const transactionsWithRTERViolations = transactionIds.map((transactionId) => { + const transactionViolations = getTransactionViolations(transactionId, allTransactionViolations); + return hasPendingRTERViolation(transactionViolations); + }); return transactionsWithRTERViolations.length !== 0 && transactionsWithRTERViolations.every((value) => value === true); } @@ -750,7 +756,7 @@ export { areRequiredFieldsEmpty, hasMissingSmartscanFields, hasPendingRTERViolation, - haveAllPendingRTERViolation, + hasAllPendingRTERViolation, hasPendingUI, getWaypointIndex, waypointHasValidAddress, From 03fb6ee2cecba73291e14d5acfc4fd059a0dd811 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 8 May 2024 10:34:27 +0200 Subject: [PATCH 15/28] Remove mocking data --- src/pages/home/report/ReportActionsList.tsx | 23 --------------------- 1 file changed, 23 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index c2f18e04c52e3..5d9198c8752b5 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -190,29 +190,6 @@ function ReportActionsList({ const hasFooterRendered = useRef(false); const lastVisibleActionCreatedRef = useRef(report.lastVisibleActionCreated); const lastReadTimeRef = useRef(report.lastReadTime); - // Single MoneyRequest - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}6196867412357270168`, {cardID: 1, merchant: 'single MoneyRequest test'}); - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}6196867412357270168`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); - // Multiple MoneyRequests test - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}1304796714991934480`, {cardID: 1, merchant: 'multiple MoneyRequests test 1'}); - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}1304796714991934480`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}6286508495235425496`, {cardID: 1, merchant: 'multiple MoneyRequests test 2'}); - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}6286508495235425496`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}2150079702326626524`, {cardID: 1, merchant: 'multiple MoneyRequests test 3'}); - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}2150079702326626524`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); - // One-Expense Chat test - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}2438117170083649063`, {cardID: 1, merchant: 'One-Expense Chat test'}); - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}2438117170083649063`, [{type: 'test', name: CONST.VIOLATIONS.RTER, data: {pendingPattern: true}}]); const sortedVisibleReportActions = useMemo( () => From 5560114f1aa5a02b3a5d2ba167f224c3cb412d12 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 8 May 2024 10:45:50 +0200 Subject: [PATCH 16/28] Eslint --- src/pages/home/report/ReportActionsList.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 5d9198c8752b5..c826e15985f5e 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -6,7 +6,6 @@ import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 're import {DeviceEventEmitter, InteractionManager} from 'react-native'; import type {LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, StyleProp, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import InvertedFlatList from '@components/InvertedFlatList'; import {AUTOSCROLL_TO_TOP_THRESHOLD} from '@components/InvertedFlatList/BaseInvertedFlatList'; @@ -27,7 +26,6 @@ import type {CentralPaneNavigatorParamList} from '@navigation/types'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; 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'; From a3d217e9efa858a9ceb43e0f0d947bbb744c7e6b Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 8 May 2024 12:53:58 +0200 Subject: [PATCH 17/28] Address review comments --- src/components/MoneyReportHeader.tsx | 2 +- src/components/MoneyRequestHeader.tsx | 103 ++++++++++++++++---------- src/libs/TransactionUtils.ts | 4 +- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 701811067994f..7a2f6d8b4739c 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -105,7 +105,7 @@ function MoneyReportHeader({ const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false); const transactionIDs = TransactionUtils.getAllReportTransactions(moneyRequestReport?.reportID).map((transaction) => transaction.transactionID); - const hasAllPendingRTERViolation = TransactionUtils.hasAllPendingRTERViolation(transactionIDs); + const hasAllPendingRTERViolation = TransactionUtils.hasAllPendingRTERViolations(transactionIDs); const cancelPayment = useCallback(() => { if (!chatReport) { diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 442f29f26577d..c20f2904fd20e 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -62,6 +62,64 @@ type MoneyRequestHeaderProps = MoneyRequestHeaderOnyxProps & { /** Method to trigger when pressing close button of the header */ onBackButtonPress: () => void; }; + +type PendingType = 'PENDING' | 'SCANNING' | 'RTER'; + +type MoneyRequestHeaderPendingStatusBarProps = {pendingType: PendingType; shouldShowBorderBottom: boolean}; + +function MoneyRequestHeaderPendingStatusBar({pendingType, shouldShowBorderBottom}: MoneyRequestHeaderPendingStatusBarProps) { + const theme = useTheme(); + const {translate} = useLocalize(); + + if (pendingType === 'PENDING') { + return ( + + } + description={translate('iou.transactionPendingDescription')} + shouldShowBorderBottom={shouldShowBorderBottom} + /> + ); + } + + if (pendingType === 'SCANNING') { + return ( + + } + description={translate('iou.receiptScanInProgressDescription')} + shouldShowBorderBottom={shouldShowBorderBottom} + /> + ); + } + + return ( + + } + description={translate('iou.pendingMatchWithCreditCardDescription')} + shouldShowBorderBottom={shouldShowBorderBottom} + /> + ); +} function MoneyRequestHeader({ session, parentReport, @@ -75,7 +133,6 @@ function MoneyRequestHeader({ onBackButtonPress, }: MoneyRequestHeaderProps) { const styles = useThemeStyles(); - const theme = useTheme(); const {translate} = useLocalize(); const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false); const [shouldShowHoldMenu, setShouldShowHoldMenu] = useState(false); @@ -122,7 +179,7 @@ function MoneyRequestHeader({ } }; - const getPendingType = () => { + const getPendingType: () => PendingType | undefined = () => { if (TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction)) { return 'PENDING'; } @@ -215,45 +272,9 @@ function MoneyRequestHeader({ shouldShowBackButton={shouldUseNarrowLayout} onBackButtonPress={onBackButtonPress} /> - {pendingType === 'PENDING' && ( - - } - description={translate('iou.transactionPendingDescription')} - shouldShowBorderBottom={!isOnHold} - /> - )} - {pendingType === 'SCANNING' && ( - - } - description={translate('iou.receiptScanInProgressDescription')} - shouldShowBorderBottom={!isOnHold} - /> - )} - {pendingType === 'RTER' && ( - - } - description={translate('iou.pendingMatchWithCreditCardDescription')} + {pendingType && ( + )} diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 8edfad9b456f7..bc33c39805c5c 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -527,7 +527,7 @@ function hasPendingRTERViolation(transactionViolations?: TransactionViolations | /** * Check if there is pending rter violation in all transactionViolations with given transactionIDs. */ -function hasAllPendingRTERViolation(transactionIds: string[]): boolean { +function hasAllPendingRTERViolations(transactionIds: string[]): boolean { const transactionsWithRTERViolations = transactionIds.map((transactionId) => { const transactionViolations = getTransactionViolations(transactionId, allTransactionViolations); return hasPendingRTERViolation(transactionViolations); @@ -756,7 +756,7 @@ export { areRequiredFieldsEmpty, hasMissingSmartscanFields, hasPendingRTERViolation, - hasAllPendingRTERViolation, + hasAllPendingRTERViolations, hasPendingUI, getWaypointIndex, waypointHasValidAddress, From 34b43dce59e2767f8fda2594c67a66eb5e01232d Mon Sep 17 00:00:00 2001 From: smelaa Date: Fri, 10 May 2024 09:50:05 +0200 Subject: [PATCH 18/28] Update Spanish translations --- src/languages/es.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 09beaa981303a..08d136de68a2b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -638,14 +638,14 @@ export default { canceled: 'Canceló', posted: 'Contabilizado', deleteReceipt: 'Eliminar recibo', - pendingMatchWithCreditCard: 'Recibo pendiente de conciliar con la tarjeta de crédito.', - pendingMatchWithCreditCardDescription: 'Recibo pendiente de conciliar con tarjeta de crédito. Marcar como efectivo para ignorar y solicitar pago.', + pendingMatchWithCreditCard: 'Recibo pendiente de adjuntar con la tarjeta de crédito.', + pendingMatchWithCreditCardDescription: 'Recibo pendiente de adjuntar con tarjeta de crédito. Marca como efectivo para ignorar y solicitar pago.', routePending: 'Ruta pendiente...', receiptIssuesFound: (count: number) => `${count === 1 ? 'Problema encontrado' : 'Problemas encontrados'}`, fieldPending: 'Pendiente...', receiptScanning: 'Escaneando recibo...', receiptScanInProgress: 'Escaneo en curso.', - receiptScanInProgressDescription: 'Escaneando recibo. Vuelva a comprobarlo más tarde o introduzca los detalles ahora.', + receiptScanInProgressDescription: 'Escaneado de recibo en proceso. Vuelva a comprobar más tarde o introduzca los detalles ahora.', defaultRate: 'Tasa predeterminada', receiptMissingDetails: 'Recibo con campos vacíos', missingAmount: 'Falta importe', @@ -653,7 +653,7 @@ export default { receiptStatusTitle: 'Escaneando…', receiptStatusText: 'Solo tú puedes ver este recibo cuando se está escaneando. Vuelve más tarde o introduce los detalles ahora.', receiptScanningFailed: 'El escaneo de recibo ha fallado. Introduce los detalles manualmente.', - transactionPendingDescription: 'Transacción pendiente. Esto puede tardar algunos días en registrarse a partir de la fecha en que se utilizó la tarjeta.', + transactionPendingDescription: 'Transacción pendiente. La transacción tarda unos días en contabilizarse desde la fecha en que se utilizó la tarjeta.', expenseCount: ({count, scanningReceipts = 0, pendingReceipts = 0}: RequestCountParams) => `${count} ${Str.pluralize('gasto', 'gastos', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}${ pendingReceipts > 0 ? `, ${pendingReceipts} pendiente` : '' From 75d88b1c8f94b6fccb434cc3bc0480f6d115962a Mon Sep 17 00:00:00 2001 From: smelaa Date: Mon, 13 May 2024 12:11:49 +0200 Subject: [PATCH 19/28] Address review comments --- src/components/MoneyReportHeader.tsx | 10 +-- src/components/MoneyRequestHeader.tsx | 90 +++++++++------------------ src/libs/TransactionUtils.ts | 2 +- 3 files changed, 35 insertions(+), 67 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 7a2f6d8b4739c..c8d4610873e60 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -105,7 +105,7 @@ function MoneyReportHeader({ const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false); const transactionIDs = TransactionUtils.getAllReportTransactions(moneyRequestReport?.reportID).map((transaction) => transaction.transactionID); - const hasAllPendingRTERViolation = TransactionUtils.hasAllPendingRTERViolations(transactionIDs); + const hasAllPendingRTERViolations = TransactionUtils.hasAllPendingRTERViolations(transactionIDs); const cancelPayment = useCallback(() => { if (!chatReport) { @@ -121,9 +121,9 @@ function MoneyReportHeader({ const shouldDisableApproveButton = shouldShowApproveButton && !ReportUtils.isAllowedToApproveExpenseReport(moneyRequestReport); - const shouldShowSettlementButton = !ReportUtils.isInvoiceReport(moneyRequestReport) && (shouldShowPayButton || shouldShowApproveButton) && !hasAllPendingRTERViolation; + const shouldShowSettlementButton = !ReportUtils.isInvoiceReport(moneyRequestReport) && (shouldShowPayButton || shouldShowApproveButton) && !hasAllPendingRTERViolations; - const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !hasAllPendingRTERViolation; + const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !hasAllPendingRTERViolations; const shouldDisableSubmitButton = shouldShowSubmitButton && !ReportUtils.isAllowedToSubmitDraftExpenseReport(moneyRequestReport); const isFromPaidPolicy = policyType === CONST.POLICY.TYPE.TEAM || policyType === CONST.POLICY.TYPE.CORPORATE; const shouldShowNextStep = !ReportUtils.isClosedExpenseReportWithNoExpenses(moneyRequestReport) && isFromPaidPolicy && !!nextStep?.message?.length; @@ -212,7 +212,7 @@ function MoneyReportHeader({ shouldShowBackButton={shouldUseNarrowLayout} onBackButtonPress={onBackButtonPress} // Shows border if no buttons or next steps are showing below the header - shouldShowBorderBottom={!(shouldShowAnyButton && shouldUseNarrowLayout) && !(shouldShowNextStep && !shouldUseNarrowLayout) && !hasAllPendingRTERViolation} + shouldShowBorderBottom={!(shouldShowAnyButton && shouldUseNarrowLayout) && !(shouldShowNextStep && !shouldUseNarrowLayout) && !hasAllPendingRTERViolations} shouldShowThreeDotsButton threeDotsMenuItems={threeDotsMenuItems} threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)} @@ -250,7 +250,7 @@ function MoneyReportHeader({ )} - {hasAllPendingRTERViolation && ( + {hasAllPendingRTERViolations && ( void; }; -type PendingType = 'PENDING' | 'SCANNING' | 'RTER'; +type NoPendingStatusBarProps = {isPending: false}; -type MoneyRequestHeaderPendingStatusBarProps = {pendingType: PendingType; shouldShowBorderBottom: boolean}; +type PendingStatusBarProps = { + isPending: true; -function MoneyRequestHeaderPendingStatusBar({pendingType, shouldShowBorderBottom}: MoneyRequestHeaderPendingStatusBarProps) { - const theme = useTheme(); - const {translate} = useLocalize(); + /** The icon to be displayed in status bar */ + pendingIcon: React.FC; - if (pendingType === 'PENDING') { - return ( - - } - description={translate('iou.transactionPendingDescription')} - shouldShowBorderBottom={shouldShowBorderBottom} - /> - ); - } + /** The description to be displayed in status bar */ + pendingDescription: string; +}; - if (pendingType === 'SCANNING') { - return ( - - } - description={translate('iou.receiptScanInProgressDescription')} - shouldShowBorderBottom={shouldShowBorderBottom} - /> - ); - } +type StatusBarProps = NoPendingStatusBarProps | PendingStatusBarProps; - return ( - - } - description={translate('iou.pendingMatchWithCreditCardDescription')} - shouldShowBorderBottom={shouldShowBorderBottom} - /> - ); -} function MoneyRequestHeader({ session, parentReport, @@ -133,6 +91,7 @@ function MoneyRequestHeader({ onBackButtonPress, }: MoneyRequestHeaderProps) { const styles = useThemeStyles(); + const theme = useTheme(); const {translate} = useLocalize(); const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false); const [shouldShowHoldMenu, setShouldShowHoldMenu] = useState(false); @@ -179,19 +138,20 @@ function MoneyRequestHeader({ } }; - const getPendingType: () => PendingType | undefined = () => { + const getStatusBarProps: () => StatusBarProps = () => { if (TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction)) { - return 'PENDING'; + return {isPending: true, pendingIcon: Expensicons.CreditCardHourglass, pendingDescription: translate('iou.transactionPendingDescription')}; } if (isScanning) { - return 'SCANNING'; + return {isPending: true, pendingIcon: Expensicons.ReceiptScan, pendingDescription: translate('iou.receiptScanInProgressDescription')}; } if (TransactionUtils.hasPendingRTERViolation(TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { - return 'RTER'; + return {isPending: true, pendingIcon: Expensicons.Hourglass, pendingDescription: translate('iou.pendingMatchWithCreditCardDescription')}; } + return {isPending: false}; }; - const pendingType = getPendingType(); + const statusBarProps = getStatusBarProps(); useEffect(() => { if (canDeleteRequest) { @@ -257,7 +217,7 @@ function MoneyRequestHeader({ <> - {pendingType && ( - + } + description={statusBarProps.pendingDescription} shouldShowBorderBottom={!isOnHold} /> )} diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 936be8a1f32db..51d35af17de9f 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -543,7 +543,7 @@ function hasAllPendingRTERViolations(transactionIds: string[]): boolean { * Check if the transaction is pending or has a pending rter violation. */ function hasPendingUI(transaction: OnyxEntry, transactionViolations?: TransactionViolations | null): boolean { - return Boolean(isReceiptBeingScanned(transaction) || isPending(transaction) || (transaction && hasPendingRTERViolation(transactionViolations))); + return !!(isReceiptBeingScanned(transaction) || isPending(transaction) || (transaction && hasPendingRTERViolation(transactionViolations))); } /** From 48b387c397f0e0cd225bbf82b391e985d7ff174d Mon Sep 17 00:00:00 2001 From: smelaa Date: Mon, 13 May 2024 15:20:08 +0200 Subject: [PATCH 20/28] Rename variables & change icon color --- src/components/MoneyRequestHeader.tsx | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 5c04c815db3bb..ee98b275b9c2d 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -64,16 +64,16 @@ type MoneyRequestHeaderProps = MoneyRequestHeaderOnyxProps & { onBackButtonPress: () => void; }; -type NoPendingStatusBarProps = {isPending: false}; +type NoPendingStatusBarProps = {shouldShowStatusBar: false}; type PendingStatusBarProps = { - isPending: true; + shouldShowStatusBar: true; /** The icon to be displayed in status bar */ - pendingIcon: React.FC; + statusBarIcon: React.FC; /** The description to be displayed in status bar */ - pendingDescription: string; + statusBarDescription: string; }; type StatusBarProps = NoPendingStatusBarProps | PendingStatusBarProps; @@ -140,15 +140,15 @@ function MoneyRequestHeader({ const getStatusBarProps: () => StatusBarProps = () => { if (TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction)) { - return {isPending: true, pendingIcon: Expensicons.CreditCardHourglass, pendingDescription: translate('iou.transactionPendingDescription')}; + return {shouldShowStatusBar: true, statusBarIcon: Expensicons.CreditCardHourglass, statusBarDescription: translate('iou.transactionPendingDescription')}; } if (isScanning) { - return {isPending: true, pendingIcon: Expensicons.ReceiptScan, pendingDescription: translate('iou.receiptScanInProgressDescription')}; + return {shouldShowStatusBar: true, statusBarIcon: Expensicons.ReceiptScan, statusBarDescription: translate('iou.receiptScanInProgressDescription')}; } if (TransactionUtils.hasPendingRTERViolation(TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { - return {isPending: true, pendingIcon: Expensicons.Hourglass, pendingDescription: translate('iou.pendingMatchWithCreditCardDescription')}; + return {shouldShowStatusBar: true, statusBarIcon: Expensicons.Hourglass, statusBarDescription: translate('iou.pendingMatchWithCreditCardDescription')}; } - return {isPending: false}; + return {shouldShowStatusBar: false}; }; const statusBarProps = getStatusBarProps(); @@ -217,7 +217,7 @@ function MoneyRequestHeader({ <> - {statusBarProps.isPending && ( + {statusBarProps.shouldShowStatusBar && ( } - description={statusBarProps.pendingDescription} + description={statusBarProps.statusBarDescription} shouldShowBorderBottom={!isOnHold} /> )} From e5670c0b3614bba6078564c051d98eec44d0ee58 Mon Sep 17 00:00:00 2001 From: smelaa Date: Tue, 14 May 2024 13:11:54 +0200 Subject: [PATCH 21/28] Fix a type & rename function --- src/components/MoneyReportHeader.tsx | 10 +++++----- src/languages/en.ts | 2 +- src/libs/TransactionUtils.ts | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index c8d4610873e60..642985bceaea8 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -105,7 +105,7 @@ function MoneyReportHeader({ const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false); const transactionIDs = TransactionUtils.getAllReportTransactions(moneyRequestReport?.reportID).map((transaction) => transaction.transactionID); - const hasAllPendingRTERViolations = TransactionUtils.hasAllPendingRTERViolations(transactionIDs); + const allHavePendingRTERViolation = TransactionUtils.allHavePendingRTERViolation(transactionIDs); const cancelPayment = useCallback(() => { if (!chatReport) { @@ -121,9 +121,9 @@ function MoneyReportHeader({ const shouldDisableApproveButton = shouldShowApproveButton && !ReportUtils.isAllowedToApproveExpenseReport(moneyRequestReport); - const shouldShowSettlementButton = !ReportUtils.isInvoiceReport(moneyRequestReport) && (shouldShowPayButton || shouldShowApproveButton) && !hasAllPendingRTERViolations; + const shouldShowSettlementButton = !ReportUtils.isInvoiceReport(moneyRequestReport) && (shouldShowPayButton || shouldShowApproveButton) && !allHavePendingRTERViolation; - const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !hasAllPendingRTERViolations; + const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !allHavePendingRTERViolation; const shouldDisableSubmitButton = shouldShowSubmitButton && !ReportUtils.isAllowedToSubmitDraftExpenseReport(moneyRequestReport); const isFromPaidPolicy = policyType === CONST.POLICY.TYPE.TEAM || policyType === CONST.POLICY.TYPE.CORPORATE; const shouldShowNextStep = !ReportUtils.isClosedExpenseReportWithNoExpenses(moneyRequestReport) && isFromPaidPolicy && !!nextStep?.message?.length; @@ -212,7 +212,7 @@ function MoneyReportHeader({ shouldShowBackButton={shouldUseNarrowLayout} onBackButtonPress={onBackButtonPress} // Shows border if no buttons or next steps are showing below the header - shouldShowBorderBottom={!(shouldShowAnyButton && shouldUseNarrowLayout) && !(shouldShowNextStep && !shouldUseNarrowLayout) && !hasAllPendingRTERViolations} + shouldShowBorderBottom={!(shouldShowAnyButton && shouldUseNarrowLayout) && !(shouldShowNextStep && !shouldUseNarrowLayout) && !allHavePendingRTERViolation} shouldShowThreeDotsButton threeDotsMenuItems={threeDotsMenuItems} threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)} @@ -250,7 +250,7 @@ function MoneyReportHeader({ )} - {hasAllPendingRTERViolations && ( + {allHavePendingRTERViolation && ( { const transactionViolations = getTransactionViolations(transactionId, allTransactionViolations); return hasPendingRTERViolation(transactionViolations); @@ -800,7 +800,7 @@ export { areRequiredFieldsEmpty, hasMissingSmartscanFields, hasPendingRTERViolation, - hasAllPendingRTERViolations, + allHavePendingRTERViolation, hasPendingUI, getWaypointIndex, waypointHasValidAddress, From e90103f37fd57fc3a84f3386a714d54a0bec1d42 Mon Sep 17 00:00:00 2001 From: smelaa Date: Tue, 14 May 2024 13:50:01 +0200 Subject: [PATCH 22/28] Create icon & description getter functions --- src/components/MoneyRequestHeader.tsx | 4 +- .../MoneyRequestPreviewContent.tsx | 62 ++++++++++--------- .../ReportActionItem/ReportPreview.tsx | 62 ++++++++++--------- 3 files changed, 69 insertions(+), 59 deletions(-) diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index ee98b275b9c2d..bd0674b40607f 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -2,7 +2,6 @@ import React, {useCallback, useEffect, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import type {SvgProps} from 'react-native-svg'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -19,6 +18,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction, ReportActions, Session, Transaction, TransactionViolations} from '@src/types/onyx'; import type {OriginalMessageIOU} from '@src/types/onyx/OriginalMessage'; +import type IconAsset from '@src/types/utils/IconAsset'; import ConfirmModal from './ConfirmModal'; import HeaderWithBackButton from './HeaderWithBackButton'; import Icon from './Icon'; @@ -70,7 +70,7 @@ type PendingStatusBarProps = { shouldShowStatusBar: true; /** The icon to be displayed in status bar */ - statusBarIcon: React.FC; + statusBarIcon: IconAsset; /** The description to be displayed in status bar */ statusBarDescription: string; diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 366445b0f1aac..f52fa644c7da5 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -36,8 +36,23 @@ import CONST from '@src/CONST'; import type {IOUMessage} from '@src/types/onyx/OriginalMessage'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import type IconAsset from '@src/types/utils/IconAsset'; import type {MoneyRequestPreviewProps} from './types'; +type NoPendingMessageProps = {shouldShowMessage: false}; + +type PendingMessageProps = { + shouldShowMessage: true; + + /** The icon to be displayed in the preview content footer */ + messageIcon: IconAsset; + + /** The description to be displayed in the preview content footer */ + messageDescription: string; +}; + +type MessageProps = PendingMessageProps | NoPendingMessageProps; + function MoneyRequestPreviewContent({ iouReport, isBillSplit, @@ -84,7 +99,6 @@ function MoneyRequestPreviewContent({ const requestMerchant = truncate(merchant, {length: CONST.REQUEST_PREVIEW.MAX_LENGTH}); const hasReceipt = TransactionUtils.hasReceipt(transaction); const isScanning = hasReceipt && TransactionUtils.isReceiptBeingScanned(transaction); - const isPending = TransactionUtils.isPending(transaction); const isOnHold = TransactionUtils.isOnHold(transaction); const isSettlementOrApprovalPartial = Boolean(iouReport?.pendingFields?.partial); const isPartialHold = isSettlementOrApprovalPartial && isOnHold; @@ -96,7 +110,6 @@ function MoneyRequestPreviewContent({ const isCardTransaction = TransactionUtils.isCardTransaction(transaction); const isSettled = ReportUtils.isSettled(iouReport?.reportID); const isDeleted = action?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; - const hasPendingUI = TransactionUtils.hasPendingUI(transaction, TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations)); const isFullySettled = isSettled && !isSettlementOrApprovalPartial; const isFullyApproved = ReportUtils.isReportApproved(iouReport) && !isSettlementOrApprovalPartial; const shouldShowRBR = hasNoticeTypeViolations || hasViolations || hasFieldErrors || (!isFullySettled && !isFullyApproved && isOnHold); @@ -185,6 +198,21 @@ function MoneyRequestPreviewContent({ return message; }; + const getPendingMessageProps: () => MessageProps = () => { + if (isScanning) { + return {shouldShowMessage: true, messageIcon: ReceiptScan, messageDescription: translate('iou.receiptScanInProgress')}; + } + if (TransactionUtils.isPending(transaction)) { + return {shouldShowMessage: true, messageIcon: Expensicons.CreditCardHourglass, messageDescription: translate('iou.transactionPending')}; + } + if (TransactionUtils.hasPendingUI(transaction, TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { + return {shouldShowMessage: true, messageIcon: Expensicons.Hourglass, messageDescription: translate('iou.pendingMatchWithCreditCard')}; + } + return {shouldShowMessage: false}; + }; + + const pendingMessageProps = getPendingMessageProps(); + const getDisplayAmountText = (): string => { if (isScanning) { return translate('iou.receiptScanning'); @@ -313,39 +341,15 @@ function MoneyRequestPreviewContent({ )} - {isScanning && ( - - - {translate('iou.receiptScanInProgress')} - - )} - {isPending && ( + {pendingMessageProps.shouldShowMessage && ( - {translate('iou.transactionPending')} - - )} - {!isScanning && hasPendingUI && ( - - - - {translate('iou.pendingMatchWithCreditCard')} - + {pendingMessageProps.messageDescription} )} diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 3fc8deb866874..e2632de87e93f 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -32,6 +32,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction, Transaction, TransactionViolations, UserWallet} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import type IconAsset from '@src/types/utils/IconAsset'; import ReportActionItemImages from './ReportActionItemImages'; type ReportPreviewOnyxProps = { @@ -83,6 +84,20 @@ type ReportPreviewProps = ReportPreviewOnyxProps & { isHovered?: boolean; }; +type NoPendingMessageProps = {shouldShowMessage: false}; + +type PendingMessageProps = { + shouldShowMessage: true; + + /** The icon to be displayed in the preview content footer */ + messageIcon: IconAsset; + + /** The description to be displayed in the preview content footer */ + messageDescription: string; +}; + +type MessageProps = PendingMessageProps | NoPendingMessageProps; + function ReportPreview({ iouReport, policy, @@ -231,6 +246,21 @@ function ReportPreview({ const shouldShowScanningSubtitle = numberOfScanningReceipts === 1 && numberOfRequests === 1; const shouldShowPendingSubtitle = numberOfPendingRequests === 1 && numberOfRequests === 1; + const getPendingMessageProps: () => MessageProps = () => { + if (shouldShowScanningSubtitle) { + return {shouldShowMessage: true, messageIcon: Expensicons.ReceiptScan, messageDescription: translate('iou.receiptScanInProgress')}; + } + if (shouldShowPendingSubtitle) { + return {shouldShowMessage: true, messageIcon: Expensicons.CreditCardHourglass, messageDescription: translate('iou.transactionPending')}; + } + if (showRTERViolationMessage) { + return {shouldShowMessage: true, messageIcon: Expensicons.Hourglass, messageDescription: translate('iou.pendingMatchWithCreditCard')}; + } + return {shouldShowMessage: false}; + }; + + const pendingMessageProps = getPendingMessageProps(); + const {supportText} = useMemo(() => { if (formattedMerchant) { return {supportText: formattedMerchant}; @@ -316,39 +346,15 @@ function ReportPreview({ )} - {showRTERViolationMessage && ( - + {pendingMessageProps.shouldShowMessage && ( + - - {translate('iou.pendingMatchWithCreditCard')} - - - )} - {shouldShowScanningSubtitle && ( - - - {translate('iou.receiptScanInProgress')} - - )} - {shouldShowPendingSubtitle && ( - - - {translate('iou.transactionPending')} + {pendingMessageProps.messageDescription} )} From 4920af0a41ff3bf4ad0765dc091383f09cf5b7e7 Mon Sep 17 00:00:00 2001 From: smelaa Date: Tue, 14 May 2024 14:12:11 +0200 Subject: [PATCH 23/28] Move types declaration to ReportUtils --- src/components/MoneyRequestHeader.tsx | 34 ++++++------------- .../MoneyRequestPreviewContent.tsx | 28 ++++----------- .../ReportActionItem/ReportPreview.tsx | 28 ++++----------- src/libs/ReportUtils.ts | 15 ++++++++ 4 files changed, 39 insertions(+), 66 deletions(-) diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index bd0674b40607f..346fd92f96132 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -10,6 +10,7 @@ import * as HeaderUtils from '@libs/HeaderUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import type {PendingMessageProps} from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import variables from '@styles/variables'; import * as IOU from '@userActions/IOU'; @@ -18,7 +19,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction, ReportActions, Session, Transaction, TransactionViolations} from '@src/types/onyx'; import type {OriginalMessageIOU} from '@src/types/onyx/OriginalMessage'; -import type IconAsset from '@src/types/utils/IconAsset'; import ConfirmModal from './ConfirmModal'; import HeaderWithBackButton from './HeaderWithBackButton'; import Icon from './Icon'; @@ -64,20 +64,6 @@ type MoneyRequestHeaderProps = MoneyRequestHeaderOnyxProps & { onBackButtonPress: () => void; }; -type NoPendingStatusBarProps = {shouldShowStatusBar: false}; - -type PendingStatusBarProps = { - shouldShowStatusBar: true; - - /** The icon to be displayed in status bar */ - statusBarIcon: IconAsset; - - /** The description to be displayed in status bar */ - statusBarDescription: string; -}; - -type StatusBarProps = NoPendingStatusBarProps | PendingStatusBarProps; - function MoneyRequestHeader({ session, parentReport, @@ -138,17 +124,17 @@ function MoneyRequestHeader({ } }; - const getStatusBarProps: () => StatusBarProps = () => { + const getStatusBarProps: () => PendingMessageProps = () => { if (TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction)) { - return {shouldShowStatusBar: true, statusBarIcon: Expensicons.CreditCardHourglass, statusBarDescription: translate('iou.transactionPendingDescription')}; + return {shouldShow: true, messageIcon: Expensicons.CreditCardHourglass, messageDescription: translate('iou.transactionPendingDescription')}; } if (isScanning) { - return {shouldShowStatusBar: true, statusBarIcon: Expensicons.ReceiptScan, statusBarDescription: translate('iou.receiptScanInProgressDescription')}; + return {shouldShow: true, messageIcon: Expensicons.ReceiptScan, messageDescription: translate('iou.receiptScanInProgressDescription')}; } if (TransactionUtils.hasPendingRTERViolation(TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { - return {shouldShowStatusBar: true, statusBarIcon: Expensicons.Hourglass, statusBarDescription: translate('iou.pendingMatchWithCreditCardDescription')}; + return {shouldShow: true, messageIcon: Expensicons.Hourglass, messageDescription: translate('iou.pendingMatchWithCreditCardDescription')}; } - return {shouldShowStatusBar: false}; + return {shouldShow: false}; }; const statusBarProps = getStatusBarProps(); @@ -217,7 +203,7 @@ function MoneyRequestHeader({ <> - {statusBarProps.shouldShowStatusBar && ( + {statusBarProps.shouldShow && ( } - description={statusBarProps.statusBarDescription} + description={statusBarProps.messageDescription} shouldShowBorderBottom={!isOnHold} /> )} diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index f52fa644c7da5..5ef7051ba1bbe 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -27,6 +27,7 @@ import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReceiptUtils from '@libs/ReceiptUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import type {PendingMessageProps} from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; import variables from '@styles/variables'; @@ -36,23 +37,8 @@ import CONST from '@src/CONST'; import type {IOUMessage} from '@src/types/onyx/OriginalMessage'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import type IconAsset from '@src/types/utils/IconAsset'; import type {MoneyRequestPreviewProps} from './types'; -type NoPendingMessageProps = {shouldShowMessage: false}; - -type PendingMessageProps = { - shouldShowMessage: true; - - /** The icon to be displayed in the preview content footer */ - messageIcon: IconAsset; - - /** The description to be displayed in the preview content footer */ - messageDescription: string; -}; - -type MessageProps = PendingMessageProps | NoPendingMessageProps; - function MoneyRequestPreviewContent({ iouReport, isBillSplit, @@ -198,17 +184,17 @@ function MoneyRequestPreviewContent({ return message; }; - const getPendingMessageProps: () => MessageProps = () => { + const getPendingMessageProps: () => PendingMessageProps = () => { if (isScanning) { - return {shouldShowMessage: true, messageIcon: ReceiptScan, messageDescription: translate('iou.receiptScanInProgress')}; + return {shouldShow: true, messageIcon: ReceiptScan, messageDescription: translate('iou.receiptScanInProgress')}; } if (TransactionUtils.isPending(transaction)) { - return {shouldShowMessage: true, messageIcon: Expensicons.CreditCardHourglass, messageDescription: translate('iou.transactionPending')}; + return {shouldShow: true, messageIcon: Expensicons.CreditCardHourglass, messageDescription: translate('iou.transactionPending')}; } if (TransactionUtils.hasPendingUI(transaction, TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { - return {shouldShowMessage: true, messageIcon: Expensicons.Hourglass, messageDescription: translate('iou.pendingMatchWithCreditCard')}; + return {shouldShow: true, messageIcon: Expensicons.Hourglass, messageDescription: translate('iou.pendingMatchWithCreditCard')}; } - return {shouldShowMessage: false}; + return {shouldShow: false}; }; const pendingMessageProps = getPendingMessageProps(); @@ -341,7 +327,7 @@ function MoneyRequestPreviewContent({ )} - {pendingMessageProps.shouldShowMessage && ( + {pendingMessageProps.shouldShow && ( MessageProps = () => { + const getPendingMessageProps: () => PendingMessageProps = () => { if (shouldShowScanningSubtitle) { - return {shouldShowMessage: true, messageIcon: Expensicons.ReceiptScan, messageDescription: translate('iou.receiptScanInProgress')}; + return {shouldShow: true, messageIcon: Expensicons.ReceiptScan, messageDescription: translate('iou.receiptScanInProgress')}; } if (shouldShowPendingSubtitle) { - return {shouldShowMessage: true, messageIcon: Expensicons.CreditCardHourglass, messageDescription: translate('iou.transactionPending')}; + return {shouldShow: true, messageIcon: Expensicons.CreditCardHourglass, messageDescription: translate('iou.transactionPending')}; } if (showRTERViolationMessage) { - return {shouldShowMessage: true, messageIcon: Expensicons.Hourglass, messageDescription: translate('iou.pendingMatchWithCreditCard')}; + return {shouldShow: true, messageIcon: Expensicons.Hourglass, messageDescription: translate('iou.pendingMatchWithCreditCard')}; } - return {shouldShowMessage: false}; + return {shouldShow: false}; }; const pendingMessageProps = getPendingMessageProps(); @@ -346,7 +332,7 @@ function ReportPreview({ )} - {pendingMessageProps.shouldShowMessage && ( + {pendingMessageProps.shouldShow && ( Date: Tue, 14 May 2024 14:12:56 +0200 Subject: [PATCH 24/28] Address review comments --- src/libs/TransactionUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 371e66dbccbb1..48c225b680865 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -543,7 +543,7 @@ function allHavePendingRTERViolation(transactionIds: string[]): boolean { * Check if the transaction is pending or has a pending rter violation. */ function hasPendingUI(transaction: OnyxEntry, transactionViolations?: TransactionViolations | null): boolean { - return !!(isReceiptBeingScanned(transaction) || isPending(transaction) || (transaction && hasPendingRTERViolation(transactionViolations))); + return isReceiptBeingScanned(transaction) || isPending(transaction) || (!!transaction && hasPendingRTERViolation(transactionViolations)); } /** From 027b40e4a810c969103d8ea96188cad053ec4c12 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 15 May 2024 13:04:25 +0200 Subject: [PATCH 25/28] Address review comments --- src/components/MoneyReportHeader.tsx | 2 +- .../MoneyRequestPreview/MoneyRequestPreviewContent.tsx | 2 +- src/components/ReportActionItem/ReportPreview.tsx | 4 ++-- src/libs/TransactionUtils.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 642985bceaea8..69cfbc150b98a 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -257,7 +257,7 @@ function MoneyReportHeader({ src={Expensicons.Hourglass} height={variables.iconSizeSmall} width={variables.iconSizeSmall} - fill={theme.textSupporting} + fill={theme.icon} /> } description={translate('iou.pendingMatchWithCreditCardDescription')} diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 5ef7051ba1bbe..544851d28fbeb 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -333,7 +333,7 @@ function MoneyRequestPreviewContent({ src={pendingMessageProps.messageIcon} height={variables.iconSizeExtraSmall} width={variables.iconSizeExtraSmall} - fill={theme.textSupporting} + fill={theme.icon} /> {pendingMessageProps.messageDescription} diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 2a22f696222f7..3d2513517a6fc 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -142,7 +142,7 @@ function ReportPreview({ const lastThreeTransactionsWithReceipts = transactionsWithReceipts.slice(-3); const lastThreeReceipts = lastThreeTransactionsWithReceipts.map((transaction) => ReceiptUtils.getThumbnailAndImageURIs(transaction)); const showRTERViolationMessage = - allTransactions.length === 1 && TransactionUtils.hasPendingUI(allTransactions[0], TransactionUtils.getTransactionViolations(allTransactions[0].transactionID, transactionViolations)); + numberOfRequests === 1 && TransactionUtils.hasPendingUI(allTransactions[0], TransactionUtils.getTransactionViolations(allTransactions[0].transactionID, transactionViolations)); let formattedMerchant = numberOfRequests === 1 ? TransactionUtils.getMerchant(allTransactions[0]) : null; const formattedDescription = numberOfRequests === 1 ? TransactionUtils.getDescription(allTransactions[0]) : null; @@ -338,7 +338,7 @@ function ReportPreview({ src={pendingMessageProps.messageIcon} height={variables.iconSizeExtraSmall} width={variables.iconSizeExtraSmall} - fill={theme.textSupporting} + fill={theme.icon} /> {pendingMessageProps.messageDescription} diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 48c225b680865..b1a8aea521b19 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -536,7 +536,7 @@ function allHavePendingRTERViolation(transactionIds: string[]): boolean { const transactionViolations = getTransactionViolations(transactionId, allTransactionViolations); return hasPendingRTERViolation(transactionViolations); }); - return transactionsWithRTERViolations.length !== 0 && transactionsWithRTERViolations.every((value) => value === true); + return transactionsWithRTERViolations.length > 0 && transactionsWithRTERViolations.every((value) => value === true); } /** From 40f471c2079e4e0bec179358dc5cda7867d58eb3 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 15 May 2024 14:26:21 +0200 Subject: [PATCH 26/28] Reuse MoneyRequestHeaderStatusBar --- src/components/MoneyRequestHeader.tsx | 52 +++++++++---------- .../MoneyRequestHeaderStatusBar.tsx | 2 + .../MoneyRequestPreviewContent.tsx | 3 +- .../MoneyRequestPreview/types.ts | 17 +++++- .../ReportActionItem/ReportPreview.tsx | 2 +- src/libs/ReportUtils.ts | 15 ------ 6 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 346fd92f96132..98d023f28e75c 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -1,3 +1,4 @@ +import type {ReactNode} from 'react'; import React, {useCallback, useEffect, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; @@ -10,7 +11,6 @@ import * as HeaderUtils from '@libs/HeaderUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import type {PendingMessageProps} from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import variables from '@styles/variables'; import * as IOU from '@userActions/IOU'; @@ -19,10 +19,12 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction, ReportActions, Session, Transaction, TransactionViolations} from '@src/types/onyx'; import type {OriginalMessageIOU} from '@src/types/onyx/OriginalMessage'; +import type IconAsset from '@src/types/utils/IconAsset'; import ConfirmModal from './ConfirmModal'; import HeaderWithBackButton from './HeaderWithBackButton'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; +import type {MoneyRequestHeaderStatusBarProps} from './MoneyRequestHeaderStatusBar'; import MoneyRequestHeaderStatusBar from './MoneyRequestHeaderStatusBar'; import ProcessMoneyRequestHoldMenu from './ProcessMoneyRequestHoldMenu'; @@ -124,17 +126,29 @@ function MoneyRequestHeader({ } }; - const getStatusBarProps: () => PendingMessageProps = () => { + const getStatusIcon: (src: IconAsset) => ReactNode = (src) => ( + + ); + + const getStatusBarProps: () => MoneyRequestHeaderStatusBarProps | undefined = () => { + if (isOnHold) { + return {title: translate('iou.hold'), description: translate('iou.expenseOnHold'), danger: true, shouldShowBorderBottom: true}; + } + if (TransactionUtils.isExpensifyCardTransaction(transaction) && TransactionUtils.isPending(transaction)) { - return {shouldShow: true, messageIcon: Expensicons.CreditCardHourglass, messageDescription: translate('iou.transactionPendingDescription')}; + return {title: getStatusIcon(Expensicons.CreditCardHourglass), description: translate('iou.transactionPendingDescription'), shouldShowBorderBottom: true}; } if (isScanning) { - return {shouldShow: true, messageIcon: Expensicons.ReceiptScan, messageDescription: translate('iou.receiptScanInProgressDescription')}; + return {title: getStatusIcon(Expensicons.ReceiptScan), description: translate('iou.receiptScanInProgressDescription'), shouldShowBorderBottom: true}; } if (TransactionUtils.hasPendingRTERViolation(TransactionUtils.getTransactionViolations(transaction?.transactionID ?? '', transactionViolations))) { - return {shouldShow: true, messageIcon: Expensicons.Hourglass, messageDescription: translate('iou.pendingMatchWithCreditCardDescription')}; + return {title: getStatusIcon(Expensicons.Hourglass), description: translate('iou.pendingMatchWithCreditCardDescription'), shouldShowBorderBottom: true}; } - return {shouldShow: false}; }; const statusBarProps = getStatusBarProps(); @@ -203,7 +217,7 @@ function MoneyRequestHeader({ <> - {statusBarProps.shouldShow && ( - - } - description={statusBarProps.messageDescription} - shouldShowBorderBottom={!isOnHold} - /> - )} - {isOnHold && ( + {statusBarProps && ( )} diff --git a/src/components/MoneyRequestHeaderStatusBar.tsx b/src/components/MoneyRequestHeaderStatusBar.tsx index b7bba02236569..4ee3079d5f1fe 100644 --- a/src/components/MoneyRequestHeaderStatusBar.tsx +++ b/src/components/MoneyRequestHeaderStatusBar.tsx @@ -57,3 +57,5 @@ function MoneyRequestHeaderStatusBar({title, description, shouldShowBorderBottom MoneyRequestHeaderStatusBar.displayName = 'MoneyRequestHeaderStatusBar'; export default MoneyRequestHeaderStatusBar; + +export type {MoneyRequestHeaderStatusBarProps}; diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 544851d28fbeb..4ff318bc3c475 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -27,7 +27,6 @@ import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReceiptUtils from '@libs/ReceiptUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import type {PendingMessageProps} from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; import variables from '@styles/variables'; @@ -37,7 +36,7 @@ import CONST from '@src/CONST'; import type {IOUMessage} from '@src/types/onyx/OriginalMessage'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import type {MoneyRequestPreviewProps} from './types'; +import type {MoneyRequestPreviewProps, PendingMessageProps} from './types'; function MoneyRequestPreviewContent({ iouReport, diff --git a/src/components/ReportActionItem/MoneyRequestPreview/types.ts b/src/components/ReportActionItem/MoneyRequestPreview/types.ts index 0e3eb37ce6e3f..2420611c44e68 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/types.ts +++ b/src/components/ReportActionItem/MoneyRequestPreview/types.ts @@ -2,6 +2,7 @@ import type {GestureResponderEvent, StyleProp, ViewStyle} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import type {ContextMenuAnchor} from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import type * as OnyxTypes from '@src/types/onyx'; +import type IconAsset from '@src/types/utils/IconAsset'; type MoneyRequestPreviewOnyxProps = { /** All of the personal details for everyone */ @@ -71,4 +72,18 @@ type MoneyRequestPreviewProps = MoneyRequestPreviewOnyxProps & { isWhisper?: boolean; }; -export type {MoneyRequestPreviewProps, MoneyRequestPreviewOnyxProps}; +type NoPendingProps = {shouldShow: false}; + +type PendingProps = { + shouldShow: true; + + /** The icon to be displayed if a request is pending */ + messageIcon: IconAsset; + + /** The description to be displayed if a request is pending */ + messageDescription: string; +}; + +type PendingMessageProps = PendingProps | NoPendingProps; + +export type {MoneyRequestPreviewProps, MoneyRequestPreviewOnyxProps, PendingMessageProps}; diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 3d2513517a6fc..dae827cdb5c0d 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -22,7 +22,6 @@ import Navigation from '@libs/Navigation/Navigation'; import * as ReceiptUtils from '@libs/ReceiptUtils'; import * as ReportActionUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import type {PendingMessageProps} from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import type {ContextMenuAnchor} from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import variables from '@styles/variables'; @@ -33,6 +32,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction, Transaction, TransactionViolations, UserWallet} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import type {PendingMessageProps} from './MoneyRequestPreview/types'; import ReportActionItemImages from './ReportActionItemImages'; type ReportPreviewOnyxProps = { diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 85893eebbcbc3..650b7abcc98f3 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -488,20 +488,6 @@ type ParsingDetails = { reportID?: string; }; -type NoPendingProps = {shouldShow: false}; - -type PendingProps = { - shouldShow: true; - - /** The icon to be displayed if a request is pending */ - messageIcon: IconAsset; - - /** The description to be displayed if a request is pending */ - messageDescription: string; -}; - -type PendingMessageProps = PendingProps | NoPendingProps; - let currentUserEmail: string | undefined; let currentUserPrivateDomain: string | undefined; let currentUserAccountID: number | undefined; @@ -6857,5 +6843,4 @@ export type { TransactionDetails, OptimisticInviteReportAction, ParsingDetails, - PendingMessageProps, }; From 1855b0173913c277ed1aba05070faa91d3541019 Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 15 May 2024 17:41:43 +0200 Subject: [PATCH 27/28] Add JSDoc comment --- src/components/ReportActionItem/MoneyRequestPreview/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ReportActionItem/MoneyRequestPreview/types.ts b/src/components/ReportActionItem/MoneyRequestPreview/types.ts index 2420611c44e68..9dcea80fdc054 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/types.ts +++ b/src/components/ReportActionItem/MoneyRequestPreview/types.ts @@ -75,6 +75,7 @@ type MoneyRequestPreviewProps = MoneyRequestPreviewOnyxProps & { type NoPendingProps = {shouldShow: false}; type PendingProps = { + /** Whether to show the pending message or not */ shouldShow: true; /** The icon to be displayed if a request is pending */ From 02d87f414d90978c18657550455e87da6bd7fdbf Mon Sep 17 00:00:00 2001 From: smelaa Date: Wed, 15 May 2024 19:27:55 +0200 Subject: [PATCH 28/28] Do not display next step banner in case of pending rter violation --- src/components/MoneyReportHeader.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 69cfbc150b98a..4eb3be871a8d1 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -126,7 +126,7 @@ function MoneyReportHeader({ const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0 && !allHavePendingRTERViolation; const shouldDisableSubmitButton = shouldShowSubmitButton && !ReportUtils.isAllowedToSubmitDraftExpenseReport(moneyRequestReport); const isFromPaidPolicy = policyType === CONST.POLICY.TYPE.TEAM || policyType === CONST.POLICY.TYPE.CORPORATE; - const shouldShowNextStep = !ReportUtils.isClosedExpenseReportWithNoExpenses(moneyRequestReport) && isFromPaidPolicy && !!nextStep?.message?.length; + const shouldShowNextStep = !ReportUtils.isClosedExpenseReportWithNoExpenses(moneyRequestReport) && isFromPaidPolicy && !!nextStep?.message?.length && !allHavePendingRTERViolation; const shouldShowAnyButton = shouldShowSettlementButton || shouldShowApproveButton || shouldShowSubmitButton || shouldShowNextStep; const bankAccountRoute = ReportUtils.getBankAccountRoute(chatReport); const formattedAmount = CurrencyUtils.convertToDisplayString(reimbursableSpend, moneyRequestReport.currency);