Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 27 additions & 69 deletions src/components/MoneyRequestReportView/MoneyRequestReportView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import HeaderGap from '@components/HeaderGap';
import MoneyReportHeader from '@components/MoneyReportHeader';
import MoneyRequestHeader from '@components/MoneyRequestHeader';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ReportActionsSkeletonView from '@components/ReportActionsSkeletonView';
import ReportHeaderSkeletonView from '@components/ReportHeaderSkeletonView';
Expand All @@ -16,13 +15,12 @@ import useThemeStyles from '@hooks/useThemeStyles';
import {removeFailedReport} from '@libs/actions/Report';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import Log from '@libs/Log';
import {selectAllTransactionsForReport, shouldDisplayReportTableView, shouldWaitForTransactions as shouldWaitForTransactionsUtil} from '@libs/MoneyRequestReportUtils';
import {selectAllTransactionsForReport, shouldWaitForTransactions as shouldWaitForTransactionsUtil} from '@libs/MoneyRequestReportUtils';
import navigationRef from '@libs/Navigation/navigationRef';
import {getFilteredReportActionsForReportView, getOneTransactionThreadReportID, isMoneyRequestAction} from '@libs/ReportActionsUtils';
import {canEditReportAction, getReportOfflinePendingActionAndErrors, isReportTransactionThread} from '@libs/ReportUtils';
import {canEditReportAction, getReportOfflinePendingActionAndErrors} from '@libs/ReportUtils';
import {buildCannedSearchQuery} from '@libs/SearchQueryUtils';
import Navigation from '@navigation/Navigation';
import ReportActionsView from '@pages/home/report/ReportActionsView';
import ReportFooter from '@pages/home/report/ReportFooter';
import CONST from '@src/CONST';
import NAVIGATORS from '@src/NAVIGATORS';
Expand Down Expand Up @@ -131,52 +129,10 @@ function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayRe
InteractionManager.runAfterInteractions(() => removeFailedReport(reportID));
}, [reportID]);

// Special case handling a report that is a transaction thread
// If true we will use standard `ReportActionsView` to display report data and a special header, anything else is handled via `MoneyRequestReportActionsList`
const isTransactionThreadView = isReportTransactionThread(report);

// Prevent the empty state flash by ensuring transaction data is fully loaded before deciding which view to render
// We need to wait for both the selector to finish AND ensure we're not in a loading state where transactions could still populate
const shouldWaitForTransactions = shouldWaitForTransactionsUtil(report, transactions, reportMetadata);

const isEmptyTransactionReport = transactions && transactions.length === 0 && transactionThreadReportID === undefined;
const shouldDisplayMoneyRequestActionsList = !!isEmptyTransactionReport || shouldDisplayReportTableView(report, transactions ?? []);

const reportHeaderView = useMemo(
() =>
isTransactionThreadView ? (
<MoneyRequestHeader
report={report}
policy={policy}
parentReportAction={parentReportAction}
onBackButtonPress={() => {
if (!backToRoute) {
goBackFromSearchMoneyRequest();
return;
}
Navigation.goBack(backToRoute);
}}
/>
) : (
<MoneyReportHeader
report={report}
policy={policy}
reportActions={reportActions}
transactionThreadReportID={transactionThreadReportID}
isLoadingInitialReportActions={isLoadingInitialReportActions}
shouldDisplayBackButton
onBackButtonPress={() => {
if (!backToRoute) {
goBackFromSearchMoneyRequest();
return;
}
Navigation.goBack(backToRoute);
}}
/>
),
[backToRoute, isLoadingInitialReportActions, isTransactionThreadView, parentReportAction, policy, report, reportActions, transactionThreadReportID],
);

