Repository: Automattic/wp-calypso
Pull request #103401: Make DIFM migration cancellation context aware
Author: login: markbiek
Created: 2025-05-13T18:36:15Z | Merged: 2025-05-19T20:21:40Z

<!--
Link a related Github/Linear issue to this PR. If the PR does not immediately resolve the issue,
for example, it requires a separate deployment to production, avoid
using the "fixes" keyword. Consider using "part of" instead.
-->

Part of DOTCON-26

## Proposed Changes

We now display slightly different context depending on if the site has a migration in progress.

If the site doesn't have a migration in progress (no migration-in-progress sticker), the user is allowed to cancel outright.

Otherwise they are told they're sending a migration cancellation request.

## Why are these changes being made?
<!--
It's easy to see what a PR does but much harder to find out why it was made,
particularly when researching old changes in history. Record an explanation of
the motivation behind this change and how it will help.
-->

*

## Testing Instructions

<!--
Add as many details as possible to help others reproduce the issue and test the fix.
"Before / After" screenshots can also be very helpful when the change is visual.
-->

This PR requires the functionality in 182742-ghe-Automattic/wpcom. If that endpoint change hasn't been merged, you'll need to apply it to your sandbox and sandbox the public-api.

You'll need to enable the `migration-flow/cancel-difm` if you're using the calypso.live url instead of running this locally. If you _are_ running this locally, you'll need to choose 'Share credentials' instead of 'Authorize application' when you reach that point of the migration flow.

### Direct Cancellation

