From cf42ff978c52c90660b38cce4579c7bf5b77bda1 Mon Sep 17 00:00:00 2001 From: Kev Date: Fri, 6 Nov 2020 14:07:02 -0500 Subject: [PATCH] Add details to restore progress screen (#47153) * Move RewindState type in dedicated file * Add useCallback hook * Add details to restore progress - WIP * Add new rewind API fields, "message" & "current_entry" * Add selector getInProgressRewindEntryDetails. * Implement selector inProgressRewindEntryDetails for test. * Remove schema validation for message & current_entry for now.. * Integrate selector to retrieve message and entry in restore progress * Fix restore progress screen not showing proper details Co-authored-by: elliottprogrammer --- .../backup/rewind-flow/progress-bar.tsx | 28 +++++++++++++-- .../my-sites/backup/rewind-flow/restore.tsx | 35 +++++++++++-------- client/my-sites/backup/rewind-flow/style.scss | 21 +++++++++-- .../wpcom/sites/rewind/api-transformer.js | 2 ++ .../data-layer/wpcom/sites/rewind/schema.js | 7 ++++ .../data-layer/wpcom/sites/rewind/type.ts | 7 ++++ .../get-in-progress-rewind-entry-details.js | 33 +++++++++++++++++ 7 files changed, 114 insertions(+), 19 deletions(-) create mode 100644 client/state/data-layer/wpcom/sites/rewind/type.ts create mode 100644 client/state/selectors/get-in-progress-rewind-entry-details.js diff --git a/client/my-sites/backup/rewind-flow/progress-bar.tsx b/client/my-sites/backup/rewind-flow/progress-bar.tsx index 23a23eb3a925e..00245a6d9edb2 100644 --- a/client/my-sites/backup/rewind-flow/progress-bar.tsx +++ b/client/my-sites/backup/rewind-flow/progress-bar.tsx @@ -10,16 +10,40 @@ import React, { FunctionComponent } from 'react'; import { ProgressBar } from '@automattic/components'; interface Props { + isReady: boolean; percent: number | null; + message?: string; + entry?: string; } -const RewindFlowProgressBar: FunctionComponent< Props > = ( { percent } ) => { +const RewindFlowProgressBar: FunctionComponent< Props > = ( { + isReady, + percent, + message, + entry, +} ) => { const translate = useTranslate(); const filteredPercent = percent !== null ? percent : 0; + return (
-

{ translate( '%(filteredPercent)d%% complete', { args: { filteredPercent } } ) }

+
+

+ { isReady ? message : translate( 'Initializing the restore process' ) } +

+

+ { translate( '%(filteredPercent)d%% complete', { args: { filteredPercent } } ) } +

+
+

+ { isReady && + entry && + translate( 'Currently restoring: %s', { + args: entry, + comment: '%s entry is the file, table, etc. being restored', + } ) } +

); }; diff --git a/client/my-sites/backup/rewind-flow/restore.tsx b/client/my-sites/backup/rewind-flow/restore.tsx index 1f0670ac21d41..c96b79939006a 100644 --- a/client/my-sites/backup/rewind-flow/restore.tsx +++ b/client/my-sites/backup/rewind-flow/restore.tsx @@ -14,6 +14,7 @@ import { rewindRestore } from 'calypso/state/activity-log/actions'; import CheckYourEmail from './rewind-flow-notice/check-your-email'; import Error from './error'; import getInProgressRewindPercentComplete from 'calypso/state/selectors/get-in-progress-rewind-percent-complete'; +import getInProgressRewindEntryDetails from 'calypso/state/selectors/get-in-progress-rewind-entry-details'; import getInProgressRewindStatus from 'calypso/state/selectors/get-in-progress-rewind-status'; import getRewindState from 'calypso/state/selectors/get-rewind-state'; import Gridicon from 'calypso/components/gridicon'; @@ -23,6 +24,11 @@ import QueryRewindState from 'calypso/components/data/query-rewind-state'; import RewindConfigEditor from './rewind-config-editor'; import RewindFlowNotice, { RewindFlowNoticeLevel } from './rewind-flow-notice'; +/** + * Type dependencies + */ +import { RewindState } from 'calypso/state/data-layer/wpcom/sites/rewind/type'; + interface Props { backupDisplayDate: string; rewindId: string; @@ -30,14 +36,6 @@ interface Props { siteUrl: string; } -//todo: move to dedicated types file -interface RewindState { - state: string; - rewind?: { - status: 'queued' | 'running' | 'finished' | 'fail'; - }; -} - const BackupRestoreFlow: FunctionComponent< Props > = ( { backupDisplayDate, rewindId, @@ -51,25 +49,27 @@ const BackupRestoreFlow: FunctionComponent< Props > = ( { const [ userHasRequestedRestore, setUserHasRequestedRestore ] = useState< boolean >( false ); const rewindState = useSelector( ( state ) => getRewindState( state, siteId ) ) as RewindState; - - const loading = rewindState.state === 'uninitialized'; - const inProgressRewindStatus = useSelector( ( state ) => getInProgressRewindStatus( state, siteId, rewindId ) ); const inProgressRewindPercentComplete = useSelector( ( state ) => getInProgressRewindPercentComplete( state, siteId, rewindId ) ); + const inProgressRewindEntryDetails = useSelector( ( state ) => + getInProgressRewindEntryDetails( state, siteId, rewindId ) + ); const requestRestore = useCallback( () => dispatch( rewindRestore( siteId, rewindId, rewindConfig ) ), [ dispatch, rewindConfig, rewindId, siteId ] ); - - const onConfirm = () => { + const onConfirm = useCallback( () => { setUserHasRequestedRestore( true ); requestRestore(); - }; + }, [ setUserHasRequestedRestore, requestRestore ] ); + + const loading = rewindState.state === 'uninitialized'; + const { message, currentEntry } = inProgressRewindEntryDetails; const renderConfirm = () => ( <> @@ -114,7 +114,12 @@ const BackupRestoreFlow: FunctionComponent< Props > = ( {

{ translate( 'Currently restoring your site' ) }

- +

{ translate( 'We are restoring your site back to {{strong}}%(backupDisplayDate)s{{/strong}}.', diff --git a/client/my-sites/backup/rewind-flow/style.scss b/client/my-sites/backup/rewind-flow/style.scss index 58e3ed48df37d..0030d26f11aba 100644 --- a/client/my-sites/backup/rewind-flow/style.scss +++ b/client/my-sites/backup/rewind-flow/style.scss @@ -139,12 +139,29 @@ a.rewind-flow-notice__title-warning:visited { margin-bottom: 22.5px; p { - color: var( --color-neutral-light ); - font-size: $font-body-extra-small; + font-size: $font-body-small; margin: 0; } } +.rewind-flow__progress-bar-header { + display: flex; + justify-content: space-between; + flex-wrap: wrap; +} + +.rewind-flow__progress-bar-percent { + color: var( --studio-gray-50 ); +} + +.rewind-flow__progress-bar-message { + font-weight: 700; +} + +.rewind-flow__progress-bar-entry { + color: var( --studio-gray-50 ); +} + .rewind-flow__info { font-size: $font-body; } diff --git a/client/state/data-layer/wpcom/sites/rewind/api-transformer.js b/client/state/data-layer/wpcom/sites/rewind/api-transformer.js index 2ad401ddd7fa8..302de15402b41 100644 --- a/client/state/data-layer/wpcom/sites/rewind/api-transformer.js +++ b/client/state/data-layer/wpcom/sites/rewind/api-transformer.js @@ -50,6 +50,8 @@ const transformRewind = ( data ) => startedAt: new Date( data.started_at ), status: data.status, }, + data.message && { message: data.message }, + data.current_entry && { currentEntry: data.current_entry }, data.progress && { progress: data.progress }, data.reason && { reason: data.reason }, data.links && data.links.dismiss && { dismiss: makeRewindDismisser( data.links.dismiss ) } diff --git a/client/state/data-layer/wpcom/sites/rewind/schema.js b/client/state/data-layer/wpcom/sites/rewind/schema.js index 37f81fbdd983e..73c4800987d79 100644 --- a/client/state/data-layer/wpcom/sites/rewind/schema.js +++ b/client/state/data-layer/wpcom/sites/rewind/schema.js @@ -49,6 +49,13 @@ export const rewind = { started_at: { type: 'string' }, progress: { type: 'integer' }, reason: { type: 'string' }, + /** + * Commenting these out temporarily because API is returning a null value for current_entry, + * triggering a schema validation error. Once this is corrected on the backend (soon), we + * will activate these properties again. + **/ + // message: { type: 'string' }, + // current_entry: { type: 'string' }, }, required: [ 'restore_id', 'rewind_id', 'status' ], }; diff --git a/client/state/data-layer/wpcom/sites/rewind/type.ts b/client/state/data-layer/wpcom/sites/rewind/type.ts new file mode 100644 index 0000000000000..c1e03b68b5d3f --- /dev/null +++ b/client/state/data-layer/wpcom/sites/rewind/type.ts @@ -0,0 +1,7 @@ +export interface RewindState { + state: string; + rewind?: { + status: 'queued' | 'running' | 'finished' | 'fail'; + restoreId?: number; + }; +} diff --git a/client/state/selectors/get-in-progress-rewind-entry-details.js b/client/state/selectors/get-in-progress-rewind-entry-details.js new file mode 100644 index 0000000000000..af75ce4b1bf63 --- /dev/null +++ b/client/state/selectors/get-in-progress-rewind-entry-details.js @@ -0,0 +1,33 @@ +/** + * External dependencies + */ +import { pick } from 'lodash'; + +/** + * Internal dependencies + */ +import getRewindState from './get-rewind-state'; + +/** + * @typedef {Object} EntryDetails + * @property {string} message - The description of current action taking place + * @property {string} currentEntry - The value (filename/tablename) being processed + */ + +/** + * Returns object containing rewind status current entry and message + * + * @param {object} globalState Global state tree + * @param {?number|string} siteId the site ID + * @param {string} rewindId the id of the rewind to get the rewind status entry and message + * @returns {EntryDetails} Details of the current rewind action + */ +export default function getInProgressRewindEntryDetails( globalState, siteId, rewindId ) { + const { state, rewind } = getRewindState( globalState, siteId ); + + if ( 'active' === state && rewind?.rewindId === rewindId ) { + return pick( rewind, [ 'message', 'currentEntry' ] ); + } + + return {}; +}