diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts index dc6678da8e26..545f3a48bdc5 100644 --- a/src/libs/actions/Delegate.ts +++ b/src/libs/actions/Delegate.ts @@ -410,6 +410,7 @@ function updateDelegateRole(email: string, role: DelegateRole, validateCode: str errorFields: {updateDelegateRole: null}, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, pendingFields: {role: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + isLoading: true, } : delegate, ), @@ -432,6 +433,7 @@ function updateDelegateRole(email: string, role: DelegateRole, validateCode: str errorFields: {updateDelegateRole: null}, pendingAction: null, pendingFields: {role: null}, + isLoading: false, } : delegate, ), @@ -453,8 +455,9 @@ function updateDelegateRole(email: string, role: DelegateRole, validateCode: str errorFields: { updateDelegateRole: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('delegate.genericError'), }, - pendingAction: null, - pendingFields: {role: null}, + isLoading: false, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + pendingFields: {role: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, } : delegate, ), @@ -498,6 +501,34 @@ function updateDelegateRoleOptimistically(email: string, role: DelegateRole) { Onyx.update(optimisticData); } +function clearDelegateRolePendingAction(email: string) { + if (!delegatedAccess?.delegates) { + return; + } + + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.ACCOUNT, + value: { + delegatedAccess: { + delegates: delegatedAccess.delegates.map((delegate) => + delegate.email === email + ? { + ...delegate, + pendingAction: null, + pendingFields: undefined, + } + : delegate, + ), + }, + }, + }, + ]; + + Onyx.update(optimisticData); +} + export { connect, disconnect, @@ -509,4 +540,5 @@ export { removeDelegate, updateDelegateRole, updateDelegateRoleOptimistically, + clearDelegateRolePendingAction, }; diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx index fc6a47da52ac..b5a1edc20c44 100644 --- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx +++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useState} from 'react'; +import React, {useEffect, useState} from 'react'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; @@ -8,12 +8,13 @@ import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import {requestValidationCode, updateDelegateRoleOptimistically} from '@libs/actions/Delegate'; +import {clearDelegateRolePendingAction, requestValidationCode, updateDelegateRoleOptimistically} from '@libs/actions/Delegate'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; +import type {DelegateRole} from '@src/types/onyx/Account'; type UpdateDelegateRolePageProps = StackScreenProps; @@ -25,12 +26,19 @@ function UpdateDelegateRolePage({route}: UpdateDelegateRolePageProps) { const styles = useThemeStyles(); const roleOptions = Object.values(CONST.DELEGATE_ROLE).map((role) => ({ value: role, - text: translate('delegate.role', role), + text: translate('delegate.role', {role}), keyForList: role, - alternateText: translate('delegate.roleDescription', role), + alternateText: translate('delegate.roleDescription', {role}), isSelected: role === currentRole, })); + useEffect(() => { + updateDelegateRoleOptimistically(login ?? '', currentRole as DelegateRole); + return () => clearDelegateRolePendingAction(login); + // eslint-disable-next-line react-compiler/react-compiler + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [login]); + return ( { requestValidationCode(); - updateDelegateRoleOptimistically(login ?? '', option.value); setCurrentRole(option.value); Navigation.navigate(ROUTES.SETTINGS_UPDATE_DELEGATE_ROLE_MAGIC_CODE.getRoute(login, option.value)); }} diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx index acd484b34878..8b0fb1fd726c 100644 --- a/src/pages/settings/Security/SecuritySettingsPage.tsx +++ b/src/pages/settings/Security/SecuritySettingsPage.tsx @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import debounce from 'lodash/debounce'; import React, {useCallback, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {RefObject} from 'react'; import {Dimensions, View} from 'react-native'; @@ -92,7 +92,7 @@ function SecuritySettingsPage() { useLayoutEffect(() => { const popoverPositionListener = Dimensions.addEventListener('change', () => { - _.debounce(setMenuPosition, CONST.TIMING.RESIZE_DEBOUNCE_TIME)(); + debounce(setMenuPosition, CONST.TIMING.RESIZE_DEBOUNCE_TIME)(); }); return () => {