Skip to content

Commit cc634d6

Browse files
authored
Merge pull request Expensify#90905 from linhvovan29546/performance/90167
Performance useHasEmptyReportsForPolicy
2 parents 42e9c77 + a5ddcaa commit cc634d6

15 files changed

Lines changed: 536 additions & 112 deletions

src/components/Navigation/QuickCreationActionsBar/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
77
import Button from '@components/Button';
88
import useCreateEmptyReportConfirmation from '@hooks/useCreateEmptyReportConfirmation';
99
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
10-
import useHasEmptyReportsForPolicy from '@hooks/useHasEmptyReportsForPolicy';
1110
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
1211
import useLocalize from '@hooks/useLocalize';
1312
import useOnyx from '@hooks/useOnyx';
1413
import usePermissions from '@hooks/usePermissions';
1514
import usePolicyForMovingExpenses from '@hooks/usePolicyForMovingExpenses';
15+
import useShouldShowEmptyReportConfirmation from '@hooks/useShouldShowEmptyReportConfirmation';
1616
import useThemeStyles from '@hooks/useThemeStyles';
1717
import {startDistanceRequest, startMoneyRequest} from '@libs/actions/IOU/MoneyRequest';
1818
import {createNewReport} from '@libs/actions/Report';
@@ -66,9 +66,7 @@ function QuickCreationActionsBar() {
6666
);
6767
const defaultChatEnabledPolicyID = defaultChatEnabledPolicy?.id;
6868

69-
const hasEmptyReport = useHasEmptyReportsForPolicy(defaultChatEnabledPolicyID);
70-
const [hasDismissedEmptyReportsConfirmation] = useOnyx(ONYXKEYS.NVP_EMPTY_REPORTS_CONFIRMATION_DISMISSED);
71-
const shouldShowEmptyReportConfirmationForDefaultChatEnabledPolicy = hasEmptyReport && hasDismissedEmptyReportsConfirmation !== true;
69+
const shouldShowEmptyReportConfirmationForDefaultChatEnabledPolicy = useShouldShowEmptyReportConfirmation(defaultChatEnabledPolicyID);
7270

7371
const travelEnabledPolicy = useMemo(() => Object.values(allPolicies ?? {}).find((policy) => !!policy?.isTravelEnabled), [allPolicies]);
7472

src/components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import type {PopoverMenuItem} from '@components/PopoverMenu';
88
import PopoverMenu from '@components/PopoverMenu';
99
import useCreateEmptyReportConfirmation from '@hooks/useCreateEmptyReportConfirmation';
1010
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
11-
import useHasEmptyReportsForPolicy from '@hooks/useHasEmptyReportsForPolicy';
1211
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
1312
import useLocalize from '@hooks/useLocalize';
1413
import useOnyx from '@hooks/useOnyx';
1514
import usePermissions from '@hooks/usePermissions';
1615
import usePolicyForMovingExpenses from '@hooks/usePolicyForMovingExpenses';
1716
import usePopoverPosition from '@hooks/usePopoverPosition';
17+
import useShouldShowEmptyReportConfirmation from '@hooks/useShouldShowEmptyReportConfirmation';
1818
import useThemeStyles from '@hooks/useThemeStyles';
1919
import {startDistanceRequest, startMoneyRequest} from '@libs/actions/IOU/MoneyRequest';
2020
import {createNewReport} from '@libs/actions/Report';
@@ -65,9 +65,7 @@ function SearchActionsBarCreateButton() {
6565
);
6666
const defaultChatEnabledPolicyID = defaultChatEnabledPolicy?.id;
6767

68-
const hasEmptyReport = useHasEmptyReportsForPolicy(defaultChatEnabledPolicyID);
69-
const [hasDismissedEmptyReportsConfirmation] = useOnyx(ONYXKEYS.NVP_EMPTY_REPORTS_CONFIRMATION_DISMISSED);
70-
const shouldShowEmptyReportConfirmationForDefaultChatEnabledPolicy = hasEmptyReport && hasDismissedEmptyReportsConfirmation !== true;
68+
const shouldShowEmptyReportConfirmationForDefaultChatEnabledPolicy = useShouldShowEmptyReportConfirmation(defaultChatEnabledPolicyID);
7169