if (!!(isLoadingInitialReportActions && reportActions.length === 0 && !isOffline) || shouldWaitForTransactions) {
return <InitialLoadingSkeleton styles={styles} />;
}
Expand Down Expand Up @@ -221,30 +177,32 @@ function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayRe
errorRowStyles={[styles.ph5, styles.mv2]}
>
<HeaderGap />
{reportHeaderView}
<MoneyReportHeader
report={report}
policy={policy}
reportActions={reportActions}
transactionThreadReportID={transactionThreadReportID}
isLoadingInitialReportActions={isLoadingInitialReportActions}
shouldDisplayBackButton
onBackButtonPress={() => {
if (!backToRoute) {
goBackFromSearchMoneyRequest();
return;
}
Navigation.goBack(backToRoute);
}}
/>
<View style={[styles.overflowHidden, styles.flex1]}>
{shouldDisplayMoneyRequestActionsList ? (
<MoneyRequestReportActionsList
report={report}
policy={policy}
transactions={transactions}
newTransactions={newTransactions}
reportActions={reportActions}
hasOlderActions={hasOlderActions}
hasNewerActions={hasNewerActions}
showReportActionsLoadingState={isLoadingInitialReportActions && !reportMetadata?.hasOnceLoadedReportActions}
/>
) : (
<ReportActionsView
report={report}
reportActions={reportActions}
isLoadingInitialReportActions={reportMetadata?.isLoadingInitialReportActions}
hasNewerActions={hasNewerActions}
hasOlderActions={hasOlderActions}
parentReportAction={parentReportAction}
transactionThreadReportID={transactionThreadReportID}
/>
)}
<MoneyRequestReportActionsList
report={report}
policy={policy}
transactions={transactions}
newTransactions={newTransactions}
reportActions={reportActions}
hasOlderActions={hasOlderActions}
hasNewerActions={hasNewerActions}
showReportActionsLoadingState={isLoadingInitialReportActions && !reportMetadata?.hasOnceLoadedReportActions}
/>
{shouldDisplayReportFooter ? (
<>
<ReportFooter
Expand Down
37 changes: 1 addition & 36 deletions src/libs/MoneyRequestReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
hasHeldExpenses as hasHeldExpensesReportUtils,
hasOnlyHeldExpenses as hasOnlyHeldExpensesReportUtils,
hasUpdatedTotal,
isReportTransactionThread,
} from './ReportUtils';

/**
Expand Down Expand Up @@ -67,37 +66,11 @@ function selectAllTransactionsForReport(transactions: OnyxCollection<Transaction
});
}

/**
* Given a list of transaction, this function checks if a given report has exactly one transaction
*
* Note: this function may seem a bit trivial, but it's used as a guarantee that the same logic of checking for report
* is used in context of Search and Inbox
*/
function isSingleTransactionReport(report: OnyxEntry<Report>, transactions: Transaction[]) {
if (transactions.length !== 1) {
return false;
}

return transactions.at(0)?.reportID === report?.reportID;
}

/**
* Returns whether a "table" ReportView/MoneyRequestReportView should be used for the report.
*
* If report is a special "transaction thread" we want to use other Report views.
* Likewise, if report has only 1 connected transaction, then we also use other views.
*/
function shouldDisplayReportTableView(report: OnyxEntry<Report>, transactions: Transaction[]) {
return !isReportTransactionThread(report) && !isSingleTransactionReport(report, transactions);
}

function shouldWaitForTransactions(report: OnyxEntry<Report>, transactions: Transaction[] | undefined, reportMetadata: OnyxEntry<ReportMetadata>) {
const isTransactionDataReady = transactions !== undefined;
const isTransactionThreadView = isReportTransactionThread(report);
const isStillLoadingData = !!reportMetadata?.isLoadingInitialReportActions || !!reportMetadata?.isLoadingOlderReportActions || !!reportMetadata?.isLoadingNewerReportActions;
return (
(!isTransactionDataReady || (isStillLoadingData && transactions?.length === 0)) &&
!isTransactionThreadView &&
report?.pendingFields?.createReport !== CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD &&
!reportMetadata?.hasOnceLoadedReportActions
);
Expand Down Expand Up @@ -139,12 +112,4 @@ const getTotalAmountForIOUReportPreviewButton = (report: OnyxEntry<Report>, poli
return convertToDisplayString(totalDisplaySpend, report?.currency);
};

export {
isActionVisibleOnMoneyRequestReport,
getThreadReportIDsForTransactions,
getTotalAmountForIOUReportPreviewButton,
selectAllTransactionsForReport,
isSingleTransactionReport,
shouldDisplayReportTableView,
shouldWaitForTransactions,
};
export {isActionVisibleOnMoneyRequestReport, getThreadReportIDsForTransactions, getTotalAmountForIOUReportPreviewButton, selectAllTransactionsForReport, shouldWaitForTransactions};
4 changes: 2 additions & 2 deletions src/pages/home/ReportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import useViewportOffsetTop from '@hooks/useViewportOffsetTop';
import {hideEmojiPicker} from '@libs/actions/EmojiPickerAction';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import Log from '@libs/Log';
import {selectAllTransactionsForReport, shouldDisplayReportTableView, shouldWaitForTransactions as shouldWaitForTransactionsUtil} from '@libs/MoneyRequestReportUtils';
import {selectAllTransactionsForReport, shouldWaitForTransactions as shouldWaitForTransactionsUtil} from '@libs/MoneyRequestReportUtils';
import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import clearReportNotifications from '@libs/Notification/clearReportNotifications';
Expand Down Expand Up @@ -769,7 +769,7 @@ function ReportScreen({route, navigation}: ReportScreenProps) {
}

// If true reports that are considered MoneyRequest | InvoiceReport will get the new report table view
const shouldDisplayMoneyRequestActionsList = isMoneyRequestOrInvoiceReport && shouldDisplayReportTableView(report, reportTransactions ?? []);
const shouldDisplayMoneyRequestActionsList = isMoneyRequestOrInvoiceReport;

return (
<ActionListContext.Provider value={actionListValue}>
Expand Down
7 changes: 0 additions & 7 deletions src/pages/home/report/ReportActionsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ import {
isConsecutiveActionMadeByPreviousActor,
isConsecutiveChronosAutomaticTimerAction,
isCurrentActionUnread,
isDeletedParentAction,
isReportPreviewAction,
isReversedTransaction,
isTransactionThread,
wasMessageReceivedWhileOffline,
} from '@libs/ReportActionsUtils';
import {
Expand Down Expand Up @@ -521,10 +518,6 @@ function ReportActionsList({
return false;
}

if (isTransactionThread(parentReportAction)) {
return !isDeletedParentAction(parentReportAction) && !isReversedTransaction(parentReportAction);
}

if (isTaskReport(report)) {
return !isCanceledTaskReport(report, parentReportAction);
}
Expand Down