1
+ import { useFocusEffect } from '@react-navigation/native' ;
1
2
import React , { useCallback , useMemo , useState } from 'react' ;
2
3
import { InteractionManager , View } from 'react-native' ;
3
4
import { useOnyx } from 'react-native-onyx' ;
@@ -9,8 +10,6 @@ import DecisionModal from '@components/DecisionModal';
9
10
import * as Expensicons from '@components/Icon/Expensicons' ;
10
11
import { usePersonalDetails } from '@components/OnyxProvider' ;
11
12
import { useProductTrainingContext } from '@components/ProductTrainingContext' ;
12
- import { useSearchContext } from '@components/Search/SearchContext' ;
13
- import type { PaymentData , SearchQueryJSON } from '@components/Search/types' ;
14
13
import EducationalTooltip from '@components/Tooltip/EducationalTooltip' ;
15
14
import useActiveWorkspace from '@hooks/useActiveWorkspace' ;
16
15
import useLocalize from '@hooks/useLocalize' ;
@@ -29,20 +28,22 @@ import {
29
28
import { mergeCardListWithWorkspaceFeeds } from '@libs/CardUtils' ;
30
29
import Navigation from '@libs/Navigation/Navigation' ;
31
30
import { getAllTaxRates , hasVBBA } from '@libs/PolicyUtils' ;
32
- import { buildFilterFormValuesFromQuery } from '@libs/SearchQueryUtils' ;
31
+ import { buildFilterFormValuesFromQuery , isCannedSearchQuery } from '@libs/SearchQueryUtils' ;
33
32
import SearchSelectedNarrow from '@pages/Search/SearchSelectedNarrow' ;
34
33
import variables from '@styles/variables' ;
35
34
import CONST from '@src/CONST' ;
36
35
import ONYXKEYS from '@src/ONYXKEYS' ;
37
36
import ROUTES from '@src/ROUTES' ;
38
37
import type DeepValueOf from '@src/types/utils/DeepValueOf' ;
38
+ import { useSearchContext } from './SearchContext' ;
39
39
import SearchPageHeaderInput from './SearchPageHeaderInput' ;
40
+ import type { PaymentData , SearchQueryJSON } from './types' ;
40
41
41
- type SearchPageHeaderProps = { queryJSON : SearchQueryJSON ; searchRouterListVisible ?: boolean ; onSearchRouterFocus ?: ( ) => void } ;
42
+ type SearchPageHeaderProps = { queryJSON : SearchQueryJSON } ;
42
43
43
44
type SearchHeaderOptionValue = DeepValueOf < typeof CONST . SEARCH . BULK_ACTION_TYPES > | undefined ;
44
45
45
- function SearchPageHeader ( { queryJSON, searchRouterListVisible , onSearchRouterFocus } : SearchPageHeaderProps ) {
46
+ function SearchPageHeader ( { queryJSON} : SearchPageHeaderProps ) {
46
47
const { translate} = useLocalize ( ) ;
47
48
const theme = useTheme ( ) ;
48
49
const styles = useThemeStyles ( ) ;
@@ -67,12 +68,24 @@ function SearchPageHeader({queryJSON, searchRouterListVisible, onSearchRouterFoc
67
68
const [ isOfflineModalVisible , setIsOfflineModalVisible ] = useState ( false ) ;
68
69
const [ isDownloadErrorModalVisible , setIsDownloadErrorModalVisible ] = useState ( false ) ;
69
70
71
+ const [ isScreenFocused , setIsScreenFocused ] = useState ( false ) ;
72
+
70
73
const { renderProductTrainingTooltip, shouldShowProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext (
71
74
CONST . PRODUCT_TRAINING_TOOLTIP_NAMES . SEARCH_FILTER_BUTTON_TOOLTIP ,
75
+ isScreenFocused ,
72
76
) ;
73
77
74
78
const { status, hash} = queryJSON ;
75
79
80
+ useFocusEffect (
81
+ useCallback ( ( ) => {
82
+ setIsScreenFocused ( true ) ;
83
+ return ( ) => {
84
+ setIsScreenFocused ( false ) ;
85
+ } ;
86
+ } , [ ] ) ,
87
+ ) ;
88
+
76
89
const selectedTransactionsKeys = Object . keys ( selectedTransactions ?? { } ) ;
77
90
78
91
const handleDeleteExpenses = ( ) => {
@@ -302,106 +315,94 @@ function SearchPageHeader({queryJSON, searchRouterListVisible, onSearchRouterFoc
302
315
styles . textWrap ,
303
316
] ) ;
304
317
305
- const onFiltersButtonPress = useCallback ( ( ) => {
318
+ if ( shouldUseNarrowLayout ) {
319
+ if ( selectionMode ?. isEnabled ) {
320
+ return (
321
+ < View >
322
+ < SearchSelectedNarrow
323
+ options = { headerButtonsOptions }
324
+ itemsLength = { selectedTransactionsKeys . length }
325
+ />
326
+ < ConfirmModal
327
+ isVisible = { isDeleteExpensesConfirmModalVisible }
328
+ onConfirm = { handleDeleteExpenses }
329
+ onCancel = { ( ) => {
330
+ setIsDeleteExpensesConfirmModalVisible ( false ) ;
331
+ } }
332
+ title = { translate ( 'iou.deleteExpense' , { count : selectedTransactionsKeys . length } ) }
333
+ prompt = { translate ( 'iou.deleteConfirmation' , { count : selectedTransactionsKeys . length } ) }
334
+ confirmText = { translate ( 'common.delete' ) }
335
+ cancelText = { translate ( 'common.cancel' ) }
336
+ danger
337
+ />
338
+ < DecisionModal
339
+ title = { translate ( 'common.youAppearToBeOffline' ) }
340
+ prompt = { translate ( 'common.offlinePrompt' ) }
341
+ isSmallScreenWidth = { isSmallScreenWidth }
342
+ onSecondOptionSubmit = { ( ) => setIsOfflineModalVisible ( false ) }
343
+ secondOptionText = { translate ( 'common.buttonConfirm' ) }
344
+ isVisible = { isOfflineModalVisible }
345
+ onClose = { ( ) => setIsOfflineModalVisible ( false ) }
346
+ />
347
+ < DecisionModal
348
+ title = { translate ( 'common.downloadFailedTitle' ) }
349
+ prompt = { translate ( 'common.downloadFailedDescription' ) }
350
+ isSmallScreenWidth = { isSmallScreenWidth }
351
+ onSecondOptionSubmit = { ( ) => setIsDownloadErrorModalVisible ( false ) }
352
+ secondOptionText = { translate ( 'common.buttonConfirm' ) }
353
+ isVisible = { isDownloadErrorModalVisible }
354
+ onClose = { ( ) => setIsDownloadErrorModalVisible ( false ) }
355
+ />
356
+ </ View >
357
+ ) ;
358
+ }
359
+ return null ;
360
+ }
361
+
362
+ const onFiltersButtonPress = ( ) => {
306
363
hideProductTrainingTooltip ( ) ;
307
364
const filterFormValues = buildFilterFormValuesFromQuery ( queryJSON , policyCategories , policyTagsLists , currencyList , personalDetails , allCards , reports , taxRates ) ;
308
365
updateAdvancedFilters ( filterFormValues ) ;
309
366
310
367
Navigation . navigate ( ROUTES . SEARCH_ADVANCED_FILTERS ) ;
311
- } , [ allCards , currencyList , hideProductTrainingTooltip , personalDetails , policyCategories , policyTagsLists , queryJSON , reports , taxRates ] ) ;
312
-
313
- const InputRightComponent = useMemo ( ( ) => {
314
- return headerButtonsOptions . length > 0 ? (
315
- < ButtonWithDropdownMenu
316
- onPress = { ( ) => null }
317
- shouldAlwaysShowDropdownMenu
318
- buttonSize = { CONST . DROPDOWN_BUTTON_SIZE . MEDIUM }
319
- customText = { translate ( 'workspace.common.selected' , { count : selectedTransactionsKeys . length } ) }
320
- options = { headerButtonsOptions }
321
- isSplitButton = { false }
322
- shouldUseStyleUtilityForAnchorPosition
323
- />
324
- ) : (
325
- < EducationalTooltip
326
- shouldRender = { shouldShowProductTrainingTooltip }
327
- anchorAlignment = { {
328
- vertical : CONST . MODAL . ANCHOR_ORIGIN_VERTICAL . BOTTOM ,
329
- horizontal : CONST . MODAL . ANCHOR_ORIGIN_HORIZONTAL . RIGHT ,
330
- } }
331
- shiftHorizontal = { variables . searchFiltersTooltipShiftHorizontal }
332
- wrapperStyle = { styles . productTrainingTooltipWrapper }
333
- renderTooltipContent = { renderProductTrainingTooltip }
334
- onTooltipPress = { onFiltersButtonPress }
335
- >
336
- < Button
337
- innerStyles = { [ styles . searchRouterInputResults , styles . borderNone , styles . bgTransparent ] }
338
- icon = { Expensicons . Filters }
339
- onPress = { onFiltersButtonPress }
340
- />
341
- </ EducationalTooltip >
342
- ) ;
343
- } , [
344
- headerButtonsOptions ,
345
- onFiltersButtonPress ,
346
- renderProductTrainingTooltip ,
347
- selectedTransactionsKeys . length ,
348
- shouldShowProductTrainingTooltip ,
349
- styles . bgTransparent ,
350
- styles . borderNone ,
351
- styles . productTrainingTooltipWrapper ,
352
- styles . searchRouterInputResults ,
353
- translate ,
354
- ] ) ;
368
+ } ;
355
369
356
- if ( shouldUseNarrowLayout && selectionMode ?. isEnabled ) {
357
- return (
358
- < View >
359
- < SearchSelectedNarrow
360
- options = { headerButtonsOptions }
361
- itemsLength = { selectedTransactionsKeys . length }
362
- />
363
- < ConfirmModal
364
- isVisible = { isDeleteExpensesConfirmModalVisible }
365
- onConfirm = { handleDeleteExpenses }
366
- onCancel = { ( ) => {
367
- setIsDeleteExpensesConfirmModalVisible ( false ) ;
368
- } }
369
- title = { translate ( 'iou.deleteExpense' , { count : selectedTransactionsKeys . length } ) }
370
- prompt = { translate ( 'iou.deleteConfirmation' , { count : selectedTransactionsKeys . length } ) }
371
- confirmText = { translate ( 'common.delete' ) }
372
- cancelText = { translate ( 'common.cancel' ) }
373
- danger
374
- />
375
- < DecisionModal
376
- title = { translate ( 'common.youAppearToBeOffline' ) }
377
- prompt = { translate ( 'common.offlinePrompt' ) }
378
- isSmallScreenWidth = { isSmallScreenWidth }
379
- onSecondOptionSubmit = { ( ) => setIsOfflineModalVisible ( false ) }
380
- secondOptionText = { translate ( 'common.buttonConfirm' ) }
381
- isVisible = { isOfflineModalVisible }
382
- onClose = { ( ) => setIsOfflineModalVisible ( false ) }
383
- />
384
- < DecisionModal
385
- title = { translate ( 'common.downloadFailedTitle' ) }
386
- prompt = { translate ( 'common.downloadFailedDescription' ) }
387
- isSmallScreenWidth = { isSmallScreenWidth }
388
- onSecondOptionSubmit = { ( ) => setIsDownloadErrorModalVisible ( false ) }
389
- secondOptionText = { translate ( 'common.buttonConfirm' ) }
390
- isVisible = { isDownloadErrorModalVisible }
391
- onClose = { ( ) => setIsDownloadErrorModalVisible ( false ) }
392
- />
393
- </ View >
394
- ) ;
395
- }
370
+ const isCannedQuery = isCannedSearchQuery ( queryJSON ) ;
396
371
397
372
return (
398
373
< >
399
- < SearchPageHeaderInput
400
- searchRouterListVisible = { searchRouterListVisible }
401
- onSearchRouterFocus = { onSearchRouterFocus }
402
- queryJSON = { queryJSON }
403
- inputRightComponent = { InputRightComponent }
404
- />
374
+ < SearchPageHeaderInput queryJSON = { queryJSON } >
375
+ { headerButtonsOptions . length > 0 ? (
376
+ < ButtonWithDropdownMenu
377
+ onPress = { ( ) => null }
378
+ shouldAlwaysShowDropdownMenu
379
+ buttonSize = { CONST . DROPDOWN_BUTTON_SIZE . MEDIUM }
380
+ customText = { translate ( 'workspace.common.selected' , { count : selectedTransactionsKeys . length } ) }
381
+ options = { headerButtonsOptions }
382
+ isSplitButton = { false }
383
+ shouldUseStyleUtilityForAnchorPosition
384
+ />
385
+ ) : (
386
+ < EducationalTooltip
387
+ shouldRender = { shouldShowProductTrainingTooltip }
388
+ anchorAlignment = { {
389
+ vertical : CONST . MODAL . ANCHOR_ORIGIN_VERTICAL . BOTTOM ,
390
+ horizontal : CONST . MODAL . ANCHOR_ORIGIN_HORIZONTAL . RIGHT ,
391
+ } }
392
+ shiftHorizontal = { variables . searchFiltersTooltipShiftHorizontal }
393
+ wrapperStyle = { styles . productTrainingTooltipWrapper }
394
+ renderTooltipContent = { renderProductTrainingTooltip }
395
+ onTooltipPress = { onFiltersButtonPress }
396
+ >
397
+ < Button
398
+ innerStyles = { ! isCannedQuery && [ styles . searchRouterInputResults , styles . borderNone ] }
399
+ text = { translate ( 'search.filtersHeader' ) }
400
+ icon = { Expensicons . Filters }
401
+ onPress = { onFiltersButtonPress }
402
+ />
403
+ </ EducationalTooltip >
404
+ ) }
405
+ </ SearchPageHeaderInput >
405
406
< ConfirmModal
406
407
isVisible = { isDeleteExpensesConfirmModalVisible }
407
408
onConfirm = { handleDeleteExpenses }
0 commit comments