Skip to content

Commit 3c39afc

Browse files
authored
Merge pull request #95130 from Expensify/claude-fixSearchBulkDeleteRegression
[CP Staging] Fix bulk delete in Search dropping deletions during confirm modal dismiss
2 parents 35fece7 + 0164dce commit 3c39afc

1 file changed

Lines changed: 21 additions & 14 deletions

File tree

src/hooks/useSearchBulkActions.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* eslint-disable react-hooks/refs -- Refs in this hook are used inside callbacks that capture stable references; the lint rule flags false positives for these patterns */
22
import {isTrackIntentUserSelector} from '@selectors/Onboarding';
33
import {useCallback, useEffect, useMemo, useRef, useState} from 'react';
4+
// eslint-disable-next-line no-restricted-imports -- InteractionManager is only exposed on the react-native root module; there is no internal re-export to import from
5+
import {InteractionManager} from 'react-native';
46
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
57
import type {ValueOf} from 'type-fest';
68
import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types';
@@ -911,19 +913,24 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
911913
return;
912914
}
913915

914-
TransitionTracker.runAfterTransitions({
915-
callback: async () => {
916-
const result = await showConfirmModal({
917-
title: deleteModalTitle,
918-
prompt: deleteModalPrompt,
919-
confirmText: translate('common.delete'),
920-
cancelText: translate('common.cancel'),
921-
danger: true,
922-
});
923-
if (result.action !== ModalActions.CONFIRM) {
924-
return;
925-
}
926-
const validTransactions = Object.fromEntries(Object.entries(allTransactions ?? {}).filter((entry): entry is [string, Transaction] => entry[1] !== undefined));
916+
// InteractionManager is deprecated but still required here to defer showing the confirm modal until pending interactions settle, matching the production behavior this PR restores (see https://github.com/Expensify/App/issues/95114).
917+
// eslint-disable-next-line @typescript-eslint/no-deprecated
918+
InteractionManager.runAfterInteractions(async () => {
919+
const result = await showConfirmModal({
920+
title: deleteModalTitle,
921+
prompt: deleteModalPrompt,
922+
confirmText: translate('common.delete'),
923+
cancelText: translate('common.cancel'),
924+
danger: true,
925+
});
926+
if (result.action !== ModalActions.CONFIRM) {
927+
return;
928+
}
929+
const validTransactions = Object.fromEntries(Object.entries(allTransactions ?? {}).filter((entry): entry is [string, Transaction] => entry[1] !== undefined));
930+
// Defer the actual deletion until after the confirm modal's dismiss interaction completes.
931+
// Dispatching it synchronously as the modal closes caused the delete to be dropped (see https://github.com/Expensify/App/issues/95114).
932+
// eslint-disable-next-line @typescript-eslint/no-deprecated
933+
InteractionManager.runAfterInteractions(() => {
927934
if (isExpenseReportType) {
928935
for (const reportID of selectedReportIDs) {
929936
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
@@ -992,7 +999,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
992999
}
9931000
}
9941001
clearSelectedTransactions();
995-
},
1002+
});
9961003
});
9971004
}, [
9981005
hash,

0 commit comments

Comments
 (0)