11import { useFocusEffect } from '@react-navigation/native' ;
2- import React , { useCallback , useContext , useState } from 'react' ;
2+ import React , { useCallback , useContext , useEffect , useRef , useState } from 'react' ;
33import type { ImageStyle , StyleProp } from 'react-native' ;
44import { Image , StyleSheet , View } from 'react-native' ;
55import { useOnyx } from 'react-native-onyx' ;
66import Avatar from '@components/Avatar' ;
77import AvatarWithImagePicker from '@components/AvatarWithImagePicker' ;
8- import Button from '@components/Button' ;
8+ import ButtonWithDropdownMenu from '@components/ButtonWithDropdownMenu' ;
9+ import type { DropdownOption } from '@components/ButtonWithDropdownMenu/types' ;
910import ConfirmModal from '@components/ConfirmModal' ;
1011import { FallbackWorkspaceAvatar , ImageCropSquareMask , QrCode , Trashcan , UserPlus } from '@components/Icon/Expensicons' ;
1112import { Building } from '@components/Icon/Illustrations' ;
@@ -173,6 +174,8 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
173174
174175 const { setIsDeletingPaidWorkspace, isLoadingBill} : { setIsDeletingPaidWorkspace : ( value : boolean ) => void ; isLoadingBill : boolean | undefined } = usePayAndDowngrade ( setIsDeleteModalOpen ) ;
175176
177+ const dropdownMenuRef = useRef < any > ( null ) ;
178+
176179 const confirmDeleteAndHideModal = useCallback ( ( ) => {
177180 if ( ! policy ?. id || ! policyName ) {
178181 return ;
@@ -186,6 +189,12 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
186189 }
187190 } , [ policy ?. id , policyName , shouldUseNarrowLayout ] ) ;
188191
192+ useEffect ( ( ) => {
193+ if ( ! isLoadingBill ) {
194+ dropdownMenuRef . current . setIsMenuVisible ( false ) ;
195+ }
196+ } , [ isLoadingBill ] ) ;
197+
189198 const onDeleteWorkspace = useCallback ( ( ) => {
190199 if ( shouldCalculateBillNewDot ( ) ) {
191200 setIsDeletingPaidWorkspace ( true ) ;
@@ -210,6 +219,59 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
210219 Navigation . popToSidebar ( ) ;
211220 } ;
212221
222+ const getHeaderButtons = ( ) => {
223+ if ( readOnly ) {
224+ return null ;
225+ }
226+ const secondaryActions : DropdownOption < string > [ ] = [ ] ;
227+ if ( isPolicyAdmin ) {
228+ secondaryActions . push ( {
229+ value : 'invite' ,
230+ text : translate ( 'common.invite' ) ,
231+ icon : UserPlus ,
232+ onSelected : ( ) => {
233+ if ( isAccountLocked ) {
234+ showLockedAccountModal ( ) ;
235+ return ;
236+ }
237+ clearInviteDraft ( route . params . policyID ) ;
238+ Navigation . navigate ( ROUTES . WORKSPACE_INVITE . getRoute ( route . params . policyID , Navigation . getActiveRouteWithoutParams ( ) ) ) ;
239+ } ,
240+ } ) ;
241+ }
242+ secondaryActions . push ( {
243+ value : 'share' ,
244+ text : translate ( 'common.share' ) ,
245+ icon : QrCode ,
246+ onSelected : isAccountLocked ? showLockedAccountModal : onPressShare ,
247+ } ) ;
248+ if ( isOwner ) {
249+ secondaryActions . push ( {
250+ value : 'delete' ,
251+ text : translate ( 'common.delete' ) ,
252+ icon : Trashcan ,
253+ onSelected : onDeleteWorkspace ,
254+ disabled : isLoadingBill ,
255+ shouldShowLoadingSpinnerIcon : isLoadingBill ,
256+ shouldCloseModalOnSelect : false ,
257+ } ) ;
258+ }
259+ return (
260+ < View style = { [ ! shouldUseNarrowLayout && styles . flexRow , ! shouldUseNarrowLayout && styles . gap2 ] } >
261+ < ButtonWithDropdownMenu
262+ ref = { dropdownMenuRef }
263+ success = { false }
264+ onPress = { ( ) => { } }
265+ shouldAlwaysShowDropdownMenu
266+ customText = { translate ( 'common.more' ) }
267+ options = { secondaryActions }
268+ isSplitButton = { false }
269+ wrapperStyle = { styles . flexGrow1 }
270+ />
271+ </ View >
272+ ) ;
273+ } ;
274+
213275 return (
214276 < WorkspacePageWithSections
215277 headerText = { translate ( 'workspace.common.profile' ) }
@@ -223,9 +285,11 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
223285 shouldShowNotFoundPage = { policy === undefined }
224286 onBackButtonPress = { handleBackButtonPress }
225287 addBottomSafeAreaPadding
288+ headerContent = { ! shouldUseNarrowLayout && getHeaderButtons ( ) }
226289 >
227290 { ( hasVBA ?: boolean ) => (
228291 < View style = { [ styles . flex1 , styles . mt3 , shouldUseNarrowLayout ? styles . workspaceSectionMobile : styles . workspaceSection ] } >
292+ { shouldUseNarrowLayout && < View style = { [ styles . pl5 , styles . pr5 , styles . pb5 ] } > { getHeaderButtons ( ) } </ View > }
229293 < Section
230294 isCentralPane
231295 title = ""
@@ -375,43 +439,6 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
375439 </ View >
376440 </ OfflineWithFeedback >
377441 ) }
378- { ! readOnly && (
379- < View style = { [ styles . flexRow , styles . mt6 , styles . mnw120 ] } >
380- { isPolicyAdmin && (
381- < Button
382- accessibilityLabel = { translate ( 'common.invite' ) }
383- text = { translate ( 'common.invite' ) }
384- onPress = { ( ) => {
385- if ( isAccountLocked ) {
386- showLockedAccountModal ( ) ;
387- return ;
388- }
389- clearInviteDraft ( route . params . policyID ) ;
390- Navigation . navigate ( ROUTES . WORKSPACE_INVITE . getRoute ( route . params . policyID , Navigation . getActiveRouteWithoutParams ( ) ) ) ;
391- } }
392- icon = { UserPlus }
393- style = { [ styles . mr2 ] }
394- />
395- ) }
396- < Button
397- accessibilityLabel = { translate ( 'common.share' ) }
398- text = { translate ( 'common.share' ) }
399- onPress = { isAccountLocked ? showLockedAccountModal : onPressShare }
400- icon = { QrCode }
401- />
402- { isOwner && (
403- < Button
404- accessibilityLabel = { translate ( 'common.delete' ) }
405- text = { translate ( 'common.delete' ) }
406- style = { [ styles . ml2 ] }
407- onPress = { onDeleteWorkspace }
408- icon = { Trashcan }
409- isLoading = { isLoadingBill }
410- iconStyles = { isLoadingBill ? styles . opacity0 : undefined }
411- />
412- ) }
413- </ View >
414- ) }
415442 </ Section >
416443 < ConfirmModal
417444 title = { translate ( 'workspace.common.delete' ) }
0 commit comments