Skip to content

Commit 99b876a

Browse files
committed
Revert "Merge pull request Expensify#88105 from Expensify/revert-87361-perf/extract-money-report-header-actions"
This reverts commit 06e4e74, reversing changes made to 19d70c2.
1 parent 9317075 commit 99b876a

18 files changed

Lines changed: 2578 additions & 2055 deletions

src/components/MoneyReportHeader.tsx

Lines changed: 54 additions & 1990 deletions
Large diffs are not rendered by default.

src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx

Lines changed: 397 additions & 0 deletions
Large diffs are not rendered by default.

src/components/MoneyReportHeaderActions/MoneyReportHeaderSelectionDropdown.tsx

Lines changed: 532 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import React, {useEffect, useRef} from 'react';
2+
import {View} from 'react-native';
3+
import type {ValueOf} from 'type-fest';
4+
import type {ButtonWithDropdownMenuRef} from '@components/ButtonWithDropdownMenu/types';
5+
import MoneyReportHeaderPrimaryAction from '@components/MoneyReportHeaderPrimaryAction';
6+
import {useSearchActionsContext, useSearchStateContext} from '@components/Search/SearchContext';
7+
import useExportAgainModal from '@hooks/useExportAgainModal';
8+
import useOnyx from '@hooks/useOnyx';
9+
import useResponsiveLayout from '@hooks/useResponsiveLayout';
10+
import useResponsiveLayoutOnWideRHP from '@hooks/useResponsiveLayoutOnWideRHP';
11+
import useThemeStyles from '@hooks/useThemeStyles';
12+
import useTransactionThreadReport from '@hooks/useTransactionThreadReport';
13+
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
14+
import CONST from '@src/CONST';
15+
import ONYXKEYS from '@src/ONYXKEYS';
16+
import MoneyReportHeaderSecondaryActions from './MoneyReportHeaderSecondaryActions';
17+
import MoneyReportHeaderSelectionDropdown from './MoneyReportHeaderSelectionDropdown';
18+
import type {MoneyReportHeaderActionsProps} from './types';
19+
20+
/**
21+
* Narrow the wide primaryAction union to what report-level secondary actions accept.
22+
* TRANSACTION_PRIMARY_ACTIONS values (e.g. "keepThisOne") are irrelevant here.
23+
*/
24+
function narrowPrimaryAction(primaryAction: MoneyReportHeaderActionsProps['primaryAction']): ValueOf<typeof CONST.REPORT.PRIMARY_ACTIONS> | '' {
25+
if ((Object.values(CONST.REPORT.PRIMARY_ACTIONS) as string[]).includes(primaryAction)) {
26+
return primaryAction as ValueOf<typeof CONST.REPORT.PRIMARY_ACTIONS>;
27+
}
28+
return '';
29+
}
30+
31+
function MoneyReportHeaderActions({reportID, primaryAction, isReportInSearch, backTo}: MoneyReportHeaderActionsProps) {
32+
const styles = useThemeStyles();
33+
const dropdownMenuRef = useRef<ButtonWithDropdownMenuRef>(null) as React.RefObject<ButtonWithDropdownMenuRef>;
34+
35+
// We need isSmallScreenWidth for the hold expense modal layout https://github.com/Expensify/App/pull/47990#issuecomment-2362382026
36+
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
37+
const {shouldUseNarrowLayout, isMediumScreenWidth} = useResponsiveLayout();
38+
const shouldDisplayNarrowVersion = shouldUseNarrowLayout || isMediumScreenWidth;
39+
const {isWideRHPDisplayedOnWideLayout, isSuperWideRHPDisplayedOnWideLayout} = useResponsiveLayoutOnWideRHP();
40+
const shouldDisplayNarrowMoreButton = !shouldDisplayNarrowVersion || isWideRHPDisplayedOnWideLayout || isSuperWideRHPDisplayedOnWideLayout;
41+
42+
const [moneyRequestReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
43+
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(moneyRequestReport?.chatReportID)}`);
44+
45+
const {transactionThreadReportID} = useTransactionThreadReport(reportID);
46+
47+
const {triggerExportOrConfirm} = useExportAgainModal(moneyRequestReport?.reportID, moneyRequestReport?.policyID);
48+
49+
const {selectedTransactionIDs} = useSearchStateContext();
50+
const {clearSelectedTransactions} = useSearchActionsContext();
51+
const hasSelectedTransactions = !!selectedTransactionIDs.length;
52+
const isTransactionThread = !!transactionThreadReportID;
53+
54+
useEffect(() => {
55+
if (!transactionThreadReportID) {
56+
return;
57+
}
58+
59+
clearSelectedTransactions(true);
60+
}, [transactionThreadReportID]); // eslint-disable-line react-hooks/exhaustive-deps
61+
62+
const narrowedPrimaryAction = narrowPrimaryAction(primaryAction);
63+
64+
if (hasSelectedTransactions && !isTransactionThread) {
65+
return (
66+
<View style={shouldDisplayNarrowMoreButton ? undefined : [styles.dFlex, styles.w100, styles.ph5, styles.pb3]}>
67+
<MoneyReportHeaderSelectionDropdown
68+
reportID={reportID}
69+
primaryAction={narrowedPrimaryAction}
70+
isReportInSearch={isReportInSearch}
71+
wrapperStyle={shouldDisplayNarrowMoreButton ? undefined : styles.w100}
72+
/>
73+
</View>
74+
);
75+
}
76+
77+
return (
78+
<View style={[styles.flexRow, styles.gap2, ...(!shouldDisplayNarrowMoreButton ? [styles.pb3, styles.ph5, styles.w100, styles.alignItemsCenter, styles.justifyContentCenter] : [])]}>
79+
{!!primaryAction && (
80+
<View style={!shouldDisplayNarrowMoreButton ? [styles.flex1] : undefined}>
81+
<MoneyReportHeaderPrimaryAction
82+
reportID={reportID}
83+
chatReportID={chatReport?.reportID}
84+
primaryAction={primaryAction}
85+
onExportModalOpen={() => triggerExportOrConfirm(CONST.REPORT.EXPORT_OPTIONS.EXPORT_TO_INTEGRATION)}
86+
/>
87+
</View>
88+
)}
89+
<MoneyReportHeaderSecondaryActions
90+
reportID={reportID}
91+
primaryAction={narrowedPrimaryAction}
92+
isReportInSearch={isReportInSearch}
93+
backTo={backTo}
94+
dropdownMenuRef={dropdownMenuRef}
95+
/>
96+
</View>
97+
);
98+
}
99+
100+
export default MoneyReportHeaderActions;
101+
export type {MoneyReportHeaderActionsProps};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type {ValueOf} from 'type-fest';
2+
import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types';
3+
import type {PopoverMenuItem} from '@components/PopoverMenu';
4+
import type CONST from '@src/CONST';
5+
import type {Route} from '@src/ROUTES';
6+
7+
type SecondaryActionEntry = DropdownOption<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>> & Pick<PopoverMenuItem, 'backButtonText' | 'rightIcon'>;
8+
9+
type MoneyReportHeaderActionsProps = {
10+
reportID: string | undefined;
11+
primaryAction: ValueOf<typeof CONST.REPORT.PRIMARY_ACTIONS> | ValueOf<typeof CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS> | '';
12+
isReportInSearch?: boolean;
13+
backTo?: Route;
14+
};
15+
16+
export type {SecondaryActionEntry, MoneyReportHeaderActionsProps};

src/components/MoneyReportHeaderPrimaryAction/ApprovePrimaryAction.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import Button from '@components/Button';
3+
import {usePaymentAnimationsContext} from '@components/PaymentAnimationsContext';
34
import useLocalize from '@hooks/useLocalize';
45
import useOnyx from '@hooks/useOnyx';
56
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
@@ -9,10 +10,10 @@ import useConfirmApproval from './useConfirmApproval';
910

1011
type ApprovePrimaryActionProps = {
1112
reportID: string | undefined;
12-
startApprovedAnimation: () => void;
1313
};
1414

15-
function ApprovePrimaryAction({reportID, startApprovedAnimation}: ApprovePrimaryActionProps) {
15+
function ApprovePrimaryAction({reportID}: ApprovePrimaryActionProps) {
16+
const {startApprovedAnimation} = usePaymentAnimationsContext();
1617
const {translate} = useLocalize();
1718

1819
const [moneyRequestReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);

src/components/MoneyReportHeaderPrimaryAction/PayPrimaryAction.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {hasSeenTourSelector} from '@selectors/Onboarding';
22
import React from 'react';
33
import {useDelegateNoAccessActions, useDelegateNoAccessState} from '@components/DelegateNoAccessModalProvider';
44
import {useMoneyReportHeaderModals} from '@components/MoneyReportHeaderModalsContext';
5+
import {usePaymentAnimationsContext} from '@components/PaymentAnimationsContext';
56
import {useSearchStateContext} from '@components/Search/SearchContext';
67
import AnimatedSettlementButton from '@components/SettlementButton/AnimatedSettlementButton';
78
import type {PaymentActionParams} from '@components/SettlementButton/types';
@@ -29,14 +30,10 @@ import useTransactionThreadData from './useTransactionThreadData';
2930
type PayPrimaryActionProps = {
3031
reportID: string | undefined;
3132
chatReportID: string | undefined;
32-
isPaidAnimationRunning: boolean;
33-
isApprovedAnimationRunning: boolean;
34-
stopAnimation: () => void;
35-
startAnimation: () => void;
36-
startApprovedAnimation: () => void;
3733
};
3834

39-
function PayPrimaryAction({reportID, chatReportID, isPaidAnimationRunning, isApprovedAnimationRunning, stopAnimation, startAnimation, startApprovedAnimation}: PayPrimaryActionProps) {
35+
function PayPrimaryAction({reportID, chatReportID}: PayPrimaryActionProps) {
36+
const {isPaidAnimationRunning, isApprovedAnimationRunning, stopAnimation, startAnimation, startApprovedAnimation} = usePaymentAnimationsContext();
4037
const {isOffline} = useNetwork();
4138
const {accountID, email} = useCurrentUserPersonalDetails();
4239
const {isDelegateAccessRestricted} = useDelegateNoAccessState();

src/components/MoneyReportHeaderPrimaryAction/SubmitPrimaryAction.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {delegateEmailSelector} from '@selectors/Account';
22
import React from 'react';
33
import AnimatedSubmitButton from '@components/AnimatedSubmitButton';
4+
import {usePaymentAnimationsContext} from '@components/PaymentAnimationsContext';
45
import {useSearchStateContext} from '@components/Search/SearchContext';
56
import useConfirmPendingRTERAndProceed from '@hooks/useConfirmPendingRTERAndProceed';
67
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
@@ -24,12 +25,10 @@ import ONYXKEYS from '@src/ONYXKEYS';
2425

2526
type SubmitPrimaryActionProps = {
2627
reportID: string | undefined;
27-
isSubmittingAnimationRunning: boolean;
28-
stopAnimation: () => void;
29-
startSubmittingAnimation: () => void;
3028
};
3129

32-
function SubmitPrimaryAction({reportID, isSubmittingAnimationRunning, stopAnimation, startSubmittingAnimation}: SubmitPrimaryActionProps) {
30+
function SubmitPrimaryAction({reportID}: SubmitPrimaryActionProps) {
31+
const {isSubmittingAnimationRunning, stopAnimation, startSubmittingAnimation} = usePaymentAnimationsContext();
3332
const {translate} = useLocalize();
3433
const {isOffline} = useNetwork();
3534
const {accountID, email} = useCurrentUserPersonalDetails();

src/components/MoneyReportHeaderPrimaryAction/index.tsx

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,53 +10,24 @@ import ReviewDuplicatesPrimaryAction from './ReviewDuplicatesPrimaryAction';
1010
import SubmitPrimaryAction from './SubmitPrimaryAction';
1111
import type {MoneyReportHeaderPrimaryActionProps} from './types';
1212

13-
function MoneyReportHeaderPrimaryAction({
14-
reportID,
15-
chatReportID,
16-
primaryAction,
17-
isPaidAnimationRunning,
18-
isApprovedAnimationRunning,
19-
isSubmittingAnimationRunning,
20-
stopAnimation,
21-
startAnimation,
22-
startApprovedAnimation,
23-
startSubmittingAnimation,
24-
onExportModalOpen,
25-
}: MoneyReportHeaderPrimaryActionProps) {
13+
function MoneyReportHeaderPrimaryAction({reportID, chatReportID, primaryAction, onExportModalOpen}: MoneyReportHeaderPrimaryActionProps) {
2614
if (!primaryAction) {
2715
return null;
2816
}
2917

3018
if (primaryAction === CONST.REPORT.PRIMARY_ACTIONS.SUBMIT) {
31-
return (
32-
<SubmitPrimaryAction
33-
reportID={reportID}
34-
isSubmittingAnimationRunning={isSubmittingAnimationRunning}
35-
stopAnimation={stopAnimation}
36-
startSubmittingAnimation={startSubmittingAnimation}
37-
/>
38-
);
19+
return <SubmitPrimaryAction reportID={reportID} />;
3920
}
4021

4122
if (primaryAction === CONST.REPORT.PRIMARY_ACTIONS.APPROVE) {
42-
return (
43-
<ApprovePrimaryAction
44-
reportID={reportID}
45-
startApprovedAnimation={startApprovedAnimation}
46-
/>
47-
);
23+
return <ApprovePrimaryAction reportID={reportID} />;
4824
}
4925

5026
if (primaryAction === CONST.REPORT.PRIMARY_ACTIONS.PAY) {
5127
return (
5228
<PayPrimaryAction
5329
reportID={reportID}
5430
chatReportID={chatReportID}
55-
isPaidAnimationRunning={isPaidAnimationRunning}
56-
isApprovedAnimationRunning={isApprovedAnimationRunning}
57-
stopAnimation={stopAnimation}
58-
startAnimation={startAnimation}
59-
startApprovedAnimation={startApprovedAnimation}
6031
/>
6132
);
6233
}

src/components/MoneyReportHeaderPrimaryAction/types.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,6 @@ type MoneyReportHeaderPrimaryActionProps = {
55
reportID: string | undefined;
66
chatReportID: string | undefined;
77
primaryAction: ValueOf<typeof CONST.REPORT.PRIMARY_ACTIONS> | ValueOf<typeof CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS> | '';
8-
isPaidAnimationRunning: boolean;
9-
isApprovedAnimationRunning: boolean;
10-
isSubmittingAnimationRunning: boolean;
11-
stopAnimation: () => void;
12-
startAnimation: () => void;
13-
startApprovedAnimation: () => void;
14-
startSubmittingAnimation: () => void;
158
onExportModalOpen: () => void;
169
};
1710

0 commit comments

Comments
 (0)