Skip to content

Commit 9107ba1

Browse files
authored
Merge pull request Expensify#65046 from Expensify/revert-63655-perf/create-report-transactions-derived-value
Revert "perf: transactions and violations by reports derived value"
2 parents fce5141 + 38cc3ef commit 9107ba1

25 files changed

Lines changed: 133 additions & 233 deletions

src/ONYXKEYS.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,6 @@ const ONYXKEYS = {
849849
},
850850
DERIVED: {
851851
REPORT_ATTRIBUTES: 'reportAttributes',
852-
REPORT_TRANSACTIONS_AND_VIOLATIONS: 'reportTransactionsAndViolations',
853852
},
854853
} as const;
855854

@@ -1203,7 +1202,6 @@ type OnyxValuesMapping = {
12031202

12041203
type OnyxDerivedValuesMapping = {
12051204
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: OnyxTypes.ReportAttributesDerivedValue;
1206-
[ONYXKEYS.DERIVED.REPORT_TRANSACTIONS_AND_VIOLATIONS]: OnyxTypes.ReportTransactionsAndViolationsDerivedValue;
12071205
};
12081206

12091207
type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping & OnyxDerivedValuesMapping;

src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ type MoneyRequestReportListProps = {
8282
/** Array of report actions for this report */
8383
reportActions?: OnyxTypes.ReportAction[];
8484

85-
/** All transactions grouped by reportID */
86-
transactionsAndViolationsByReport: OnyxTypes.ReportTransactionsAndViolationsDerivedValue;
85+
/** List of transactions belonging to this report */
86+
transactions?: OnyxTypes.Transaction[];
8787

8888
/** List of transactions that arrived when the report was open */
8989
newTransactions: OnyxTypes.Transaction[];
@@ -109,7 +109,7 @@ function MoneyRequestReportActionsList({
109109
report,
110110
policy,
111111
reportActions = [],
112-
transactionsAndViolationsByReport,
112+
transactions = [],
113113
newTransactions,
114114
hasNewerActions,
115115
hasOlderActions,
@@ -124,9 +124,7 @@ function MoneyRequestReportActionsList({
124124
const [isVisible, setIsVisible] = useState(Visibility.isVisible);
125125
const isFocused = useIsFocused();
126126
const route = useRoute<PlatformStackRouteProp<ReportsSplitNavigatorParamList, typeof SCREENS.REPORT>>();
127-
const {transactions: reportTransactions} = transactionsAndViolationsByReport[report.reportID] ?? {};
128-
const transactions = useMemo(() => Object.values(reportTransactions ?? {}) ?? [], [reportTransactions]);
129-
const reportTransactionIDs = useMemo(() => transactions.map((transaction) => transaction.transactionID), [transactions]);
127+
const reportTransactionIDs = transactions.map((transaction) => transaction.transactionID);
130128
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(report?.chatReportID)}`, {canBeMissing: true});
131129

132130
const reportID = report?.reportID;
@@ -486,7 +484,6 @@ function MoneyRequestReportActionsList({
486484
isFirstVisibleReportAction={firstVisibleReportActionID === reportAction.reportActionID}
487485
shouldHideThreadDividerLine
488486
linkedReportActionID={linkedReportActionID}
489-
transactionsAndViolationsByReport={transactionsAndViolationsByReport}
490487
/>
491488
);
492489
},
@@ -500,7 +497,6 @@ function MoneyRequestReportActionsList({
500497
unreadMarkerReportActionID,
501498
firstVisibleReportActionID,
502499
linkedReportActionID,
503-
transactionsAndViolationsByReport,
504500
allReports,
505501
],
506502
);

src/components/MoneyRequestReportView/MoneyRequestReportView.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {PortalHost} from '@gorhom/portal';
22
import React, {useCallback, useMemo} from 'react';
33
import {InteractionManager, View} from 'react-native';
4-
import type {OnyxEntry} from 'react-native-onyx';
4+
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
55
import {useOnyx} from 'react-native-onyx';
66
import HeaderGap from '@components/HeaderGap';
77
import MoneyReportHeader from '@components/MoneyReportHeader';
@@ -16,15 +16,14 @@ import useThemeStyles from '@hooks/useThemeStyles';
1616
import {removeFailedReport} from '@libs/actions/Report';
1717
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
1818
import Log from '@libs/Log';
19-
import {shouldDisplayReportTableView, shouldWaitForTransactions as shouldWaitForTransactionsUtil} from '@libs/MoneyRequestReportUtils';
19+
import {selectAllTransactionsForReport, shouldDisplayReportTableView, shouldWaitForTransactions as shouldWaitForTransactionsUtil} from '@libs/MoneyRequestReportUtils';
2020
import navigationRef from '@libs/Navigation/navigationRef';
2121
import {getFilteredReportActionsForReportView, getOneTransactionThreadReportID, isMoneyRequestAction} from '@libs/ReportActionsUtils';
2222
import {canEditReportAction, getReportOfflinePendingActionAndErrors, isReportTransactionThread} from '@libs/ReportUtils';
2323
import {buildCannedSearchQuery} from '@libs/SearchQueryUtils';
2424
import Navigation from '@navigation/Navigation';
2525
import ReportActionsView from '@pages/home/report/ReportActionsView';
2626
import ReportFooter from '@pages/home/report/ReportFooter';
27-
import CONST from '@src/CONST';
2827
import NAVIGATORS from '@src/NAVIGATORS';
2928
import ONYXKEYS from '@src/ONYXKEYS';
3029
import type {Route} from '@src/ROUTES';
@@ -48,9 +47,6 @@ type MoneyRequestReportViewProps = {
4847

4948
/** The `backTo` route that should be used when clicking back button */
5049
backToRoute: Route | undefined;
51-
52-
/** All transactions grouped by reportID */
53-
transactionsAndViolationsByReport: OnyxTypes.ReportTransactionsAndViolationsDerivedValue;
5450
};
5551

5652
function goBackFromSearchMoneyRequest() {
@@ -88,7 +84,7 @@ function getParentReportAction(parentReportActions: OnyxEntry<OnyxTypes.ReportAc
8884
return parentReportActions[parentReportActionID];
8985
}
9086

91-
function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayReportFooter, backToRoute, transactionsAndViolationsByReport = {}}: MoneyRequestReportViewProps) {
87+
function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayReportFooter, backToRoute}: MoneyRequestReportViewProps) {
9288
const styles = useThemeStyles();
9389
const {isOffline} = useNetwork();
9490

@@ -101,8 +97,11 @@ function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayRe
10197
const {reportActions: unfilteredReportActions, hasNewerActions, hasOlderActions} = usePaginatedReportActions(reportID);
10298
const reportActions = getFilteredReportActionsForReportView(unfilteredReportActions);
10399

104-
const {transactions: reportTransactions} = transactionsAndViolationsByReport[reportID ?? CONST.DEFAULT_NUMBER_ID];
105-
const transactions = useMemo(() => Object.values(reportTransactions ?? {}) ?? [], [reportTransactions]);
100+
const [transactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {
101+
selector: (allTransactions: OnyxCollection<OnyxTypes.Transaction>) => selectAllTransactionsForReport(allTransactions, reportID, reportActions),
102+
canBeMissing: true,
103+
});
104+
106105
const reportTransactionIDs = transactions?.map((transaction) => transaction.transactionID);
107106
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, reportActions ?? [], isOffline, reportTransactionIDs);
108107

@@ -218,7 +217,7 @@ function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayRe
218217
<MoneyRequestReportActionsList
219218
report={report}
220219
policy={policy}
221-
transactionsAndViolationsByReport={transactionsAndViolationsByReport}
220+
transactions={transactions}
222221
newTransactions={newTransactions}
223222
reportActions={reportActions}
224223
hasOlderActions={hasOlderActions}
@@ -234,7 +233,6 @@ function MoneyRequestReportView({report, policy, reportMetadata, shouldDisplayRe
234233
hasOlderActions={hasOlderActions}
235234
parentReportAction={parentReportAction}
236235
transactionThreadReportID={transactionThreadReportID}
237-
transactionsAndViolationsByReport={transactionsAndViolationsByReport}
238236
/>
239237
)}
240238
{shouldDisplayReportFooter ? (

src/components/ReportActionItem/MoneyRequestReportPreview/index.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import React, {useCallback, useMemo, useState} from 'react';
22
import type {LayoutChangeEvent, ListRenderItem} from 'react-native';
33
import {useOnyx} from 'react-native-onyx';
44
import TransactionPreview from '@components/ReportActionItem/TransactionPreview';
5-
import useNetwork from '@hooks/useNetwork';
65
import usePolicy from '@hooks/usePolicy';
6+
import useReportWithTransactionsAndViolations from '@hooks/useReportWithTransactionsAndViolations';
77
import useResponsiveLayout from '@hooks/useResponsiveLayout';
88
import useStyleUtils from '@hooks/useStyleUtils';
99
import useThemeStyles from '@hooks/useThemeStyles';
@@ -35,7 +35,6 @@ function MoneyRequestReportPreview({
3535
shouldDisplayContextMenu = true,
3636
isInvoice = false,
3737
shouldShowBorder,
38-
transactionsAndViolationsByReport,
3938
}: MoneyRequestReportPreviewProps) {
4039
const styles = useThemeStyles();
4140
const StyleUtils = useStyleUtils();
@@ -50,12 +49,8 @@ function MoneyRequestReportPreview({
5049
personalDetails?.[chatReport?.invoiceReceiver && 'accountID' in chatReport.invoiceReceiver ? chatReport.invoiceReceiver.accountID : CONST.DEFAULT_NUMBER_ID],
5150
canBeMissing: true,
5251
});
53-
const [iouReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, {canBeMissing: true});
54-
const {transactions: reportTransactions, violations} = transactionsAndViolationsByReport[iouReportID ?? CONST.DEFAULT_NUMBER_ID] ?? {};
55-
const {isOffline} = useNetwork();
56-
const filteredTransactions = Object.values(reportTransactions ?? {}).filter((transaction) => isOffline || transaction?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
52+
const [iouReport, transactions, violations] = useReportWithTransactionsAndViolations(iouReportID);
5753
const policy = usePolicy(policyID);
58-
const transactions = useMemo(() => Object.values(filteredTransactions ?? {}) ?? [], [filteredTransactions]);
5954
const lastTransaction = transactions?.at(0);
6055
const lastTransactionViolations = useTransactionViolations(lastTransaction?.transactionID);
6156
const isTrackExpenseAction = isTrackExpenseActionReportActionsUtils(action);

src/components/ReportActionItem/MoneyRequestReportPreview/types.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type {LayoutChangeEvent, ListRenderItem, StyleProp, ViewStyle} from 'reac
22
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
33
import type {TransactionPreviewStyleType} from '@components/ReportActionItem/TransactionPreview/types';
44
import type {ContextMenuAnchor} from '@pages/home/report/ContextMenu/ReportActionContextMenu';
5-
import type {PersonalDetails, Policy, Report, ReportAction, ReportTransactionsAndViolationsDerivedValue, Transaction, TransactionViolation, TransactionViolations} from '@src/types/onyx';
5+
import type {PersonalDetails, Policy, Report, ReportAction, Transaction, TransactionViolation, TransactionViolations} from '@src/types/onyx';
66

77
type TransactionPreviewStyle = {
88
[key in keyof TransactionPreviewStyleType]: number;
@@ -56,9 +56,6 @@ type MoneyRequestReportPreviewProps = {
5656

5757
/** Whether to show a border to separate Reports Chat Item and Money Request Report Preview */
5858
shouldShowBorder?: boolean;
59-
60-
/** All transactions grouped by reportID */
61-
transactionsAndViolationsByReport: ReportTransactionsAndViolationsDerivedValue;
6259
};
6360

6461
type MoneyRequestReportPreviewContentOnyxProps = {
@@ -73,7 +70,7 @@ type MoneyRequestReportPreviewContentOnyxProps = {
7370
};
7471

7572
type MoneyRequestReportPreviewContentProps = MoneyRequestReportPreviewContentOnyxProps &
76-
Omit<MoneyRequestReportPreviewProps, 'policyID' | 'transactionsAndViolationsByReport'> & {
73+
Omit<MoneyRequestReportPreviewProps, 'policyID'> & {
7774
/** Extra styles passed used by MoneyRequestReportPreviewContent */
7875
reportPreviewStyles: MoneyRequestReportPreviewStyleType;
7976

src/components/ReportActionItem/TripRoomPreview.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import variables from '@styles/variables';
2828
import * as Expensicons from '@src/components/Icon/Expensicons';
2929
import CONST from '@src/CONST';
3030
import ROUTES from '@src/ROUTES';
31-
import type {Report, ReportAction, ReportTransactionsAndViolationsDerivedValue} from '@src/types/onyx';
31+
import type {Report, ReportAction} from '@src/types/onyx';
3232
import type {Reservation} from '@src/types/onyx/Transaction';
3333

3434
type TripRoomPreviewProps = {
@@ -55,9 +55,6 @@ type TripRoomPreviewProps = {
5555

5656
/** Whether context menu should be shown on press */
5757
shouldDisplayContextMenu?: boolean;
58-
59-
/** The transactions for the report */
60-
transactionsAndViolationsByReport: ReportTransactionsAndViolationsDerivedValue;
6158
};
6259

6360
type ReservationViewProps = {
@@ -151,12 +148,11 @@ function TripRoomPreview({
151148
isHovered = false,
152149
checkIfContextMenuActive = () => {},
153150
shouldDisplayContextMenu = true,
154-
transactionsAndViolationsByReport,
155151
}: TripRoomPreviewProps) {
156152
const styles = useThemeStyles();
157153
const {translate} = useLocalize();
158154
const chatReportID = chatReport?.reportID;
159-
const tripTransactions = useTripTransactions(chatReportID, transactionsAndViolationsByReport);
155+
const tripTransactions = useTripTransactions(chatReportID);
160156

161157
const reservationsData: ReservationData[] = getReservationsFromTripTransactions(tripTransactions);
162158
const dateInfo =
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
2+
import {reportTransactionsSelector} from '@libs/ReportUtils';
3+
import CONST from '@src/CONST';
4+
import ONYXKEYS from '@src/ONYXKEYS';
5+
import type {Report, Transaction, TransactionViolation} from '@src/types/onyx';
6+
import useNetwork from './useNetwork';
7+
import useOnyx from './useOnyx';
8+
9+
const DEFAULT_TRANSACTIONS: Transaction[] = [];
10+
const DEFAULT_VIOLATIONS: Record<string, TransactionViolation[]> = {};
11+
12+
function useReportWithTransactionsAndViolations(reportID?: string): [OnyxEntry<Report>, Transaction[], OnyxCollection<TransactionViolation[]>] {
13+
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {canBeMissing: false});
14+
const [transactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {
15+
selector: (_transactions) => reportTransactionsSelector(_transactions, reportID),
16+
canBeMissing: true,
17+
});
18+
const {isOffline} = useNetwork();
19+
const filteredTransactions = transactions?.filter((transaction) => isOffline || transaction?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
20+
const [violations] = useOnyx(
21+
ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
22+
{
23+
selector: (allViolations) =>
24+
Object.fromEntries(
25+
Object.entries(allViolations ?? {}).filter(([key]) =>
26+
filteredTransactions?.some((transaction) => transaction.transactionID === key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, '')),
27+
),
28+
),
29+
canBeMissing: true,
30+
},
31+
[filteredTransactions],
32+
);
33+
return [report, filteredTransactions ?? DEFAULT_TRANSACTIONS, violations ?? DEFAULT_VIOLATIONS];
34+
}
35+
36+
export default useReportWithTransactionsAndViolations;

src/hooks/useTripTransactions.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {useOnyx} from 'react-native-onyx';
2-
import CONST from '@src/CONST';
32
import ONYXKEYS from '@src/ONYXKEYS';
4-
import type {ReportTransactionsAndViolationsDerivedValue, Transaction} from '@src/types/onyx';
3+
import type {Transaction} from '@src/types/onyx';
54

65
/**
76
* Hook to fetch transactions associated with a specific `tripRoom` report.
@@ -13,17 +12,26 @@ import type {ReportTransactionsAndViolationsDerivedValue, Transaction} from '@sr
1312
* @param reportID - The trip room's reportID.
1413
* @returns Transactions linked to the specified trip room.
1514
*/
16-
function useTripTransactions(reportID: string | undefined, transactionsAndViolationsByReport: ReportTransactionsAndViolationsDerivedValue): Transaction[] {
15+
function useTripTransactions(reportID: string | undefined): Transaction[] {
1716
const [tripTransactionReportIDs = []] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {
1817
selector: (reports) =>
1918
Object.values(reports ?? {})
2019
.filter((report) => report && report.chatReportID === reportID)
2120
.map((report) => report?.reportID),
22-
canBeMissing: true,
2321
});
24-
const {transactions} = transactionsAndViolationsByReport[reportID ?? CONST.DEFAULT_NUMBER_ID] ?? {};
25-
const tripTransactions = tripTransactionReportIDs.flatMap((transactionReportID) => transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionReportID}`] ?? []);
22+
const [tripTransactions = []] = useOnyx(
23+
ONYXKEYS.COLLECTION.TRANSACTION,
24+
{
25+
selector: (transactions) => {
26+
if (!tripTransactionReportIDs.length) {
27+
return [];
28+
}
2629

30+
return Object.values(transactions ?? {}).filter((transaction): transaction is Transaction => !!transaction && tripTransactionReportIDs.includes(transaction.reportID));
31+
},
32+
},
33+
[tripTransactionReportIDs],
34+
);
2735
return tripTransactions;
2836
}
2937

src/libs/MoneyRequestReportUtils.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type {OnyxEntry} from 'react-native-onyx';
1+
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
22
import type {ValueOf} from 'type-fest';
33
import type {TransactionListItemType} from '@components/SelectionList/types';
44
import CONST from '@src/CONST';
@@ -69,15 +69,20 @@ function getReportIDForTransaction(transactionItem: TransactionListItemType) {
6969
}
7070

7171
/**
72-
* Filters all available transactions and returns the ones that belong to not removed parent action.
72+
* Filters all available transactions and returns the ones that belong to a specific report (by `reportID`).
73+
* It is used as an onyx selector, to make sure that report related views do not process all transactions in onyx.
7374
*/
74-
function getAllNonDeletedTransactions(transactions: Transaction[], reportActions: ReportAction[]) {
75-
return transactions.filter((transaction): transaction is Transaction => {
75+
function selectAllTransactionsForReport(transactions: OnyxCollection<Transaction>, reportID: string | undefined, reportActions: ReportAction[]) {
76+
if (!reportID) {
77+
return [];
78+
}
79+
80+
return Object.values(transactions ?? {}).filter((transaction): transaction is Transaction => {
7681
if (!transaction) {
7782
return false;
7883
}
7984
const action = getIOUActionForTransactionID(reportActions, transaction.transactionID);
80-
return !isDeletedParentAction(action);
85+
return transaction.reportID === reportID && !isDeletedParentAction(action);
8186
});
8287
}
8388

@@ -159,7 +164,7 @@ export {
159164
getThreadReportIDsForTransactions,
160165
getReportIDForTransaction,
161166
getTotalAmountForIOUReportPreviewButton,
162-
getAllNonDeletedTransactions,
167+
selectAllTransactionsForReport,
163168
isSingleTransactionReport,
164169
shouldDisplayReportTableView,
165170
shouldWaitForTransactions,

src/libs/actions/OnyxDerived/ONYX_DERIVED_VALUES.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type {ValueOf} from 'type-fest';
22
import ONYXKEYS from '@src/ONYXKEYS';
33
import reportAttributesConfig from './configs/reportAttributes';
4-
import reportTransactionsAndViolationsConfig from './configs/reportTransactionsAndViolations';
54
import type {OnyxDerivedValueConfig} from './types';
65

76
/**
@@ -10,7 +9,6 @@ import type {OnyxDerivedValueConfig} from './types';
109
*/
1110
const ONYX_DERIVED_VALUES = {
1211
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: reportAttributesConfig,
13-
[ONYXKEYS.DERIVED.REPORT_TRANSACTIONS_AND_VIOLATIONS]: reportTransactionsAndViolationsConfig,
1412
} as const satisfies {
1513
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1614
[Key in ValueOf<typeof ONYXKEYS.DERIVED>]: OnyxDerivedValueConfig<Key, any>;

0 commit comments

Comments
 (0)