Skip to content

Commit ba04c09

Browse files
committed
perf: narrow Onyx subs in InvoiceSenderField and ReportField
1 parent cfeaadd commit ba04c09

2 files changed

Lines changed: 28 additions & 24 deletions

File tree

src/components/MoneyRequestConfirmationList/sections/InvoiceSenderField.tsx

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {emailSelector} from '@selectors/Session';
22
import React from 'react';
3-
import type {OnyxEntry} from 'react-native-onyx';
3+
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
44
import MenuItem from '@components/MenuItem';
55
import useLocalize from '@hooks/useLocalize';
66
import useOnyx from '@hooks/useOnyx';
@@ -35,37 +35,42 @@ type InvoiceSenderFieldProps = {
3535
transaction: OnyxEntry<OnyxTypes.Transaction>;
3636
};
3737

38+
const senderWorkspaceSelector = (policy: OnyxEntry<OnyxTypes.Policy>) => (policy ? {id: policy.id, name: policy.name, avatarURL: policy.avatarURL} : undefined);
39+
40+
const createCanUpdateSenderWorkspaceSelector =
41+
(selectedParticipants: Participant[], currentUserLogin: string | undefined, isFromGlobalCreate: boolean) =>
42+
(policies: OnyxCollection<OnyxTypes.Policy>): boolean => {
43+
const isInvoiceRoomParticipant = selectedParticipants.some((participant) => participant.isInvoiceRoom);
44+
return canSendInvoice(policies ?? null, currentUserLogin) && isFromGlobalCreate && !isInvoiceRoomParticipant;
45+
};
46+
3847
function InvoiceSenderField({selectedParticipants, isReadOnly, didConfirm, iouType, reportID, transaction}: InvoiceSenderFieldProps) {
3948
const styles = useThemeStyles();
4049
const {translate} = useLocalize();
4150

42-
// canSendInvoice needs the full policy collection to check all admin workspaces
43-
const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY);
51+
const senderPolicyID = selectedParticipants.find((participant) => participant.isSender)?.policyID;
52+
53+
const [senderWorkspace] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${senderPolicyID}`, {selector: senderWorkspaceSelector});
4454
const [currentUserLogin] = useOnyx(ONYXKEYS.SESSION, {selector: emailSelector});
4555

4656
const isFromGlobalCreate = !!transaction?.isFromGlobalCreate;
4757

48-
const senderWorkspace = (() => {
49-
const senderWorkspaceParticipant = selectedParticipants.find((participant) => participant.isSender);
50-
return allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${senderWorkspaceParticipant?.policyID}`];
51-
})();
52-
53-
const canUpdateSenderWorkspace = (() => {
54-
const isInvoiceRoomParticipant = selectedParticipants.some((participant) => participant.isInvoiceRoom);
55-
return canSendInvoice(allPolicies, currentUserLogin) && isFromGlobalCreate && !isInvoiceRoomParticipant;
56-
})();
58+
// canSendInvoice needs the full policy collection to check all admin workspaces
59+
const [canUpdateSenderWorkspace] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {
60+
selector: createCanUpdateSenderWorkspaceSelector(selectedParticipants, currentUserLogin, isFromGlobalCreate),
61+
});
5762

5863
return (
5964
<MenuItem
6065
avatarID={senderWorkspace?.id}
61-
shouldShowRightIcon={!isReadOnly && canUpdateSenderWorkspace}
66+
shouldShowRightIcon={!isReadOnly && !!canUpdateSenderWorkspace}
6267
title={senderWorkspace?.name}
63-
icon={senderWorkspace?.avatarURL ? senderWorkspace?.avatarURL : getDefaultWorkspaceAvatar(senderWorkspace?.name)}
68+
icon={senderWorkspace?.avatarURL ? senderWorkspace.avatarURL : getDefaultWorkspaceAvatar(senderWorkspace?.name)}
6469
iconType={CONST.ICON_TYPE_WORKSPACE}
6570
description={translate('workspace.common.workspace')}
6671
label={translate('workspace.invoices.sendFrom')}
6772
isLabelHoverable={false}
68-
interactive={!isReadOnly && canUpdateSenderWorkspace}
73+
interactive={!isReadOnly && !!canUpdateSenderWorkspace}
6974
onPress={() => {
7075
if (!transaction?.transactionID) {
7176
return;

src/components/MoneyRequestConfirmationList/sections/ReportField.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import ROUTES from '@src/ROUTES';
1616
import type * as OnyxTypes from '@src/types/onyx';
1717
import type {Participant} from '@src/types/onyx/IOU';
1818

19+
const createOutstandingReportsForPolicySelector = (policyID: string | undefined) => (derived: OnyxEntry<OnyxTypes.OutstandingReportsByPolicyIDDerivedValue>) =>
20+
derived?.[policyID ?? CONST.DEFAULT_NUMBER_ID];
21+
1922
type ReportFieldProps = {
2023
/** The selected participants */
2124
selectedParticipants: Participant[];
@@ -50,8 +53,9 @@ function ReportField({selectedParticipants, iouType, reportID, reportActionID, a
5053
const {translate, localeCompare} = useLocalize();
5154

5255
const reportAttributes = useReportAttributes();
56+
const policyID = selectedParticipants?.at(0)?.policyID;
5357
const [reportNameValuePairs] = useOnyx(ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS);
54-
const [outstandingReportsByPolicyID] = useOnyx(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID);
58+
const [outstandingReportsForPolicy] = useOnyx(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID, {selector: createOutstandingReportsForPolicySelector(policyID)});
5559

5660
// Per-key report subscriptions instead of full COLLECTION.REPORT
5761
const [transactionReportEntry] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`);
@@ -66,18 +70,13 @@ function ReportField({selectedParticipants, iouType, reportID, reportActionID, a
6670
* We need to check if the transaction report exists first in order to prevent the outstanding reports from being used.
6771
* Also we need to check if transaction report exists in outstanding reports in order to show a correct report name.
6872
*/
69-
const policyID = selectedParticipants?.at(0)?.policyID;
7073
const shouldUseTransactionReport = (!!transactionReportEntry && isReportOutstanding(transactionReportEntry, policyID, undefined, false)) || isUnreported;
7174

7275
const ownerAccountID = selectedParticipants?.at(0)?.ownerAccountID;
7376

74-
const availableOutstandingReports = getOutstandingReportsForUser(
75-
policyID,
76-
ownerAccountID,
77-
outstandingReportsByPolicyID?.[policyID ?? CONST.DEFAULT_NUMBER_ID] ?? {},
78-
reportNameValuePairs,
79-
false,
80-
).sort((a, b) => localeCompare(a?.reportName?.toLowerCase() ?? '', b?.reportName?.toLowerCase() ?? ''));
77+
const availableOutstandingReports = getOutstandingReportsForUser(policyID, ownerAccountID, outstandingReportsForPolicy ?? {}, reportNameValuePairs, false).sort((a, b) =>
78+
localeCompare(a?.reportName?.toLowerCase() ?? '', b?.reportName?.toLowerCase() ?? ''),
79+
);
8180

8281
const outstandingReportID = isPolicyExpenseChat ? (iouReportIDFromMain ?? availableOutstandingReports.at(0)?.reportID) : reportID;
8382

0 commit comments

Comments
 (0)