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 Avatar from '@components/Avatar' ;
66import AvatarWithImagePicker from '@components/AvatarWithImagePicker' ;
7- import Button from '@components/Button' ;
7+ import ButtonWithDropdownMenu from '@components/ButtonWithDropdownMenu' ;
8+ import type { DropdownOption } from '@components/ButtonWithDropdownMenu/types' ;
89import ConfirmModal from '@components/ConfirmModal' ;
910import { FallbackWorkspaceAvatar , ImageCropSquareMask , QrCode , Trashcan , UserPlus } from '@components/Icon/Expensicons' ;
1011import { Building } from '@components/Icon/Illustrations' ;
@@ -174,6 +175,8 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
174175
175176 const { setIsDeletingPaidWorkspace, isLoadingBill} : { setIsDeletingPaidWorkspace : ( value : boolean ) => void ; isLoadingBill : boolean | undefined } = usePayAndDowngrade ( setIsDeleteModalOpen ) ;
176177
178+ const dropdownMenuRef = useRef < { setIsMenuVisible : ( visible : boolean ) => void } | null > ( null ) ;
179+
177180 const confirmDeleteAndHideModal = useCallback ( ( ) => {
178181 if ( ! policy ?. id || ! policyName ) {
179182 return ;
@@ -187,6 +190,13 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
187190 }
188191 } , [ policy ?. id , policyName , shouldUseNarrowLayout ] ) ;
189192
193+ useEffect ( ( ) => {
194+ if ( isLoadingBill ) {
195+ return ;
196+ }
197+ dropdownMenuRef . current ?. setIsMenuVisible ( false ) ;
198+ } , [ isLoadingBill ] ) ;
199+
190200 const onDeleteWorkspace = useCallback ( ( ) => {
191201 if ( shouldCalculateBillNewDot ( ) ) {
192202 setIsDeletingPaidWorkspace ( true ) ;
@@ -211,6 +221,59 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
211221 Navigation . popToSidebar ( ) ;
212222 } ;
213223
224+ const getHeaderButtons = ( ) => {
225+ if ( readOnly ) {
226+ return null ;
227+ }
228+ const secondaryActions : Array < DropdownOption < string > > = [ ] ;
229+ if ( isPolicyAdmin ) {
230+ secondaryActions . push ( {
231+ value : 'invite' ,
232+ text : translate ( 'common.invite' ) ,
233+ icon : UserPlus ,
234+ onSelected : ( ) => {
235+ if ( isAccountLocked ) {
236+ showLockedAccountModal ( ) ;
237+ return ;
238+ }
239+ clearInviteDraft ( route . params . policyID ) ;
240+ Navigation . navigate ( ROUTES . WORKSPACE_INVITE . getRoute ( route . params . policyID , Navigation . getActiveRouteWithoutParams ( ) ) ) ;
241+ } ,
242+ } ) ;
243+ }
244+ secondaryActions . push ( {
245+ value : 'share' ,
246+ text : translate ( 'common.share' ) ,
247+ icon : QrCode ,
248+ onSelected : isAccountLocked ? showLockedAccountModal : onPressShare ,
249+ } ) ;
250+ if ( isOwner ) {
251+ secondaryActions . push ( {
252+ value : 'delete' ,
253+ text : translate ( 'common.delete' ) ,
254+ icon : Trashcan ,
255+ onSelected : onDeleteWorkspace ,
256+ disabled : isLoadingBill ,
257+ shouldShowLoadingSpinnerIcon : isLoadingBill ,
258+ shouldCloseModalOnSelect : ! shouldCalculateBillNewDot ( ) ,
259+ } ) ;
260+ }
261+ return (
262+ < View style = { [ ! shouldUseNarrowLayout && styles . flexRow , ! shouldUseNarrowLayout && styles . gap2 ] } >
263+ < ButtonWithDropdownMenu
264+ ref = { dropdownMenuRef }
265+ success = { false }
266+ onPress = { ( ) => { } }
267+ shouldAlwaysShowDropdownMenu
268+ customText = { translate ( 'common.more' ) }
269+ options = { secondaryActions }
270+ isSplitButton = { false }
271+ wrapperStyle = { styles . flexGrow1 }
272+ />
273+ </ View >
274+ ) ;
275+ } ;
276+
214277 return (
215278 < WorkspacePageWithSections
216279 headerText = { translate ( 'workspace.common.profile' ) }
@@ -224,9 +287,11 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
224287 shouldShowNotFoundPage = { policy === undefined }
225288 onBackButtonPress = { handleBackButtonPress }
226289 addBottomSafeAreaPadding
290+ headerContent = { ! shouldUseNarrowLayout && getHeaderButtons ( ) }
227291 >
228292 { ( hasVBA ?: boolean ) => (
229293 < View style = { [ styles . flex1 , styles . mt3 , shouldUseNarrowLayout ? styles . workspaceSectionMobile : styles . workspaceSection ] } >
294+ { shouldUseNarrowLayout && < View style = { [ styles . pl5 , styles . pr5 , styles . pb5 ] } > { getHeaderButtons ( ) } </ View > }
230295 < Section
231296 isCentralPane
232297 title = ""
@@ -376,43 +441,6 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
376441 </ View >
377442 </ OfflineWithFeedback >
378443 ) }
379- { ! readOnly && (
380- < View style = { [ styles . flexRow , styles . mt6 , styles . mnw120 ] } >
381- { isPolicyAdmin && (
382- < Button
383- accessibilityLabel = { translate ( 'common.invite' ) }
384- text = { translate ( 'common.invite' ) }
385- onPress = { ( ) => {
386- if ( isAccountLocked ) {
387- showLockedAccountModal ( ) ;
388- return ;
389- }
390- clearInviteDraft ( route . params . policyID ) ;
391- Navigation . navigate ( ROUTES . WORKSPACE_INVITE . getRoute ( route . params . policyID , Navigation . getActiveRouteWithoutParams ( ) ) ) ;
392- } }
393- icon = { UserPlus }
394- style = { [ styles . mr2 ] }
395- />
396- ) }
397- < Button
398- accessibilityLabel = { translate ( 'common.share' ) }
399- text = { translate ( 'common.share' ) }
400- onPress = { isAccountLocked ? showLockedAccountModal : onPressShare }
401- icon = { QrCode }
402- />
403- { isOwner && (
404- < Button
405- accessibilityLabel = { translate ( 'common.delete' ) }
406- text = { translate ( 'common.delete' ) }
407- style = { [ styles . ml2 ] }
408- onPress = { onDeleteWorkspace }
409- icon = { Trashcan }
410- isLoading = { isLoadingBill }
411- iconStyles = { isLoadingBill ? styles . opacity0 : undefined }
412- />
413- ) }
414- </ View >
415- ) }
416444 </ Section >
417445 < ConfirmModal
418446 title = { translate ( 'workspace.common.delete' ) }
0 commit comments