diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx index ac66c368f631..a93a9f154276 100644 --- a/src/pages/settings/Security/SecuritySettingsPage.tsx +++ b/src/pages/settings/Security/SecuritySettingsPage.tsx @@ -14,7 +14,8 @@ import MenuItem from '@components/MenuItem'; import type {MenuItemProps} from '@components/MenuItem'; import MenuItemList from '@components/MenuItemList'; import {usePersonalDetails} from '@components/OnyxProvider'; -import Popover from '@components/Popover'; +import PopoverMenu from '@components/PopoverMenu'; +import type {PopoverMenuItem} from '@components/PopoverMenu'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Section from '@components/Section'; @@ -31,7 +32,7 @@ import getClickedTargetLocation from '@libs/getClickedTargetLocation'; import {formatPhoneNumber} from '@libs/LocalePhoneNumber'; import Navigation from '@libs/Navigation/Navigation'; import {getPersonalDetailByEmail} from '@libs/PersonalDetailsUtils'; -import variables from '@styles/variables'; +import type {AnchorPosition} from '@styles/index'; import * as Modal from '@userActions/Modal'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; @@ -54,43 +55,41 @@ function SecuritySettingsPage() { const [shouldShowDelegatePopoverMenu, setShouldShowDelegatePopoverMenu] = useState(false); const [shouldShowRemoveDelegateModal, setShouldShowRemoveDelegateModal] = useState(false); const [selectedDelegate, setSelectedDelegate] = useState(); + const [selectedEmail, setSelectedEmail] = useState(); + const errorFields = account?.delegatedAccess?.errorFields ?? {}; - const [anchorPosition, setAnchorPosition] = useState({ - anchorPositionHorizontal: 0, - anchorPositionVertical: 0, - anchorPositionTop: 0, - anchorPositionRight: 0, + const [anchorPosition, setAnchorPosition] = useState({ + horizontal: 0, + vertical: 0, }); + const isActingAsDelegate = !!account?.delegatedAccess?.delegate || false; + + const delegates = account?.delegatedAccess?.delegates ?? []; + const delegators = account?.delegatedAccess?.delegators ?? []; + + const hasDelegates = delegates.length > 0; + const hasDelegators = delegators.length > 0; + const setMenuPosition = useCallback(() => { if (!delegateButtonRef.current) { return; } const position = getClickedTargetLocation(delegateButtonRef.current); - setAnchorPosition({ - anchorPositionTop: position.top + position.height - variables.bankAccountActionPopoverTopSpacing, - // We want the position to be 23px to the right of the left border - anchorPositionRight: windowWidth - position.right + variables.bankAccountActionPopoverRightSpacing, - anchorPositionHorizontal: position.x + variables.addBankAccountLeftSpacing, - anchorPositionVertical: position.y, + horizontal: position.right - position.left, + vertical: position.y + position.height, }); - }, [windowWidth]); - const isActingAsDelegate = !!account?.delegatedAccess?.delegate || false; - - const delegates = account?.delegatedAccess?.delegates ?? []; - const delegators = account?.delegatedAccess?.delegators ?? []; - - const hasDelegates = delegates.length > 0; - const hasDelegators = delegators.length > 0; + }, [delegateButtonRef]); const showPopoverMenu = (nativeEvent: GestureResponderEvent | KeyboardEvent, delegate: Delegate) => { delegateButtonRef.current = nativeEvent?.currentTarget as HTMLDivElement; setMenuPosition(); setShouldShowDelegatePopoverMenu(true); setSelectedDelegate(delegate); + setSelectedEmail(delegate.email); }; useLayoutEffect(() => { @@ -174,10 +173,11 @@ function SecuritySettingsPage() { onPendingActionDismiss: () => clearDelegateErrorsByField(email, 'addDelegate'), error, onPress, + success: selectedEmail === email, }; }), // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - [delegates, translate, styles, personalDetails, errorFields], + [delegates, translate, styles, personalDetails, errorFields, windowWidth, selectedEmail], ); const delegatorMenuItems: MenuItemProps[] = useMemo( @@ -202,6 +202,29 @@ function SecuritySettingsPage() { [delegators, styles, translate, personalDetails], ); + const delegatePopoverMenuItems: PopoverMenuItem[] = [ + { + text: translate('delegate.changeAccessLevel'), + icon: Expensicons.Pencil, + onPress: () => { + Navigation.navigate(ROUTES.SETTINGS_UPDATE_DELEGATE_ROLE.getRoute(selectedDelegate?.email ?? '', selectedDelegate?.role ?? '')); + setShouldShowDelegatePopoverMenu(false); + setSelectedDelegate(undefined); + setSelectedEmail(undefined); + }, + }, + { + text: translate('delegate.removeCopilot'), + icon: Expensicons.Trashcan, + onPress: () => + Modal.close(() => { + setShouldShowDelegatePopoverMenu(false); + setShouldShowRemoveDelegateModal(true); + setSelectedEmail(undefined); + }), + }, + ]; + return ( - } anchorPosition={{ - top: anchorPosition.anchorPositionTop, - right: anchorPosition.anchorPositionRight, + horizontal: anchorPosition.horizontal, + vertical: anchorPosition.vertical, + }} + anchorAlignment={{ + horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, + vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP, }} + menuItems={delegatePopoverMenuItems} onClose={() => { setShouldShowDelegatePopoverMenu(false); + setSelectedEmail(undefined); }} - > - - { - Navigation.navigate(ROUTES.SETTINGS_UPDATE_DELEGATE_ROLE.getRoute(selectedDelegate?.email ?? '', selectedDelegate?.role ?? '')); - setShouldShowDelegatePopoverMenu(false); - setSelectedDelegate(undefined); - }} - wrapperStyle={[styles.pv3, styles.ph5, !shouldUseNarrowLayout ? styles.sidebarPopover : {}]} - /> - - Modal.close(() => { - setShouldShowDelegatePopoverMenu(false); - setShouldShowRemoveDelegateModal(true); - }) - } - wrapperStyle={[styles.pv3, styles.ph5, !shouldUseNarrowLayout ? styles.sidebarPopover : {}]} - /> - - + />