diff --git a/src/components/ReportActionItem/TripDetailsView.tsx b/src/components/ReportActionItem/TripDetailsView.tsx index a7fdef547bf..e4137f74c27 100644 --- a/src/components/ReportActionItem/TripDetailsView.tsx +++ b/src/components/ReportActionItem/TripDetailsView.tsx @@ -20,14 +20,6 @@ import * as TripReservationUtils from '@src/libs/TripReservationUtils'; import ROUTES from '@src/ROUTES'; import type {Reservation, ReservationTimeDetails} from '@src/types/onyx/Transaction'; -type TripDetailsViewProps = { - /** The active tripRoomReportID, used for Onyx subscription */ - tripRoomReportID: string; - - /** Whether we should display the horizontal rule below the component */ - shouldShowHorizontalRule: boolean; -}; - type ReservationViewProps = { reservation: Reservation; transactionID: string; @@ -142,6 +134,14 @@ function ReservationView({reservation, transactionID, tripRoomReportID, reservat ); } +type TripDetailsViewProps = { + /** The active tripRoomReportID, used for Onyx subscription */ + tripRoomReportID: string; + + /** Whether we should display the horizontal rule below the component */ + shouldShowHorizontalRule: boolean; +}; + function TripDetailsView({tripRoomReportID, shouldShowHorizontalRule}: TripDetailsViewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index e0899d1ee0a..a496b3dec56 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7359,8 +7359,9 @@ function canApproveIOU( isTransactionBeingScanned = true; } } + const isPayAtEndExpenseReport = isPayAtEndExpenseReportReportUtils(iouReport?.reportID, reportTransactions); - return isCurrentUserManager && !isOpenExpenseReport && !isApproved && !iouSettled && !isArchivedExpenseReport && !isTransactionBeingScanned; + return isCurrentUserManager && !isOpenExpenseReport && !isApproved && !iouSettled && !isArchivedExpenseReport && !isTransactionBeingScanned && !isPayAtEndExpenseReport; } function canIOUBePaid( diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 5976ac5de72..332f773a7b4 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -3,14 +3,14 @@ import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; -import TripDetailsView from '@components/ReportActionItem/TripDetailsView'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import onyxSubscribe from '@libs/onyxSubscribe'; -import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportUtils from '@libs/ReportUtils'; -import * as Report from '@userActions/Report'; +import {shouldReportActionBeVisible} from '@libs/ReportActionsUtils'; +import type {Ancestor} from '@libs/ReportUtils'; +import {canCurrentUserOpenReport, canUserPerformWriteAction as canUserPerformWriteActionReportUtils, getAllAncestorReportActionIDs, getAllAncestorReportActions} from '@libs/ReportUtils'; +import {navigateToConciergeChatAndDeleteReport} from '@userActions/Report'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; @@ -65,9 +65,9 @@ function ReportActionItemParentAction({ }: ReportActionItemParentActionProps) { const styles = useThemeStyles(); const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); - const ancestorIDs = useRef(ReportUtils.getAllAncestorReportActionIDs(report)); + const ancestorIDs = useRef(getAllAncestorReportActionIDs(report)); const ancestorReports = useRef>>({}); - const [allAncestors, setAllAncestors] = useState([]); + const [allAncestors, setAllAncestors] = useState([]); const {isOffline} = useNetwork(); useEffect(() => { @@ -83,7 +83,7 @@ function ReportActionItemParentAction({ // holds the report collection. However, allReports is not updated by the time this current callback is called. // Therefore we need to pass the up-to-date report to getAllAncestorReportActions so that it uses the up-to-date report value // to calculate, for instance, unread marker. - setAllAncestors(ReportUtils.getAllAncestorReportActions(report, val)); + setAllAncestors(getAllAncestorReportActions(report, val)); }, }), ); @@ -91,7 +91,7 @@ function ReportActionItemParentAction({ onyxSubscribe({ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${ancestorReportID}`, callback: () => { - setAllAncestors(ReportUtils.getAllAncestorReportActions(report)); + setAllAncestors(getAllAncestorReportActions(report)); }, }), ); @@ -110,7 +110,7 @@ function ReportActionItemParentAction({ {/* eslint-disable-next-line react-compiler/react-compiler */} {allAncestors.map((ancestor) => { const ancestorReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${ancestor.report.reportID}`]; - const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(ancestorReport); + const canUserPerformWriteAction = canUserPerformWriteActionReportUtils(ancestorReport); return ( Report.navigateToConciergeChatAndDeleteReport(ancestor.report.reportID)} + onClose={() => navigateToConciergeChatAndDeleteReport(ancestor.report.reportID)} > - {ReportActionsUtils.isTripPreview(ancestor?.reportAction) ? ( - - - - ) : ( - { - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( - ancestor.reportAction, - ancestor.reportAction.reportActionID ?? '-1', - canUserPerformWriteAction, - ); - // Pop the thread report screen before navigating to the chat report. - Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1')); - if (isVisibleAction && !isOffline) { - // Pop the chat report screen before navigating to the linked report action. - Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1', ancestor.reportAction.reportActionID)); - } + { + const isVisibleAction = shouldReportActionBeVisible(ancestor.reportAction, ancestor.reportAction.reportActionID, canUserPerformWriteAction); + // Pop the thread report screen before navigating to the chat report. + Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID)); + if (isVisibleAction && !isOffline) { + // Pop the chat report screen before navigating to the linked report action. + Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID, ancestor.reportAction.reportActionID)); } - : undefined - } - parentReportAction={parentReportAction} - report={ancestor.report} - reportActions={reportActions} - transactionThreadReport={transactionThreadReport} - action={ancestor.reportAction} - displayAsGroup={false} - isMostRecentIOUReportAction={false} - shouldDisplayNewMarker={ancestor.shouldDisplayNewMarker} - index={index} - isFirstVisibleReportAction={isFirstVisibleReportAction} - shouldUseThreadDividerLine={shouldUseThreadDividerLine} - isThreadReportParentAction - /> - )} + } + : undefined + } + parentReportAction={parentReportAction} + report={ancestor.report} + reportActions={reportActions} + transactionThreadReport={transactionThreadReport} + action={ancestor.reportAction} + displayAsGroup={false} + isMostRecentIOUReportAction={false} + shouldDisplayNewMarker={ancestor.shouldDisplayNewMarker} + index={index} + isFirstVisibleReportAction={isFirstVisibleReportAction} + shouldUseThreadDividerLine={shouldUseThreadDividerLine} + isThreadReportParentAction + /> ); })} diff --git a/src/pages/home/report/ReportActionsListItemRenderer.tsx b/src/pages/home/report/ReportActionsListItemRenderer.tsx index 63b2cb43d83..7e2da550860 100644 --- a/src/pages/home/report/ReportActionsListItemRenderer.tsx +++ b/src/pages/home/report/ReportActionsListItemRenderer.tsx @@ -1,11 +1,12 @@ import React, {memo, useMemo} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; -import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportUtils from '@libs/ReportUtils'; +import {getOriginalMessage, isSentMoneyReportAction, isTransactionThread} from '@libs/ReportActionsUtils'; +import {getTripTransactions, isChatThread, isInvoiceRoom, isPolicyExpenseChat, isTripRoom} from '@libs/ReportUtils'; import CONST from '@src/CONST'; import type {Report, ReportAction} from '@src/types/onyx'; import ReportActionItem from './ReportActionItem'; import ReportActionItemParentAction from './ReportActionItemParentAction'; +import TripSummary from './TripSummary'; type ReportActionsListItemRendererProps = { /** All the data of the action item */ @@ -71,12 +72,8 @@ function ReportActionsListItemRenderer({ shouldUseThreadDividerLine = false, parentReportActionForTransactionThread, }: ReportActionsListItemRendererProps) { - const shouldDisplayParentAction = - reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED && - ReportUtils.isChatThread(report) && - (!ReportActionsUtils.isTransactionThread(parentReportAction) || ReportActionsUtils.isSentMoneyReportAction(parentReportAction)); + const originalMessage = useMemo(() => getOriginalMessage(reportAction), [reportAction]); - const originalMessage = useMemo(() => ReportActionsUtils.getOriginalMessage(reportAction), [reportAction]); /** * Create a lightweight ReportAction so as to keep the re-rendering as light as possible by * passing in only the required props. @@ -145,20 +142,34 @@ function ReportActionsListItemRenderer({ ], ); - return shouldDisplayParentAction ? ( - - ) : ( + const shouldDisplayParentAction = + reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED && (!isTransactionThread(parentReportAction) || isSentMoneyReportAction(parentReportAction)); + + const tripTransactions = getTripTransactions(report?.reportID); + const shouldDisplayTripSummary = shouldDisplayParentAction && isTripRoom(report) && tripTransactions.length > 0; + + if (shouldDisplayTripSummary) { + return ; + } + + if (shouldDisplayParentAction && isChatThread(report)) { + return ( + + ); + } + + return ( ; +}; + +function TripSummary({report}: TripSummaryProps) { + const styles = useThemeStyles(); + + if (!report?.reportID) { + return null; + } + + return ( + + + + + + + + ); +} + +TripSummary.displayName = 'TripSummary'; + +export default TripSummary;