@@ -48,7 +48,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
4848import { turnOnMobileSelectionMode } from '@libs/actions/MobileSelectionMode' ;
4949import DateUtils from '@libs/DateUtils' ;
5050import navigationRef from '@libs/Navigation/navigationRef' ;
51- import { getTableMinWidth } from '@libs/SearchUIUtils' ;
51+ import { getTableMinWidth , isTransactionReportGroupListItemType } from '@libs/SearchUIUtils' ;
5252import variables from '@styles/variables' ;
5353import type { TransactionPreviewData } from '@userActions/Search' ;
5454import CONST from '@src/CONST' ;
@@ -239,16 +239,51 @@ function SearchList({
239239 }
240240 return data ;
241241 } , [ data , groupBy , type ] ) ;
242- const flattenedItemsWithoutPendingDelete = useMemo ( ( ) => flattenedItems . filter ( ( t ) => t ?. pendingAction !== CONST . RED_BRICK_ROAD_PENDING_ACTION . DELETE ) , [ flattenedItems ] ) ;
242+ const emptyReports = useMemo ( ( ) => {
243+ if ( type === CONST . SEARCH . DATA_TYPES . EXPENSE_REPORT && isTransactionGroupListItemArray ( data ) ) {
244+ return data . filter ( ( item ) => item . transactions . length === 0 ) ;
245+ }
246+ return [ ] ;
247+ } , [ data , type ] ) ;
243248
244249 const selectedItemsLength = useMemo ( ( ) => {
245- return flattenedItemsWithoutPendingDelete . reduce ( ( acc , item ) => {
246- if ( item . keyForList && selectedTransactions [ item . keyForList ] ?. isSelected ) {
247- return acc + 1 ;
248- }
249- return acc ;
250+ const selectedTransactionsCount = flattenedItems . reduce ( ( acc , item ) => {
251+ const isTransactionSelected = ! ! ( item ?. keyForList && selectedTransactions [ item . keyForList ] ?. isSelected ) ;
252+ return acc + ( isTransactionSelected ? 1 : 0 ) ;
250253 } , 0 ) ;
251- } , [ flattenedItemsWithoutPendingDelete , selectedTransactions ] ) ;
254+
255+ if ( type === CONST . SEARCH . DATA_TYPES . EXPENSE_REPORT && isTransactionGroupListItemArray ( data ) ) {
256+ const selectedEmptyReports = emptyReports . reduce ( ( acc , item ) => {
257+ const isEmptyReportSelected = ! ! ( item . keyForList && selectedTransactions [ item . keyForList ] ?. isSelected ) ;
258+ return acc + ( isEmptyReportSelected ? 1 : 0 ) ;
259+ } , 0 ) ;
260+
261+ return selectedEmptyReports + selectedTransactionsCount ;
262+ }
263+
264+ return selectedTransactionsCount ;
265+ } , [ flattenedItems , type , data , emptyReports , selectedTransactions ] ) ;
266+
267+ const totalItems = useMemo ( ( ) => {
268+ if ( type === CONST . SEARCH . DATA_TYPES . EXPENSE_REPORT && isTransactionGroupListItemArray ( data ) ) {
269+ const selectableEmptyReports = emptyReports . filter ( ( item ) => item . pendingAction !== CONST . RED_BRICK_ROAD_PENDING_ACTION . DELETE ) ;
270+ const selectableTransactions = flattenedItems . filter ( ( item ) => {
271+ if ( 'pendingAction' in item ) {
272+ return item . pendingAction !== CONST . RED_BRICK_ROAD_PENDING_ACTION . DELETE ;
273+ }
274+ return true ;
275+ } ) ;
276+ return selectableEmptyReports . length + selectableTransactions . length ;
277+ }
278+
279+ const selectableTransactions = flattenedItems . filter ( ( item ) => {
280+ if ( 'pendingAction' in item ) {
281+ return item . pendingAction !== CONST . RED_BRICK_ROAD_PENDING_ACTION . DELETE ;
282+ }
283+ return true ;
284+ } ) ;
285+ return selectableTransactions . length ;
286+ } , [ data , type , flattenedItems , emptyReports ] ) ;
252287
253288 const itemsWithSelection = useMemo ( ( ) => {
254289 return data . map ( ( item ) => {
@@ -259,10 +294,16 @@ function SearchList({
259294 if ( ! canSelectMultiple ) {
260295 itemWithSelection = { ...item , isSelected : false } ;
261296 } else {
262- const hasAnySelected = item . transactions . some ( ( t ) => t . keyForList && selectedTransactions [ t . keyForList ] ?. isSelected ) ;
297+ const isEmptyReportSelected =
298+ item . transactions . length === 0 && isTransactionReportGroupListItemType ( item ) && ! ! ( item . keyForList && selectedTransactions [ item . keyForList ] ?. isSelected ) ;
299+
300+ const hasAnySelected = item . transactions . some ( ( t ) => t . keyForList && selectedTransactions [ t . keyForList ] ?. isSelected ) || isEmptyReportSelected ;
263301
264302 if ( ! hasAnySelected ) {
265303 itemWithSelection = { ...item , isSelected : false } ;
304+ } else if ( isEmptyReportSelected ) {
305+ isSelected = true ;
306+ itemWithSelection = { ...item , isSelected} ;
266307 } else {
267308 let allNonDeletedSelected = true ;
268309 let hasNonDeletedTransactions = false ;
@@ -351,13 +392,10 @@ function SearchList({
351392 }
352393
353394 // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
354- if ( shouldPreventLongPressRow || ! isSmallScreenWidth || item ?. isDisabled || item ?. isDisabledCheckbox ) {
355- return ;
356- }
357- // disable long press for empty expense reports
358- if ( 'transactions' in item && item . transactions . length === 0 && ! groupBy ) {
395+ if ( shouldPreventLongPressRow || ! isSmallScreenWidth || item ?. isDisabled || item ?. isDisabledCheckbox || item . pendingAction === CONST . RED_BRICK_ROAD_PENDING_ACTION . DELETE ) {
359396 return ;
360397 }
398+
361399 if ( isMobileSelectionModeEnabled ) {
362400 onCheckboxPress ( item , itemTransactions ) ;
363401 return ;
@@ -366,7 +404,7 @@ function SearchList({
366404 setLongPressedItemTransactions ( itemTransactions ) ;
367405 setIsModalVisible ( true ) ;
368406 } ,
369- [ groupBy , route . key , shouldPreventLongPressRow , isSmallScreenWidth , isMobileSelectionModeEnabled , onCheckboxPress ] ,
407+ [ route . key , shouldPreventLongPressRow , isSmallScreenWidth , isMobileSelectionModeEnabled , onCheckboxPress ] ,
370408 ) ;
371409
372410 const turnOnSelectionMode = useCallback ( ( ) => {
@@ -493,7 +531,7 @@ function SearchList({
493531
494532 const tableHeaderVisible = canSelectMultiple || ! ! SearchTableHeader ;
495533 const selectAllButtonVisible = canSelectMultiple && ! SearchTableHeader ;
496- const isSelectAllChecked = selectedItemsLength > 0 && selectedItemsLength === flattenedItemsWithoutPendingDelete . length && hasLoadedAllTransactions ;
534+ const isSelectAllChecked = selectedItemsLength > 0 && selectedItemsLength === totalItems && hasLoadedAllTransactions ;
497535
498536 const content = (
499537 < View style = { [ styles . flex1 , ! isKeyboardShown && safeAreaPaddingBottomStyle , containerStyle ] } >
@@ -503,11 +541,11 @@ function SearchList({
503541 < Checkbox
504542 accessibilityLabel = { translate ( 'workspace.people.selectAll' ) }
505543 isChecked = { isSelectAllChecked }
506- isIndeterminate = { selectedItemsLength > 0 && ( selectedItemsLength !== flattenedItemsWithoutPendingDelete . length || ! hasLoadedAllTransactions ) }
544+ isIndeterminate = { selectedItemsLength > 0 && ( selectedItemsLength !== totalItems || ! hasLoadedAllTransactions ) }
507545 onPress = { ( ) => {
508546 onAllCheckboxPress ( ) ;
509547 } }
510- disabled = { flattenedItems . length === 0 }
548+ disabled = { totalItems === 0 }
511549 />
512550 ) }
513551
@@ -520,6 +558,7 @@ function SearchList({
520558 accessibilityLabel = { translate ( 'workspace.people.selectAll' ) }
521559 role = "button"
522560 accessibilityState = { { checked : isSelectAllChecked } }
561+ sentryLabel = { CONST . SENTRY_LABEL . SEARCH . SELECT_ALL_BUTTON }
523562 dataSet = { { [ CONST . SELECTION_SCRAPER_HIDDEN_ELEMENT ] : true } }
524563 >
525564 < Text style = { [ styles . textMicroSupporting , styles . ph3 ] } > { translate ( 'workspace.people.selectAll' ) } </ Text >
0 commit comments