-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Jetpack Backup: i4 backup states (#46543)
Co-authored-by: Kevin Zoschke <kevin.zoschke@automattic.com>
- Loading branch information
1 parent
1fcdda8
commit 7bf8123
Showing
10 changed files
with
548 additions
and
21 deletions.
There are no files selected for viewing
115 changes: 115 additions & 0 deletions
115
client/components/jetpack/backup-card/backup-failed.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import React, { FunctionComponent } from 'react'; | ||
import { useSelector } from 'react-redux'; | ||
import classNames from 'classnames'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { applySiteOffset } from 'calypso/lib/site/timezone'; | ||
import { Button } from '@automattic/components'; | ||
import { Card } from '@automattic/components'; | ||
import { getSelectedSiteId } from 'calypso/state/ui/selectors'; | ||
import { useTranslate } from 'i18n-calypso'; | ||
import ActivityDescription from 'calypso/components/activity-card/activity-description'; | ||
import contactSupportUrl from 'calypso/lib/jetpack/contact-support-url'; | ||
import getSiteTimezoneValue from 'calypso/state/selectors/get-site-timezone-value'; | ||
import getSiteGmtOffset from 'calypso/state/selectors/get-site-gmt-offset'; | ||
import getSiteUrl from 'calypso/state/sites/selectors/get-site-url'; | ||
import JetpackLogo from 'calypso/components/jetpack-logo'; | ||
|
||
/** | ||
* Style dependencies | ||
*/ | ||
import './style.scss'; | ||
import cloudErrorIcon from 'calypso/components/jetpack/daily-backup-status/status-card/icons/cloud-error.svg'; | ||
|
||
/** | ||
* Type dependencies | ||
*/ | ||
import type { Activity } from 'calypso/state/activity-log/types'; | ||
|
||
type Props = { backup: Activity; isFeatured: boolean }; | ||
|
||
const BackupFailed: FunctionComponent< Props > = ( { backup, isFeatured } ) => { | ||
const translate = useTranslate(); | ||
const siteId = useSelector( ( state ) => getSelectedSiteId( state ) ) || -1; | ||
const siteUrl = useSelector( ( state ) => getSiteUrl( state, siteId ) ); | ||
|
||
const timezone = useSelector( ( state ) => getSiteTimezoneValue( state, siteId ) ); | ||
const gmtOffset = useSelector( ( state ) => getSiteGmtOffset( state, siteId ) ); | ||
|
||
const backupDate = applySiteOffset( backup.activityTs, { timezone, gmtOffset } ); | ||
|
||
const displayDate = backupDate.format( 'MMM Do' ); | ||
const displayTime = backupDate.format( 'H:mma' ); | ||
|
||
return ( | ||
<Card | ||
className={ classNames( 'backup-card', { | ||
'is-featured': isFeatured, | ||
} ) } | ||
> | ||
<div className="backup-card__main"> | ||
<div className="backup-card__header"> | ||
<div className="backup-card__header-text"> | ||
<h2 className="backup-card__date">{ translate( 'Backup failed' ) }</h2> | ||
<p className="backup-card__title backup-card__title--failed"> | ||
<img className="backup-card__icon" src={ cloudErrorIcon } alt="" /> | ||
{ translate( 'Backup attempted on %(displayDate)s, %(displayTime)s and failed', { | ||
args: { displayDate, displayTime }, | ||
} ) } | ||
</p> | ||
</div> | ||
</div> | ||
<ul className="backup-card__actions"> | ||
<li> | ||
<Button | ||
className="backup-card__support-button" | ||
href="https://jetpack.com/support/backup/" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
primary | ||
> | ||
{ translate( 'Read the support guide' ) } | ||
</Button> | ||
</li> | ||
<li> | ||
<Button | ||
className="backup-card__support-button" | ||
href={ contactSupportUrl( siteUrl ) } | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
{ translate( 'Contact support' ) } | ||
</Button> | ||
</li> | ||
</ul> | ||
</div> | ||
<div className="backup-card__about"> | ||
<h3 className="backup-card__about-heading">{ translate( 'About this backup' ) }</h3> | ||
<div className="backup-card__about-content"> | ||
<ul className="backup-card__about-list"> | ||
<li> | ||
<div className="backup-card__about-media backup-card__about-media--notice"> | ||
<JetpackLogo className="backup-card__jetpack-logo-danger" size={ 32 } /> | ||
</div> | ||
<div className="backup-card__about-body"> | ||
{ translate( | ||
'Jetpack failed to complete the backup. Jetpack returned the following error:' | ||
) } | ||
<div> | ||
<ActivityDescription activity={ backup } /> | ||
</div> | ||
</div> | ||
</li> | ||
</ul> | ||
</div> | ||
</div> | ||
</Card> | ||
); | ||
}; | ||
|
||
export default BackupFailed; |
131 changes: 131 additions & 0 deletions
131
client/components/jetpack/backup-card/backup-scheduled.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import classNames from 'classnames'; | ||
import React, { FunctionComponent } from 'react'; | ||
import { useSelector } from 'react-redux'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { Button } from '@automattic/components'; | ||
import { backupMainPath } from 'calypso/my-sites/backup/paths'; | ||
import { Card } from '@automattic/components'; | ||
import { useTranslate } from 'i18n-calypso'; | ||
import { INDEX_FORMAT } from 'calypso/lib/jetpack/backup-utils'; | ||
import { applySiteOffset } from 'calypso/lib/site/timezone'; | ||
import { useLocalizedMoment } from 'calypso/components/localized-moment'; | ||
import { getSelectedSiteId, getSelectedSiteSlug } from 'calypso/state/ui/selectors'; | ||
import getSiteTimezoneValue from 'calypso/state/selectors/get-site-timezone-value'; | ||
import getSiteGmtOffset from 'calypso/state/selectors/get-site-gmt-offset'; | ||
import JetpackLogo from 'calypso/components/jetpack-logo'; | ||
/** | ||
* Style dependencies | ||
*/ | ||
import './style.scss'; | ||
import cloudScheduleIcon from 'calypso/components/jetpack/daily-backup-status/status-card/icons/cloud-schedule.svg'; | ||
|
||
/** | ||
* Type dependencies | ||
*/ | ||
import type { Moment } from 'moment'; | ||
|
||
type Props = { lastBackupDate: Moment; isFeatured: boolean }; | ||
|
||
const BackupScheduled: FunctionComponent< Props > = ( { lastBackupDate, isFeatured } ) => { | ||
const translate = useTranslate(); | ||
const siteId = useSelector( ( state ) => getSelectedSiteId( state ) ) || -1; | ||
const siteSlug = useSelector( ( state ) => getSelectedSiteSlug( state ) ) || ''; | ||
|
||
const timezone = useSelector( ( state ) => getSiteTimezoneValue( state, siteId ) ); | ||
const gmtOffset = useSelector( ( state ) => getSiteGmtOffset( state, siteId ) ); | ||
const moment = useLocalizedMoment(); | ||
|
||
const today = applySiteOffset( moment(), { | ||
timezone: timezone, | ||
gmtOffset: gmtOffset, | ||
} ); | ||
|
||
const yesterday = moment( today ).subtract( 1, 'days' ); | ||
|
||
const lastBackupDay = lastBackupDate.isSame( yesterday, 'day' ) | ||
? translate( 'Yesterday ' ) | ||
: lastBackupDate.format( 'll' ); | ||
|
||
const lastBackupTime = lastBackupDate.format( 'H:mma' ); | ||
|
||
// Calculates the remaining hours for the next backup + 3 hours of safety margin | ||
const DAY_HOURS = 24; | ||
const hoursForNextBackup = DAY_HOURS - today.diff( lastBackupDate, 'hours' ) + 3; | ||
|
||
const nextBackupHoursText = | ||
hoursForNextBackup <= 1 | ||
? translate( 'In the next hour' ) | ||
: translate( 'In the next %d hour', 'In the next %d hours', { | ||
args: [ hoursForNextBackup ], | ||
count: hoursForNextBackup, | ||
} ); | ||
|
||
return ( | ||
<Card | ||
className={ classNames( 'backup-card', { | ||
'is-featured': isFeatured, | ||
} ) } | ||
> | ||
<div className="backup-card__main"> | ||
<div className="backup-card__header"> | ||
<div className="backup-card__header-text"> | ||
<h2 className="backup-card__date">{ nextBackupHoursText }</h2> | ||
<p className="backup-card__title backup-card__title--scheduled"> | ||
<img className="backup-card__icon" src={ cloudScheduleIcon } alt="" /> | ||
{ translate( 'Your next backup has been scheduled' ) } | ||
</p> | ||
</div> | ||
</div> | ||
<ul className="backup-card__actions"> | ||
<li> | ||
<Button className="backup-card__restore-button" primary disabled> | ||
{ translate( 'Restore to this point' ) } | ||
</Button> | ||
</li> | ||
<li> | ||
<Button className="backup-card__download-button" disabled> | ||
{ translate( 'Download backup' ) } | ||
</Button> | ||
</li> | ||
</ul> | ||
</div> | ||
<div className="backup-card__about"> | ||
<h3 className="backup-card__about-heading">{ translate( 'About this backup' ) }</h3> | ||
<div className="backup-card__about-content"> | ||
<ul className="backup-card__about-list"> | ||
<li> | ||
<div className="backup-card__about-media backup-card__about-media--notice"> | ||
<JetpackLogo className="backup-card__jetpack-logo-muted" size={ 32 } /> | ||
</div> | ||
<div className="backup-card__about-body"> | ||
{ translate( | ||
'Jetpack has scheduled your next backup. {{link}}Your last backup was %(lastBackupDay)s %(lastBackupTime)s{{/link}}', | ||
{ | ||
args: { lastBackupDay, lastBackupTime }, | ||
components: { | ||
link: ( | ||
<a | ||
href={ backupMainPath( siteSlug, { | ||
date: lastBackupDate.format( INDEX_FORMAT ), | ||
} ) } | ||
/> | ||
), | ||
}, | ||
} | ||
) } | ||
</div> | ||
</li> | ||
</ul> | ||
</div> | ||
</div> | ||
</Card> | ||
); | ||
}; | ||
|
||
export default BackupScheduled; |
111 changes: 111 additions & 0 deletions
111
client/components/jetpack/backup-card/no-backups-on-selected-date.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import React, { FunctionComponent } from 'react'; | ||
import { useSelector } from 'react-redux'; | ||
import classNames from 'classnames'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { Button } from '@automattic/components'; | ||
import { backupMainPath } from 'calypso/my-sites/backup/paths'; | ||
import { Card } from '@automattic/components'; | ||
import { useTranslate } from 'i18n-calypso'; | ||
import { INDEX_FORMAT } from 'calypso/lib/jetpack/backup-utils'; | ||
import { getSelectedSiteId, getSelectedSiteSlug } from 'calypso/state/ui/selectors'; | ||
import contactSupportUrl from 'calypso/lib/jetpack/contact-support-url'; | ||
import getSiteUrl from 'calypso/state/sites/selectors/get-site-url'; | ||
import JetpackLogo from 'calypso/components/jetpack-logo'; | ||
/** | ||
* Style dependencies | ||
*/ | ||
import './style.scss'; | ||
import cloudWarningIcon from 'calypso/components/jetpack/daily-backup-status/status-card/icons/cloud-warning-orange-30.svg'; | ||
|
||
/** | ||
* Type dependencies | ||
*/ | ||
import type { Moment } from 'moment'; | ||
|
||
type Props = { selectedDate: Moment; isFeatured: boolean }; | ||
|
||
const NoBackupsOnSelectedDate: FunctionComponent< Props > = ( { selectedDate, isFeatured } ) => { | ||
const translate = useTranslate(); | ||
const siteId = useSelector( ( state ) => getSelectedSiteId( state ) ) || -1; | ||
const siteSlug = useSelector( ( state ) => getSelectedSiteSlug( state ) ) || ''; | ||
const siteUrl = useSelector( ( state ) => getSiteUrl( state, siteId ) ); | ||
|
||
const displayDate = selectedDate.format( 'MMM Do' ); | ||
const nextDate = selectedDate.clone().add( 1, 'days' ); | ||
const displayNextDate = nextDate.format( 'll' ); | ||
|
||
return ( | ||
<Card | ||
className={ classNames( 'backup-card', { | ||
'is-featured': isFeatured, | ||
} ) } | ||
> | ||
<div className="backup-card__main"> | ||
<div className="backup-card__header"> | ||
<div className="backup-card__header-text"> | ||
<h2 className="backup-card__date"> | ||
{ translate( 'No Backup for %(displayDate)s', { | ||
args: { displayDate }, | ||
} ) } | ||
</h2> | ||
<p className="backup-card__title backup-card__title--delayed"> | ||
<img className="backup-card__icon" src={ cloudWarningIcon } alt="" /> | ||
{ translate( 'Backup was delayed' ) } | ||
</p> | ||
</div> | ||
</div> | ||
<ul className="backup-card__actions"> | ||
<li> | ||
<Button | ||
className="backup-card__support-button" | ||
href={ contactSupportUrl( siteUrl ) } | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
primary | ||
> | ||
{ translate( 'Contact support' ) } | ||
</Button> | ||
</li> | ||
</ul> | ||
</div> | ||
<div className="backup-card__about"> | ||
<h3 className="backup-card__about-heading">{ translate( 'About this backup' ) }</h3> | ||
<div className="backup-card__about-content"> | ||
<ul className="backup-card__about-list"> | ||
<li> | ||
<div className="backup-card__about-media backup-card__about-media--notice"> | ||
<JetpackLogo className="backup-card__jetpack-logo-warning" size={ 32 } /> | ||
</div> | ||
<div className="backup-card__about-body"> | ||
{ translate( | ||
'Don’t worry, the backup was most likely completed in the early hours of the following morning. ' + | ||
'Check the following day ({{link}}%(displayNextDate)s{{/link}}) or contact support if you need help.', | ||
{ | ||
args: { displayNextDate }, | ||
components: { | ||
link: ( | ||
<a | ||
href={ backupMainPath( siteSlug, { | ||
date: nextDate.format( INDEX_FORMAT ), | ||
} ) } | ||
/> | ||
), | ||
}, | ||
} | ||
) } | ||
</div> | ||
</li> | ||
</ul> | ||
</div> | ||
</div> | ||
</Card> | ||
); | ||
}; | ||
|
||
export default NoBackupsOnSelectedDate; |
Oops, something went wrong.