@@ -577,8 +577,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
577577
578578 const payableSelectedReports = useMemo ( ( ) => selectedReports . filter ( ( report ) => report . canPay ) , [ selectedReports ] ) ;
579579 const payableSelectedReportIDs = useMemo ( ( ) => payableSelectedReports . map ( ( report ) => report . reportID ) . filter ( ( reportID ) => reportID !== undefined ) , [ payableSelectedReports ] ) ;
580- // Fall back to the raw selection so transaction-only selections (which have no selected reports) and selections
581- // with nothing payable keep their previous derivations. The Pay group is hidden in the latter case anyway.
582580 const payScopedReports = useMemo ( ( ) => ( payableSelectedReports . length > 0 ? payableSelectedReports : selectedReports ) , [ payableSelectedReports , selectedReports ] ) ;
583581 const payScopedReportIDs = useMemo ( ( ) => payScopedReports . map ( ( report ) => report . reportID ) . filter ( ( reportID ) => reportID !== undefined ) , [ payScopedReports ] ) ;
584582
@@ -714,9 +712,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
714712 isCurrencySupportedWallet : isCurrencySupportedBulkWallet ,
715713 currency : selectedBulkCurrency ,
716714 formattedAmount : totalFormattedAmount ,
717- // When "Select all" spans pages, the selection can cover many workspaces/currencies whose per-report payment
718- // methods aren't all loaded, and QueueBulkPayReports only carries the query (no payment method). So offer only
719- // the manual "Pay elsewhere" option in that mode, which routes to QueueBulkPayReports in onBulkPaySelected.
720715 onlyShowPayElsewhere : onlyShowPayElsewhere || areAllMatchingItemsSelected ,
721716 } ) ;
722717
@@ -1347,8 +1342,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
13471342 return ;
13481343 }
13491344
1350- // "Select all" can cover more reports than are loaded on the current page(s), so the client can't enumerate them.
1351- // Hand the search query to the backend, which pages through every matching report and queues a payment for each.
13521345 if ( areAllMatchingItemsSelected ) {
13531346 const serializedQuery = queryJSON ? serializeQueryJSONForBackend ( queryJSON ) : JSON . stringify ( queryJSON ) ;
13541347 queueBulkPayReports ( serializedQuery ) ;
@@ -1809,11 +1802,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
18091802
18101803 const options : Array < DropdownOption < SearchHeaderOptionValue > > = [ ] ;
18111804 const isAnyTransactionOnHold = Object . values ( selectedTransactions ) . some ( ( transaction ) => transaction . isHeld ) ;
1812- // A hold only blocks paying the report that holds it. Bulk pay acts on the payable subset of the selection
1813- // (see payableSelectedReports), and canPay is already false for any report containing a held expense, so a
1814- // hold inside a report the viewer is not paying must not drop Pay for the ones they are. Whole-page
1815- // selections routinely mix the two, which is why the unscoped check left Export as the only bulk action.
1816- // Transaction-level selections have no payable subset to fall back to, so they keep the unscoped check.
18171805 const isAnyPayableTransactionOnHold =
18181806 payableSelectedReports . length > 0
18191807 ? Object . values ( selectedTransactions ) . some ( ( transaction ) => transaction . isHeld && ! ! transaction . reportID && payableSelectedReportIDs . includes ( transaction . reportID ) )
@@ -2181,17 +2169,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
21812169 return isExportTheOnlyAction && subMenuItems . length > 0 ? subMenuItems : builtOptions ;
21822170 } ;
21832171
2184- // Pay is offered for both "Select all" (all matching) and normal selections, so build it once here and reuse it in both branches below.
21852172 const { shouldEnableBulkPayOption} = getPayOption ( selectedReports , selectedTransactions , lastPaymentMethods , selectedReportIDs , personalPolicyID ) ;
2186- // Keep Pay visible while offline: selecting it is handled by onBulkPaySelected, which shows the offline modal
2187- // rather than attempting a payment. Gating on !isOffline here would hide Pay entirely offline, which is wrong.
2188- //
2189- // Under "Select all" the selection covers every report matching the query, but only the first page is loaded,
2190- // and QueueBulkPayReports re-resolves eligibility server-side from that query. So the two page-derived gates
2191- // must not apply: the hold check lets one held expense on the loaded page drop Pay for the whole query, and
2192- // getPayOption additionally requires every payable report to agree on a report type. Both make the menu depend
2193- // on what happens to be loaded rather than on what is actually payable. Keep only the "some report is payable"
2194- // signal, which is the one thing the loaded page can honestly tell us.
21952173 const hasLoadedPayableReport = payableSelectedReports . length > 0 || selectedReports . length === 0 ;
21962174 const shouldShowPayOption = areAllMatchingItemsSelected
21972175 ? hasLoadedPayableReport && ! ! bulkPayButtonOptions ?. length
@@ -2207,8 +2185,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
22072185 onSelected : ( ) => onBulkPaySelected ( undefined ) ,
22082186 } ;
22092187
2210- // With "Select all" the selection can span more reports than are loaded, so per-report actions other than Pay
2211- // (which the backend resolves from the query) can't be built. Offer the manual bulk Pay alongside Export only.
22122188 if ( areAllMatchingItemsSelected ) {
22132189 return openExportOptionsDirectlyIfSoleAction ( shouldShowPayOption ? [ payButtonOption , exportButtonOption ] : [ exportButtonOption ] ) ;
22142190 }
0 commit comments