7270
const handleCreateWorkspaceReport = useCallback(
7371
(shouldDismissEmptyReportsConfirmation?: boolean) => {

src/hooks/useConditionalCreateEmptyReportConfirmation.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import {useCallback, useMemo} from 'react';
2-
import ONYXKEYS from '@src/ONYXKEYS';
1+
import {useCallback} from 'react';
32
import useCreateEmptyReportConfirmation from './useCreateEmptyReportConfirmation';
4-
import useHasEmptyReportsForPolicy from './useHasEmptyReportsForPolicy';
5-
import useOnyx from './useOnyx';
3+
import useShouldShowEmptyReportConfirmation from './useShouldShowEmptyReportConfirmation';
64

75
type UseConditionalCreateEmptyReportConfirmationParams = {
86
/** The policy ID for which the report is being created */
@@ -35,9 +33,7 @@ export default function useConditionalCreateEmptyReportConfirmation({
3533
onCancel,
3634
shouldBypassConfirmation = false,
3735
}: UseConditionalCreateEmptyReportConfirmationParams): UseConditionalCreateEmptyReportConfirmationResult {
38-
const hasEmptyReport = useHasEmptyReportsForPolicy(policyID);
39-
const [hasDismissedEmptyReportsConfirmation] = useOnyx(ONYXKEYS.NVP_EMPTY_REPORTS_CONFIRMATION_DISMISSED);
40-
const shouldSkipConfirmation = useMemo(() => shouldBypassConfirmation || hasDismissedEmptyReportsConfirmation === true, [hasDismissedEmptyReportsConfirmation, shouldBypassConfirmation]);
36+
const shouldShowEmptyReportConfirmation = useShouldShowEmptyReportConfirmation(policyID, shouldBypassConfirmation);
4137

4238
const handleReportCreationConfirmed = useCallback(
4339
(shouldDismissEmptyReportsConfirmation?: boolean) => {
@@ -54,16 +50,16 @@ export default function useConditionalCreateEmptyReportConfirmation({
5450
});
5551

5652
const handleCreateReport = useCallback(() => {
57-
if (hasEmptyReport && !shouldSkipConfirmation) {
53+
if (shouldShowEmptyReportConfirmation) {
5854
openCreateReportConfirmation();
5955
return;
6056
}
6157

6258
onCreateReport(false);
63-
}, [hasEmptyReport, onCreateReport, openCreateReportConfirmation, shouldSkipConfirmation]);
59+
}, [shouldShowEmptyReportConfirmation, onCreateReport, openCreateReportConfirmation]);
6460

6561
return {
6662
handleCreateReport,
67-
hasEmptyReport,
63+
hasEmptyReport: shouldShowEmptyReportConfirmation,
6864
};
6965
}

src/hooks/useCreateReport.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import ROUTES from '@src/ROUTES';
1111
import type * as OnyxTypes from '@src/types/onyx';
1212
import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
1313
import useCreateEmptyReportConfirmation from './useCreateEmptyReportConfirmation';
14-
import useHasEmptyReportsForPolicy from './useHasEmptyReportsForPolicy';
1514
import useOnyx from './useOnyx';
15+
import useShouldShowEmptyReportConfirmation from './useShouldShowEmptyReportConfirmation';
1616

1717
type UseCreateReportParams = {
1818
/** Callback that creates the report and navigates after creation */
@@ -47,7 +47,6 @@ export default function useCreateReport({onCreateReport, groupPoliciesWithChatEn
4747
const [ownerBillingGracePeriodEnd] = useOnyx(ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END);
4848
const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END);
4949
const [amountOwed] = useOnyx(ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED);
50-
const [hasDismissedEmptyReportsConfirmation] = useOnyx(ONYXKEYS.NVP_EMPTY_REPORTS_CONFIRMATION_DISMISSED);
5150
const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.accountID});
5251

5352
// Gate visibility and routing on policy hydration. Without this, during Onyx cold-start
@@ -60,8 +59,7 @@ export default function useCreateReport({onCreateReport, groupPoliciesWithChatEn
6059
const defaultChatEnabledPolicy = getDefaultChatEnabledPolicy(groupPoliciesWithChatEnabled as Array<OnyxEntry<OnyxTypes.Policy>>, activePolicy);
6160
const defaultChatEnabledPolicyID = defaultChatEnabledPolicy?.id;
6261

63-
const hasEmptyReport = useHasEmptyReportsForPolicy(defaultChatEnabledPolicyID);
64-
const shouldShowEmptyReportConfirmation = hasEmptyReport && hasDismissedEmptyReportsConfirmation !== true;
62+
const shouldShowEmptyReportConfirmation = useShouldShowEmptyReportConfirmation(defaultChatEnabledPolicyID);
6563

6664
const {openCreateReportConfirmation} = useCreateEmptyReportConfirmation({
6765
policyID: defaultChatEnabledPolicyID,

src/hooks/useHasEmptyReportsForPolicy.ts

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {accountIDSelector} from '@selectors/Session';
2+
import {useCallback} from 'react';
3+
import {hasEmptyReportsForPolicy} from '@libs/ReportUtils';
4+
import ONYXKEYS from '@src/ONYXKEYS';
5+
import useOnyx from './useOnyx';
6+
7+
function useShouldShowEmptyReportConfirmation(policyID: string | undefined, skip?: boolean): boolean {
8+
const [hasDismissedConfirmation] = useOnyx(ONYXKEYS.NVP_EMPTY_REPORTS_CONFIRMATION_DISMISSED);
9+
const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: accountIDSelector});
10+
const hasEmptyReportSelector = useCallback(
11+
(reports: Parameters<typeof hasEmptyReportsForPolicy>[0]) => {
12+
if (skip || hasDismissedConfirmation) {
13+
return false;
14+
}
15+
return hasEmptyReportsForPolicy(reports, policyID, accountID);
16+
},
17+
[policyID, accountID, hasDismissedConfirmation, skip],
18+
);
19+
const [hasEmptyReport = false] = useOnyx(
20+
ONYXKEYS.COLLECTION.REPORT,
21+
{
22+
selector: hasEmptyReportSelector,
23+
},
24+
[policyID, accountID, hasDismissedConfirmation, skip],
25+
);
26+
27+
return hasEmptyReport;
28+
}
29+
30+
export default useShouldShowEmptyReportConfirmation;

src/pages/NewReportWorkspaceSelectionPage.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag
8383
const [todos] = useOnyx(ONYXKEYS.DERIVED.TODOS);
8484
const transactionsByReportID = todos?.transactionsByReportID;
8585

86-
const policiesWithEmptyReportsForAccountSelector = useMemo(() => policyIDsWithEmptyReportsSelector(accountID, transactionsByReportID ?? {}), [accountID, transactionsByReportID]);
86+
const policiesWithEmptyReportsForAccountSelector = useMemo(
87+
() => policyIDsWithEmptyReportsSelector(accountID, transactionsByReportID ?? {}, !!hasDismissedEmptyReportsConfirmation),
88+
[accountID, transactionsByReportID, hasDismissedEmptyReportsConfirmation],
89+
);
8790
const [policiesWithEmptyReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {selector: policiesWithEmptyReportsForAccountSelector});
8891

8992
const navigateToNewReport = (optimisticReportID: string) => {
@@ -179,7 +182,7 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag
179182
return;
180183
}
181184

182-
const shouldShowEmptyReportConfirmation = !!policiesWithEmptyReports?.[policy.policyID] && hasDismissedEmptyReportsConfirmation !== true;
185+
const shouldShowEmptyReportConfirmation = !!policiesWithEmptyReports?.[policy.policyID];
183186
if (!shouldShowEmptyReportConfirmation) {
184187
createReport(policy.policyID, false);
185188
return;

src/pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
1313
import Tooltip from '@components/Tooltip/PopoverAnchorTooltip';
1414
import useCreateEmptyReportConfirmation from '@hooks/useCreateEmptyReportConfirmation';
1515
import useEnvironment from '@hooks/useEnvironment';
16-
import useHasEmptyReportsForPolicy from '@hooks/useHasEmptyReportsForPolicy';
1716
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
1817
import useLocalize from '@hooks/useLocalize';
1918
import useOnyx from '@hooks/useOnyx';
@@ -23,6 +22,7 @@ import usePreferredPolicy from '@hooks/usePreferredPolicy';
2322
import usePrevious from '@hooks/usePrevious';
2423
import useReportIsArchived from '@hooks/useReportIsArchived';
2524
import useResponsiveLayout from '@hooks/useResponsiveLayout';
25+
import useShouldShowEmptyReportConfirmation from '@hooks/useShouldShowEmptyReportConfirmation';
2626
import useTheme from '@hooks/useTheme';
2727
import useThemeStyles from '@hooks/useThemeStyles';
2828
import {isSafari} from '@libs/Browser';
@@ -177,11 +177,9 @@ function AttachmentPickerWithMenuItems({
177177
const {isBetaEnabled} = usePermissions();
178178
const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT);
179179
const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: accountIDSelector});
180-
const [hasDismissedEmptyReportsConfirmation] = useOnyx(ONYXKEYS.NVP_EMPTY_REPORTS_CONFIRMATION_DISMISSED);
181180
const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END);
182181
const hasViolations = hasViolationsReportUtils(undefined, transactionViolations, accountID ?? CONST.DEFAULT_NUMBER_ID, '');
183-
const hasEmptyReport = useHasEmptyReportsForPolicy(report?.policyID);
184-
const shouldShowEmptyReportConfirmation = hasEmptyReport && hasDismissedEmptyReportsConfirmation !== true;
182+
const shouldShowEmptyReportConfirmation = useShouldShowEmptyReportConfirmation(report?.policyID);
185183

186184
const selectOption = useCallback(
187185
(onSelected: () => void, shouldRestrictAction: boolean) => {

src/selectors/Report.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@ function getReportOwnerAccountID(report: OnyxEntry<Report>) {
3030
return report?.ownerAccountID;
3131
}
3232

33-
const policyIDsWithEmptyReportsSelector = (accountID: number | undefined, transactionsByReportID: Record<string, Transaction[]>) => (reports: OnyxCollection<Report>) => {
34-
if (!accountID) {
35-
return {};
36-
}
37-
return getPolicyIDsWithEmptyReportsForAccount(reports, accountID, transactionsByReportID);
38-
};
33+
const policyIDsWithEmptyReportsSelector =
34+
(accountID: number | undefined, transactionsByReportID: Record<string, Transaction[]>, hasDismissedEmptyReportsConfirmation: boolean) => (reports: OnyxCollection<Report>) => {
35+
if (hasDismissedEmptyReportsConfirmation || !accountID) {
36+
return {};
37+
}
38+
return getPolicyIDsWithEmptyReportsForAccount(reports, accountID, transactionsByReportID);
39+
};
3940

4041
function openExpenseReportIDsSelector(reports: OnyxCollection<Report>): OpenExpenseReportIDMap {
4142
if (!reports) {

0 commit comments

Comments
 (0)