In this case, the migration is _not_ in-progress (doesn't have the `migration-in-progress` sticker) and can be cancelled directly.

* Go to /start and continue to the Goals step.
* Select the 'import or migrate' intent.
* Continue with the migration flow and select a DIFM migration.
* When you reach the site overview, there should be a new 'Cancel migration' button.
![image](https://github.com/user-attachments/assets/8f0d3a62-6534-4e5a-8b22-590df88cb851)
* Clicking the button should show the following dialog.
![image](https://github.com/user-attachments/assets/25c88f80-a58c-44d5-b9aa-3de66b6b97fc)
* Clicking 'Cancel migration' in the dialog should show the following success message.
![image](https://github.com/user-attachments/assets/69193738-cbe5-4e62-aade-a0233548e877)
* Verify that the Zendesk ticket for the migration has an internal message reading 'The user has cancelled the migration'.
* The site should also have the `migration-cancelled-difm` sticker.

### Cancellation request

In this case, the migration _is_ = in-progress (has the `migration-in-progress` sticker) so a cancellation request is sent instead.

* Go to /start and continue to the Goals step.
* Select the 'import or migrate' intent.
* Continue with the migration flow and select a DIFM migration.
* When you reach the site overview, there should be a new 'Request migration cancellation' button.
![image](https://github.com/user-attachments/assets/438f2175-b327-4069-a298-d05c2046f21e)

* Clicking the button should show the following dialog.
![image](https://github.com/user-attachments/assets/78f6ef35-79d7-4125-94c0-edf47120e9ba)

* Clicking 'Send request' in the dialog should show the following success message.
![image](https://github.com/user-attachments/assets/042fb04c-788f-4ac2-b287-8cb07d11e75c)

* Verify that the Zendesk ticket for the migration has an internal message reading 'The user has requested to cancel the migration'.
* The site should _not_ have the `migration-cancellation-difm` sticker added.

## Pre-merge Checklist

<!--
Complete applicable items on this checklist **before** merging into trunk. Inapplicable items can be left unchecked.

Both the PR author and reviewer are responsible for ensuring the checklist is completed.
-->

- [ ] Has the general commit checklist been followed? (PCYsg-hS-p2)
- [ ] [Have you written new tests](https://wpcalypso.wordpress.com/devdocs/docs/testing/index.md) for your changes?
- [ ] Have you tested the feature in Simple (P9HQHe-k8-p2), Atomic (P9HQHe-jW-p2), and self-hosted Jetpack sites (PCYsg-g6b-p2)?
- [ ] Have you checked for TypeScript, React or other console errors?
- [ ] Have you used memoizing on expensive computations? More info in [Memoizing with create-selector](https://github.com/Automattic/wp-calypso/blob/trunk/packages/state-utils/src/create-selector/README.md) and [Using memoizing selectors](https://react-redux.js.org/api/hooks#using-memoizing-selectors) and [Our Approach to Data](https://github.com/Automattic/wp-calypso/blob/trunk/docs/our-approach-to-data.md)
- [ ] Have we added the "[Status] String Freeze" label as soon as any new strings were ready for translation (p4TIVU-5Jq-p2)?
    - [ ] For UI changes, have we tested the change in various languages (for example, ES, PT, FR, or DE)? The length of text and words vary significantly between languages. 
- [ ] For changes affecting Jetpack: Have we added the "[Status] Needs Privacy Updates" label if this pull request changes what data or activity we track or use (p4TIVU-aUh-p2)?


Diff:
diff --git a/client/sites/overview/components/migration-overview/components/cancel-difm-migration/index.tsx b/client/sites/overview/components/migration-overview/components/cancel-difm-migration/index.tsx
index 5ca358ce16fc..a07348620a44 100644
--- a/client/sites/overview/components/migration-overview/components/cancel-difm-migration/index.tsx
+++ b/client/sites/overview/components/migration-overview/components/cancel-difm-migration/index.tsx
@@ -3,13 +3,103 @@ import { Modal, Button } from '@wordpress/components';
 import { useTranslate } from 'i18n-calypso';
 import { useState } from 'react';
 import { useDispatch } from 'react-redux';
+import { useBlogStickersQuery } from 'calypso/blocks/blog-stickers/use-blog-stickers-query';
 import { LoadingBar } from 'calypso/components/loading-bar';
 import wp from 'calypso/lib/wp';
 import { successNotice, errorNotice } from 'calypso/state/notices/actions';
 
+type CancelMigrationButtonProps = {
+	isMigrationInProgress: boolean;
+	onClick: () => void;
+	buttonType: 'cta' | 'confirm';
+	variant?: 'link' | 'primary' | 'secondary' | 'tertiary' | undefined;
+	key?: string;
+};
+
+const CancelMigrationButton = ( {
+	isMigrationInProgress,
+	onClick,
+	buttonType,
+	...buttonProps
+}: CancelMigrationButtonProps ) => {
+	const translate = useTranslate();
+
+	let cancelMigrationButtonText = translate( 'Cancel migration' );
+
+	if ( buttonType === 'cta' && isMigrationInProgress ) {
+		cancelMigrationButtonText = translate( 'Request migration cancellation' );
+	}
+
+	if ( buttonType === 'confirm' && isMigrationInProgress ) {
+		cancelMigrationButtonText = translate( 'Send request' );
+	}
+
+	return (
+		<Button
+			onClick={ ( e: React.MouseEvent< HTMLButtonElement > ) => {
+				e.preventDefault();
+				onClick();
+			} }
+			{ ...buttonProps }
+		>
+			{ cancelMigrationButtonText }
+		</Button>
+	);
+};
+
+const CancelMigrationModal = ( {
+	closeModal,
+	handleCancelMigration,
+	siteId,
+	isMigrationInProgress,
+}: {
+	closeModal: () => void;
+	handleCancelMigration: ( siteId: number ) => void;
+	siteId: number;
+	isMigrationInProgress: boolean;
+} ) => {
+	const translate = useTranslate();
+
+	const modalTitle = ! isMigrationInProgress
+		? translate( 'Cancel migration' )
+		: translate( 'Request migration cancellation' );
+
+	const modalContent = ! isMigrationInProgress
+		? translate(
+				"If you cancel now, our Happiness Engineers will be notified that you've chosen not to move your site to WordPress.com, and your current site will remain exactly as it is."
+		  )
+		: translate(
+				"Since your migration is already underway, you'll need to send us a cancellation request. If you cancel now, you'll lose all your progress."
+		  );
+
+	return (
+		<Modal
+			className="migration-started-difm__cancel-dialog"
+			title={ modalTitle }
+			onRequestClose={ closeModal }
+			size="medium"
+		>
+			<p>{ modalContent }</p>
+			<div className="migration-started-difm__cancel-dialog-buttons">
+				<Button key="cancel" variant="secondary" onClick={ () => closeModal() }>
+					{ translate( "Don't cancel migration" ) }
+				</Button>
+				<CancelMigrationButton
+					key="send"
+					variant="primary"
+					isMigrationInProgress={ isMigrationInProgress }
+					onClick={ () => handleCancelMigration( siteId ) }
+					buttonType="confirm"
+				/>
+			</div>
+		</Modal>
+	);
+};
+
 const CancelDifmMigrationForm = ( { siteId }: { siteId: number } ) => {
 	const translate = useTranslate();
 	const dispatch = useDispatch();
+	const { data: stickers = [] } = useBlogStickersQuery( siteId );
 	const [ isOpen, setOpen ] = useState( false );
 	const openModal = () => setOpen( true );
 	const closeModal = () => setOpen( false );
@@ -21,6 +111,8 @@ const CancelDifmMigrationForm = ( { siteId }: { siteId: number } ) => {
 		return null;
 	}
 
+	const isMigrationInProgress = stickers.includes( 'migration-in-progress' );
+
 	const handleSendCancellationRequest = async ( siteId: number ) => {
 		try {
 			return await wp.req.post( {
@@ -50,9 +142,13 @@ const CancelDifmMigrationForm = ( { siteId }: { siteId: number } ) => {
 			return;
 		}
 
+		const cancellationSuccessMessage = isMigrationInProgress
+			? translate( 'Migration cancellation request sent.' )
+			: translate( 'Migration cancelled.' );
+
 		setCancellationStatus( 'success' );
 		dispatch(
-			successNotice( translate( 'Migration cancellation request sent.' ), {
+			successNotice( cancellationSuccessMessage, {
 				duration: 5000,
 			} )
 		);
@@ -64,37 +160,20 @@ const CancelDifmMigrationForm = ( { siteId }: { siteId: number } ) => {
 				<LoadingBar className="migration-started-difm__cancel-loading-bar" progress={ 0.5 } />
 			) }
 			{ cancellationStatus === null && (
-				<Button
+				<CancelMigrationButton
+					isMigrationInProgress={ isMigrationInProgress }
+					onClick={ openModal }
+					buttonType="cta"
 					variant="link"
-					onClick={ ( e: React.MouseEvent< HTMLButtonElement > ) => {
-						e.preventDefault();
-						openModal();
-					} }
-				>
-					{ translate( 'Request cancellation' ) }
-				</Button>
+				/>
 			) }
 			{ isOpen && (
-				<Modal
-					className="migration-started-difm__cancel-dialog"
-					title={ translate( 'Request migration cancellation' ) }
-					onRequestClose={ closeModal }
-					size="medium"
-				>
-					<p>
-						{ translate(
-							"Since your migration is already underway, you'll need to send us a cancellation request. If you cancel now, you'll lose all your progress."
-						) }
-					</p>
-					<div className="migration-started-difm__cancel-dialog-buttons">
-						<Button key="cancel" variant="secondary" onClick={ () => closeModal() }>
-							{ translate( "Don't cancel migration" ) }
-						</Button>
-						<Button key="send" variant="primary" onClick={ () => handleCancelMigration( siteId ) }>
-							{ translate( 'Send request' ) }
-						</Button>
-					</div>
-				</Modal>
+				<CancelMigrationModal
+					closeModal={ closeModal }
+					handleCancelMigration={ handleCancelMigration }
+					siteId={ siteId }
+					isMigrationInProgress={ isMigrationInProgress }
+				/>
 			) }
 		</div>
 	);
diff --git a/client/sites/overview/components/migration-overview/components/cancel-difm-migration/test/index.tsx b/client/sites/overview/components/migration-overview/components/cancel-difm-migration/test/index.tsx
index 8bf473326d41..e9eee7e02b55 100644
--- a/client/sites/overview/components/migration-overview/components/cancel-difm-migration/test/index.tsx
+++ b/client/sites/overview/components/migration-overview/components/cancel-difm-migration/test/index.tsx
@@ -23,32 +23,77 @@ jest.mock( 'calypso/lib/wp', () => ( {
 	},
 } ) );
 
+jest.mock( 'calypso/blocks/blog-stickers/use-blog-stickers-query', () => ( {
+	useBlogStickersQuery: jest.fn(),
+} ) );
+
 describe( 'CancelDifmMigrationForm', () => {
 	const siteId = 123;
 	const isEnabled = jest.requireMock( '@automattic/calypso-config' ).isEnabled;
+	const useBlogStickersQuery = jest.requireMock(
+		'calypso/blocks/blog-stickers/use-blog-stickers-query'
+	).useBlogStickersQuery;
 
 	beforeEach( () => {
 		nock.cleanAll();
 		jest.clearAllMocks();
 		isEnabled.mockReturnValue( true );
+		useBlogStickersQuery.mockReturnValue( { data: [] } );
 	} );
 
 	it( 'renders nothing if feature flag is disabled', () => {
 		isEnabled.mockReturnValue( false );
 		renderWithProvider( <CancelDifmMigrationForm siteId={ siteId } /> );
-		expect( screen.queryByRole( 'button', { name: /request cancellation/i } ) ).toBeNull();
+		expect( screen.queryByRole( 'button', { name: /cancel migration/i } ) ).toBeNull();
 	} );
 
-	it( 'opens dialog on button click', async () => {
-		renderWithProvider( <CancelDifmMigrationForm siteId={ siteId } /> );
-		await userEvent.click( screen.getByRole( 'button', { name: /request cancellation/i } ) );
-		expect( screen.getByRole( 'dialog' ) ).toBeVisible();
-		expect( screen.getByText( /request migration cancellation/i ) ).toBeVisible();
+	describe( 'when migration is not in progress', () => {
+		beforeEach( () => {
+			useBlogStickersQuery.mockReturnValue( { data: [] } );
+		} );
+
+		it( 'shows cancel migration button', () => {
+			renderWithProvider( <CancelDifmMigrationForm siteId={ siteId } /> );
+			expect( screen.getByRole( 'button', { name: /cancel migration/i } ) ).toBeVisible();
+		} );
+
+		it( 'opens dialog with cancel migration content', async () => {
+			renderWithProvider( <CancelDifmMigrationForm siteId={ siteId } /> );
+			await userEvent.click( screen.getByRole( 'button', { name: /cancel migration/i } ) );
+			expect( screen.getByRole( 'dialog' ) ).toBeVisible();
+			expect( screen.getByRole( 'heading', { name: /cancel migration/i } ) ).toBeVisible();
+			expect( screen.getByText( /our Happiness Engineers will be notified/i ) ).toBeVisible();
+		} );
+	} );
+
+	describe( 'when migration is in progress', () => {
+		beforeEach( () => {
+			useBlogStickersQuery.mockReturnValue( { data: [ 'migration-in-progress' ] } );
+		} );
+
+		it( 'shows request cancellation button', () => {
+			renderWithProvider( <CancelDifmMigrationForm siteId={ siteId } /> );
+			expect(
+				screen.getByRole( 'button', { name: /request migration cancellation/i } )
+			).toBeVisible();
+		} );
+
+		it( 'opens dialog with request cancellation content', async () => {
+			renderWithProvider( <CancelDifmMigrationForm siteId={ siteId } /> );
+			await userEvent.click(
+				screen.getByRole( 'button', { name: /request migration cancellation/i } )
+			);
+			expect( screen.getByRole( 'dialog' ) ).toBeVisible();
+			expect(
+				screen.getByRole( 'heading', { name: /request migration cancellation/i } )
+			).toBeVisible();
+			expect( screen.getByText( /you'll lose all your progress/i ) ).toBeVisible();
+		} );
 	} );
 
 	it( 'closes dialog on cancel', async () => {
 		renderWithProvider( <CancelDifmMigrationForm siteId={ siteId } /> );
-		await userEvent.click( screen.getByRole( 'button', { name: /request cancellation/i } ) );
+		await userEvent.click( screen.getByRole( 'button', { name: /cancel migration/i } ) );
 		await userEvent.click( screen.getByRole( 'button', { name: /don't cancel migration/i } ) );
 		await waitFor( () => {
 			expect( screen.queryByRole( 'dialog' ) ).toBeNull();
diff --git a/client/sites/overview/components/style.scss b/client/sites/overview/components/style.scss
index 89aaac4c2324..1141fa7d62a7 100644
--- a/client/sites/overview/components/style.scss
+++ b/client/sites/overview/components/style.scss
@@ -133,6 +133,20 @@ $blueberry-color: #3858e9;
 		}
 	}
 
+	&__navigation-header {
+		margin-bottom: 24px;
+	}
+
+	&__blog-stickers {
+		margin: 0 0 24px;
+		padding: 16px;
+		background-color: var(--color-surface);
+		border: 1px solid var(--color-border-subtle);
+		border-radius: 4px;
+		font-size: 14px;
+		color: var(--color-text-subtle);
+	}
+
 }
 
 .hosting-overview__domain-to-plan-credit-notice {
@@ -140,14 +154,6 @@ $blueberry-color: #3858e9;
 	text-wrap: pretty;
 }
 
-.hosting-overview__navigation-header {
-	grid-column: 1 / -1;
-
-	&.navigation-header {
-		margin-bottom: 16px;
-	}
-}
-
 .hosting-overview__navigation-header,
 .hosting-overview__active-domains {
 	grid-column: 1 / -1;


Reviews:
user: login: fditrapani
body: Thanks for the update Mark. Looks good from the screenshot!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T19:15:51Z
user: login: valterlorran
body: Don't forget to remove the a8c gate in the back-end before deploying this change.
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T18:25:32Z
user: login: markbiek
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T18:37:41Z
user: login: markbiek
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T18:53:38Z
user: login: valterlorran
body: LGTM! Thanks for addressing the feedback!

state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T18:25:33Z

Review comments:
diff_hunk: @@ -36,6 +38,11 @@ const HostingOverview: FC = () => {
 				title={ translate( 'Overview' ) }
 				subtitle={ subtitle }
 			/>
+			{ stickers.length > 0 && (
+				<div className="hosting-overview__blog-stickers">
+					{ translate( 'Blog Stickers: %s', { args: stickers.join( ', ' ) } ) }
+				</div>
+			) }
path: client/sites/overview/components/hosting-overview.tsx
user: login: valterlorran
body: Was this a test, or do we really intend to add the stickers in the overview?

![Captura de Tela 2025-05-16 às 15 15 33](https://github.com/user-attachments/assets/bec06918-5c2d-465b-ab4f-58e550c0fa77)

created_at: 2025-05-16T18:16:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -3,13 +3,90 @@ import { Modal, Button } from '@wordpress/components';
 import { useTranslate } from 'i18n-calypso';
 import { useState } from 'react';
 import { useDispatch } from 'react-redux';
+import { useBlogStickersQuery } from 'calypso/blocks/blog-stickers/use-blog-stickers-query';
 import { LoadingBar } from 'calypso/components/loading-bar';
 import wp from 'calypso/lib/wp';
 import { successNotice, errorNotice } from 'calypso/state/notices/actions';
 
+const CancelMigrationButton = ( {
+	isMigrationInProgress,
+	onClick,
+}: {
+	isMigrationInProgress: boolean;
+	onClick: () => void;
+} ) => {
+	const translate = useTranslate();
+
+	const cancelMigrationButtonText = ! isMigrationInProgress
+		? translate( 'Cancel migration' )
+		: translate( 'Request migration cancellation' );
+
+	return (
+		<Button
+			variant="link"
+			onClick={ ( e: React.MouseEvent< HTMLButtonElement > ) => {
+				e.preventDefault();
+				onClick();
+			} }
+		>
+			{ cancelMigrationButtonText }
+		</Button>
+	);
+};
+
+const CancelMigrationModal = ( {
+	closeModal,
+	handleCancelMigration,
+	siteId,
+	isMigrationInProgress,
+}: {
+	closeModal: () => void;
+	handleCancelMigration: ( siteId: number ) => void;
+	siteId: number;
+	isMigrationInProgress: boolean;
+} ) => {
+	const translate = useTranslate();
+
+	const modalTitle = ! isMigrationInProgress
+		? translate( 'Cancel migration' )
+		: translate( 'Request migration cancellation' );
+
+	const cancelButtonText = ! isMigrationInProgress
+		? translate( 'Cancel migration' )
+		: translate( 'Send request' );
+
+	const modalContent = ! isMigrationInProgress
+		? translate(
+				'If you cancel now, our Happiness Engineers will be notified that you’ve chosen not to move your site to WordPress.com, and your current site will remain exactly as it is.'
+		  )
+		: translate(
+				"Since your migration is already underway, you'll need to send us a cancellation request. If you cancel now, you'll lose all your progress."
+		  );
+
+	return (
+		<Modal
+			className="migration-started-difm__cancel-dialog"
+			title={ modalTitle }
+			onRequestClose={ closeModal }
+			size="medium"
+		>
+			<p>{ modalContent }</p>
+			<div className="migration-started-difm__cancel-dialog-buttons">
+				<Button key="cancel" variant="secondary" onClick={ () => closeModal() }>
+					{ translate( "Don't cancel migration" ) }
+				</Button>
+				<Button key="send" variant="primary" onClick={ () => handleCancelMigration( siteId ) }>
+					{ cancelButtonText }
+				</Button>
path: client/sites/overview/components/migration-overview/components/cancel-difm-migration/index.tsx
user: login: valterlorran
body: Would it be possible to use the CancelMigrationButton component to avoid repeating(almost) the button text?
created_at: 2025-05-16T18:19:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -36,6 +38,11 @@ const HostingOverview: FC = () => {
 				title={ translate( 'Overview' ) }
 				subtitle={ subtitle }
 			/>
+			{ stickers.length > 0 && (
+				<div className="hosting-overview__blog-stickers">
+					{ translate( 'Blog Stickers: %s', { args: stickers.join( ', ' ) } ) }
+				</div>
+			) }
path: client/sites/overview/components/hosting-overview.tsx
user: login: markbiek
body: That was a test that I forgot to remove. Thanks!
created_at: 2025-05-16T18:37:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -3,13 +3,90 @@ import { Modal, Button } from '@wordpress/components';
 import { useTranslate } from 'i18n-calypso';
 import { useState } from 'react';
 import { useDispatch } from 'react-redux';
+import { useBlogStickersQuery } from 'calypso/blocks/blog-stickers/use-blog-stickers-query';
 import { LoadingBar } from 'calypso/components/loading-bar';
 import wp from 'calypso/lib/wp';
 import { successNotice, errorNotice } from 'calypso/state/notices/actions';
 
+const CancelMigrationButton = ( {
+	isMigrationInProgress,
+	onClick,
+}: {
+	isMigrationInProgress: boolean;
+	onClick: () => void;
+} ) => {
+	const translate = useTranslate();
+
+	const cancelMigrationButtonText = ! isMigrationInProgress
+		? translate( 'Cancel migration' )
+		: translate( 'Request migration cancellation' );
+
+	return (
+		<Button
+			variant="link"
+			onClick={ ( e: React.MouseEvent< HTMLButtonElement > ) => {
+				e.preventDefault();
+				onClick();
+			} }
+		>
+			{ cancelMigrationButtonText }
+		</Button>
+	);
+};
+
+const CancelMigrationModal = ( {
+	closeModal,
+	handleCancelMigration,
+	siteId,
+	isMigrationInProgress,
+}: {
+	closeModal: () => void;
+	handleCancelMigration: ( siteId: number ) => void;
+	siteId: number;
+	isMigrationInProgress: boolean;
+} ) => {
+	const translate = useTranslate();
+
+	const modalTitle = ! isMigrationInProgress
+		? translate( 'Cancel migration' )
+		: translate( 'Request migration cancellation' );
+
+	const cancelButtonText = ! isMigrationInProgress
+		? translate( 'Cancel migration' )
+		: translate( 'Send request' );
+
+	const modalContent = ! isMigrationInProgress
+		? translate(
+				'If you cancel now, our Happiness Engineers will be notified that you’ve chosen not to move your site to WordPress.com, and your current site will remain exactly as it is.'
+		  )
+		: translate(
+				"Since your migration is already underway, you'll need to send us a cancellation request. If you cancel now, you'll lose all your progress."
+		  );
+
+	return (
+		<Modal
+			className="migration-started-difm__cancel-dialog"
+			title={ modalTitle }
+			onRequestClose={ closeModal }
+			size="medium"
+		>
+			<p>{ modalContent }</p>
+			<div className="migration-started-difm__cancel-dialog-buttons">
+				<Button key="cancel" variant="secondary" onClick={ () => closeModal() }>
+					{ translate( "Don't cancel migration" ) }
+				</Button>
+				<Button key="send" variant="primary" onClick={ () => handleCancelMigration( siteId ) }>
+					{ cancelButtonText }
+				</Button>
path: client/sites/overview/components/migration-overview/components/cancel-difm-migration/index.tsx
user: login: markbiek
body: That's a good thought. I'll see if I can clean that up.
created_at: 2025-05-16T18:53:38Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-13T18:36:28Z
body: <details>
<summary>Calypso Live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144856">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-144856%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144856">https://calypso.live?image=registry.a8c.com/calypso/app:build-144856</a>
</td>
</tr>
</table>
</details>
<details>
<summary>Jetpack Cloud live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144856&env=jetpack">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-144856%26env%3Djetpack%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144856&env=jetpack">https://calypso.live?image=registry.a8c.com/calypso/app:build-144856&env=jetpack</a>
</td>
</tr>
</table>
</details>
<details>
<summary>Automattic for Agencies live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144856&env=a8c-for-agencies">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-144856%26env%3Da8c-for-agencies%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144856&env=a8c-for-agencies">https://calypso.live?image=registry.a8c.com/calypso/app:build-144856&env=a8c-for-agencies</a>
</td>
</tr>
</table>
</details>
<!--calypso-live-watermark:apr@v1-->
author_association: NONE
user: login: matticbot
created_at: 2025-05-13T18:39:14Z
body: <!-- icfy-watermark: c52822 -->
Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

**Sections** (~396 bytes added 📈 [gzipped])
<details>

```
name      parsed_size           gzip_size
overview      +1479 B  (+0.1%)     +396 B  (+0.1%)
```

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.
</details>

**Legend**
<details>
<summary>What is parsed and gzip size?</summary>

**Parsed Size:** Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
**Gzip Size:** Compressed size of the JS and CSS files. This much data needs to be downloaded over network.
</details>

Generated by performance advisor bot at [iscalypsofastyet.com](http://iscalypsofastyet.com).
author_association: CONTRIBUTOR
user: login: a8ci18n
created_at: 2025-05-13T19:25:19Z
body: This Pull Request is now available for translation here: https://translate.wordpress.com/deliverables/17467380

Some locales (Brazilian Portuguese, Hebrew) have been temporarily machine-translated due to translator availability. All other translations are usually ready within a few days. Untranslated and machine-translated strings will be sent for translation next Monday and are expected to be completed by the following Friday.

Thank you @markbiek for including a screenshot in the description! This is really helpful for our translators.
author_association: NONE
user: login: markbiek
created_at: 2025-05-16T18:38:42Z
body: > Don't forget to remove the a8c gate in the back-end before deploying this change.

The Calypso piece is still behind the `migration-flow/cancel-difm` flag. I was planning to remove the backend gate and update the flag after this PR is deployed.
author_association: CONTRIBUTOR
user: login: matticbot
created_at: 2025-05-16T20:45:13Z
body: **This PR modifies the release build for the following Calypso Apps:**

_For info about this notification, see here: PCYsg-OT6-p2_

* help-center
* notifications
* wpcom-block-editor

To test WordPress.com changes, run `install-plugin.sh $pluginSlug DOTCON-26/tweak-difm-cancellation` on your sandbox.
<!--calypso-app-artifacts-watermark:apr@v1-->
author_association: CONTRIBUTOR
user: login: a8ci18n
created_at: 2025-05-18T21:29:25Z
body: Translation for this Pull Request [has now been finished](https://translate.wordpress.com/deliverables/overview/17467380).
author_association: NONE