Skip to content
Draft
Show file tree
Hide file tree
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
Expand Up @@ -101,6 +101,9 @@ function useCopyPolicySettingsProgressModal() {
confirmText: translate('workspace.copyPolicySettings.progress.letMeKnowPrompt'),
cancelText: '',
shouldShowCancelButton: false,
// The X is the only way to close this step. Without it onCancel is reachable only by backdrop press,
// Escape, or browser back, so a user who walks away from the copy never asks to be told if it fails.
shouldShowDismissIcon: true,
isTitleLoading: true,
onConfirm: () => {
requestCopyPolicySettingsNotification();
Expand Down Expand Up @@ -144,7 +147,8 @@ function useCopyPolicySettingsProgressModal() {
}

function CopyPolicySettingsProgressModal() {
const {isVisible, title, prompt, confirmText, cancelText, shouldShowCancelButton, isTitleLoading, danger, onConfirm, onCancel} = useCopyPolicySettingsProgressModal();
const {isVisible, title, prompt, confirmText, cancelText, shouldShowCancelButton, shouldShowDismissIcon, isTitleLoading, danger, onConfirm, onCancel} =
useCopyPolicySettingsProgressModal();

return (
// eslint-disable-next-line @typescript-eslint/no-deprecated -- The global useConfirmModal()/showConfirmModal() API is one-shot (its promise resolves on the first confirm/cancel and the modal unmounts). This progress modal must stay open across multiple Onyx state transitions ('loading' → notify-requested → 'complete') and update its content in place, which the global system does not support.
Expand All @@ -157,6 +161,7 @@ function CopyPolicySettingsProgressModal() {
confirmText={confirmText}
cancelText={cancelText}
shouldShowCancelButton={shouldShowCancelButton}
shouldShowDismissIcon={shouldShowDismissIcon}
isTitleLoading={isTitleLoading}
shouldHandleNavigationBack
buttonVariant={danger ? CONST.BUTTON_VARIANT.DANGER : CONST.BUTTON_VARIANT.SUCCESS}
Expand Down
23 changes: 23 additions & 0 deletions tests/unit/CopyPolicySettingsProgressModalTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type MockConfirmModalProps = {
confirmText?: string;
cancelText?: string;
shouldShowCancelButton?: boolean;
shouldShowDismissIcon?: boolean;
shouldHandleNavigationBack?: boolean;
buttonVariant?: string;
};
Expand Down Expand Up @@ -171,6 +172,12 @@ describe('CopyPolicySettingsProgressModal', () => {
expect(lastModalProps?.shouldShowCancelButton).toBe(false);
});

it('should show the dismiss icon so the modal can be closed while the copy runs', async () => {
await renderModal();

expect(lastModalProps?.shouldShowDismissIcon).toBe(true);
});

it('should call requestCopyPolicySettingsNotification on confirm', async () => {
await renderModal();

Expand All @@ -179,6 +186,20 @@ describe('CopyPolicySettingsProgressModal', () => {
});

expect(mockRequestNotification).toHaveBeenCalledTimes(1);
// "Let me know when it's done" asks to be notified either way, not only on failure
expect(mockRequestNotification).not.toHaveBeenCalledWith(true);
});

it('should request a failure-only Concierge notification on cancel (dismiss)', async () => {
await renderModal();

act(() => {
lastModalProps?.onCancel?.();
});

expect(mockRequestNotification).toHaveBeenCalledTimes(1);
expect(mockRequestNotification).toHaveBeenCalledWith(true);
expect(mockClearCopyPolicySettings).toHaveBeenCalledTimes(1);
});
});

Expand Down Expand Up @@ -374,6 +395,8 @@ describe('CopyPolicySettingsProgressModal', () => {

expect(mockClearCopyPolicySettings).toHaveBeenCalledTimes(1);
expect(mockNavigate).not.toHaveBeenCalled();
// The failure is already on screen, so there is nothing for Concierge to report
expect(mockRequestNotification).not.toHaveBeenCalled();
});

it('should not navigate when sourcePolicyID is not available', async () => {
Expand Down
Loading