diff --git a/client/components/jetpack/daily-backup-status/status-card/backup-realtime-message.tsx b/client/components/jetpack/daily-backup-status/status-card/backup-realtime-message.tsx
index e433328d3eaa9..bd612c782af40 100644
--- a/client/components/jetpack/daily-backup-status/status-card/backup-realtime-message.tsx
+++ b/client/components/jetpack/daily-backup-status/status-card/backup-realtime-message.tsx
@@ -1,21 +1,31 @@
+import { useCallback } from '@wordpress/element';
import { useTranslate } from 'i18n-calypso';
import { FunctionComponent } from 'react';
import { useLocalizedMoment } from 'calypso/components/localized-moment';
+import { useDispatch } from 'calypso/state';
+import { recordTracksEvent } from 'calypso/state/analytics/actions/record';
import type { Moment } from 'moment';
type Props = {
baseBackupDate: Moment;
eventsCount: number;
selectedBackupDate: Moment;
+ learnMoreUrl?: string;
};
export const BackupRealtimeMessage: FunctionComponent< Props > = ( {
baseBackupDate,
eventsCount,
selectedBackupDate,
+ learnMoreUrl,
} ) => {
const translate = useTranslate();
const moment = useLocalizedMoment();
+ const dispatch = useDispatch();
+
+ const onLearnMoreClick = useCallback( () => {
+ dispatch( recordTracksEvent( 'calypso_jetpack_backup_realtime_message_learn_more_click' ) );
+ }, [ dispatch ] );
if (
! moment.isMoment( baseBackupDate ) ||
@@ -76,5 +86,17 @@ export const BackupRealtimeMessage: FunctionComponent< Props > = ( {
);
}
- return <>{ message }>;
+ return (
+
+ { message }
+ { learnMoreUrl && (
+ <>
+ { ' ' }
+
+ { translate( 'Learn more' ) }
+
+ >
+ ) }
+
+ );
};
diff --git a/client/components/jetpack/daily-backup-status/test/backup-realtime-message.jsx b/client/components/jetpack/daily-backup-status/test/backup-realtime-message.jsx
index b1d1488a38b12..5989d3db6ccb8 100644
--- a/client/components/jetpack/daily-backup-status/test/backup-realtime-message.jsx
+++ b/client/components/jetpack/daily-backup-status/test/backup-realtime-message.jsx
@@ -4,33 +4,40 @@
import { render } from '@testing-library/react';
import { useTranslate } from 'i18n-calypso';
import moment from 'moment';
+import { useDispatch } from 'calypso/state';
import { BackupRealtimeMessage } from '../status-card/backup-realtime-message';
-// Mock the useTranslate function
-jest.mock( 'i18n-calypso' );
+jest.mock( 'i18n-calypso' ); // Mock the useTranslate hook
+jest.mock( 'calypso/state' ); // Mock the useDispatch hook
describe( 'BackupRealtimeMessage', () => {
- const renderMessage = ( baseBackupDate, eventsCount, selectedDate ) => {
+ const renderMessage = ( baseBackupDate, eventsCount, selectedDate, learnMoreUrl ) => {
return render(
);
};
- const translateMock = jest.fn( ( singular, plural, { count, args } ) => {
- const translatedText = count === 1 ? singular : plural;
+ const translateMock = jest.fn( ( singular, plural, options ) => {
+ if ( options === undefined ) {
+ return singular;
+ }
+
+ const translatedText = options.count === 1 ? singular : plural;
return translatedText
- .replace( '%(baseBackupDate)s', args.baseBackupDate )
- .replace( '%(eventsCount)d', args.eventsCount )
- .replace( '%(daysAgo)d', args.daysAgo );
+ .replace( '%(baseBackupDate)s', options.args.baseBackupDate )
+ .replace( '%(eventsCount)d', options.args.eventsCount )
+ .replace( '%(daysAgo)d', options.args.daysAgo );
} );
beforeEach( () => {
jest.clearAllMocks();
useTranslate.mockImplementation( () => translateMock );
+ useDispatch.mockImplementation( () => jest.fn() );
} );
test( 'renders the correct message when the base backup date is the same as the selected backup date', () => {
@@ -77,4 +84,24 @@ describe( 'BackupRealtimeMessage', () => {
`We are using a full backup from this day (2024-08-26 12:00 PM) with 2 changes you have made since then until now.`
);
} );
+
+ test( 'renders the correct message and the "Learn more" link when learnMoreUrl is provided', () => {
+ useTranslate.mockImplementation( () => translateMock );
+
+ const selectedDate = moment( '2024-08-26T12:00:00Z' );
+ const baseBackupDate = moment( '2024-08-26T12:00:00Z' );
+ const learnMoreUrl = '/learn-more';
+
+ const { container, getByText } = renderMessage( baseBackupDate, 3, selectedDate, learnMoreUrl );
+
+ // Verify the message content
+ expect( container.textContent ).toContain(
+ 'We are using a full backup from this day (2024-08-26 12:00 PM) with 3 changes you have made since then until now.'
+ );
+
+ // Verify the `Learn more` link is rendered
+ const learnMoreLink = getByText( 'Learn more' );
+ expect( learnMoreLink ).toBeInTheDocument();
+ expect( learnMoreLink.getAttribute( 'href' ) ).toBe( learnMoreUrl );
+ } );
} );
diff --git a/client/my-sites/backup/rewind-flow/index.tsx b/client/my-sites/backup/rewind-flow/index.tsx
index fbf0a39ab60e3..418b3b47a83ec 100644
--- a/client/my-sites/backup/rewind-flow/index.tsx
+++ b/client/my-sites/backup/rewind-flow/index.tsx
@@ -99,6 +99,7 @@ const BackupRewindFlow: FunctionComponent< Props > = ( { rewindId, purpose } ) =
if ( purpose === RewindFlowPurpose.RESTORE ) {
return (
= ( {
+ backup,
backupDisplayDate,
rewindId,
siteId,
@@ -62,6 +66,7 @@ const BackupRestoreFlow: FunctionComponent< Props > = ( {
} ) => {
const dispatch = useDispatch();
const translate = useTranslate();
+ const moment = useLocalizedMoment();
const [ rewindConfig, setRewindConfig ] = useState< RewindConfig >( defaultRewindConfig );
@@ -223,6 +228,10 @@ const BackupRestoreFlow: FunctionComponent< Props > = ( {
( ! isAtomic && areCredentialsInvalid ) ||
Object.values( rewindConfig ).every( ( setting ) => ! setting );
+ const selectedDate = moment( rewindId, 'X' );
+ const baseBackupDate = backup.baseRewindId ? moment.unix( backup.baseRewindId ) : null;
+ const showRealTimeMessage = backup.baseRewindId && baseBackupDate && backup.rewindStepCount > 0;
+
const renderConfirm = () => (
<>
{ ! isAtomic && }
@@ -240,6 +249,13 @@ const BackupRestoreFlow: FunctionComponent< Props > = ( {
},
} ) }
+ { config.isEnabled( 'jetpack/backup-realtime-message' ) && showRealTimeMessage && (
+
+ ) }
{ translate( 'Choose the items you wish to restore:' ) }