Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useCallback} from 'react';
import BaseVacationDelegateSelectionComponent from '@components/BaseVacationDelegateSelectionComponent';
import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView';
import {ModalActions} from '@components/Modal/Global/ModalContext';
import ScreenWrapper from '@components/ScreenWrapper';
import useConfirmModal from '@hooks/useConfirmModal';
Expand All @@ -21,6 +22,20 @@ function VacationDelegatePage() {

const [vacationDelegate] = useOnyx(ONYXKEYS.NVP_PRIVATE_VACATION_DELEGATE);

const showErrorModal = useCallback(
async (message?: string) => {
await showConfirmModal({
title: translate('common.headsUp'),
prompt: message ?? translate('statusPage.vacationDelegateError'),
confirmText: translate('common.buttonConfirm'),
shouldShowCancelButton: false,
});

clearVacationDelegateError(vacationDelegate?.previousDelegate);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Clear EXP_ERROR with current previous delegate value

showErrorModal captures vacationDelegate?.previousDelegate from the render before setVacationDelegate applies its optimistic Onyx update. When a user already has a delegate and selects an invalid account, the EXP_ERROR path calls clearVacationDelegateError with that stale value (often undefined), so the rollback sets delegate to null instead of restoring the original delegate. This turns a failed edit into an unintended delegate removal in that flow.

Useful? React with 👍 / 👎.

},
[showConfirmModal, translate, vacationDelegate?.previousDelegate],
);

const showWarningModal = useCallback(
async (delegateLogin: string) => {
const result = await showConfirmModal({
Expand Down Expand Up @@ -56,6 +71,11 @@ function VacationDelegatePage() {
return;
}

if (response.jsonCode === CONST.JSON_CODE.EXP_ERROR) {
showErrorModal(response.message);
return;
}

if (response.jsonCode === CONST.JSON_CODE.POLICY_DIFF_WARNING) {
showWarningModal(option?.login ?? '');
return;
Expand All @@ -64,22 +84,24 @@ function VacationDelegatePage() {
Navigation.goBack(ROUTES.SETTINGS_STATUS);
});
},
[currentUserLogin, vacationDelegate, showWarningModal],
[currentUserLogin, vacationDelegate, showWarningModal, showErrorModal],
);

return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
testID="VacationDelegatePage"
>
<BaseVacationDelegateSelectionComponent
vacationDelegate={vacationDelegate}
onSelectRow={onSelectRow}
headerTitle={translate('common.vacationDelegate')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_STATUS)}
cannotSetDelegateMessage={translate('statusPage.cannotSetVacationDelegate')}
includeCurrentUser={false}
/>
<FullPageOfflineBlockingView>
<BaseVacationDelegateSelectionComponent
vacationDelegate={vacationDelegate}
onSelectRow={onSelectRow}
headerTitle={translate('common.vacationDelegate')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_STATUS)}
cannotSetDelegateMessage={translate('statusPage.cannotSetVacationDelegate')}
includeCurrentUser={false}
/>
</FullPageOfflineBlockingView>
</ScreenWrapper>
);
}
Expand Down
Loading