Skip to content

Commit

Permalink
Add details to restore progress screen (#47153)
Browse files Browse the repository at this point in the history
* 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 <bryan@elliottprogrammer.com>
  • Loading branch information
monsieur-z and elliottprogrammer committed Nov 6, 2020
1 parent 054d9d1 commit cf42ff9
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 19 deletions.
28 changes: 26 additions & 2 deletions client/my-sites/backup/rewind-flow/progress-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div className="rewind-flow__progress-bar">
<p>{ translate( '%(filteredPercent)d%% complete', { args: { filteredPercent } } ) }</p>
<div className="rewind-flow__progress-bar-header">
<p className="rewind-flow__progress-bar-message">
{ isReady ? message : translate( 'Initializing the restore process' ) }
</p>
<p className="rewind-flow__progress-bar-percent">
{ translate( '%(filteredPercent)d%% complete', { args: { filteredPercent } } ) }
</p>
</div>
<ProgressBar value={ filteredPercent } total={ 100 } />
<p className="rewind-flow__progress-bar-entry">
{ isReady &&
entry &&
translate( 'Currently restoring: %s', {
args: entry,
comment: '%s entry is the file, table, etc. being restored',
} ) }
</p>
</div>
);
};
Expand Down
35 changes: 20 additions & 15 deletions client/my-sites/backup/rewind-flow/restore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -23,21 +24,18 @@ 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;
siteId: number;
siteUrl: string;
}

//todo: move to dedicated types file
interface RewindState {
state: string;
rewind?: {
status: 'queued' | 'running' | 'finished' | 'fail';
};
}

const BackupRestoreFlow: FunctionComponent< Props > = ( {
backupDisplayDate,
rewindId,
Expand All @@ -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 = () => (
<>
Expand Down Expand Up @@ -114,7 +114,12 @@ const BackupRestoreFlow: FunctionComponent< Props > = ( {
<Gridicon icon="history" size={ 48 } />
</div>
<h3 className="rewind-flow__title">{ translate( 'Currently restoring your site' ) }</h3>
<ProgressBar percent={ inProgressRewindPercentComplete } />
<ProgressBar
isReady={ 'running' === inProgressRewindStatus }
message={ message }
entry={ currentEntry }
percent={ inProgressRewindPercentComplete }
/>
<p className="rewind-flow__info">
{ translate(
'We are restoring your site back to {{strong}}%(backupDisplayDate)s{{/strong}}.',
Expand Down
21 changes: 19 additions & 2 deletions client/my-sites/backup/rewind-flow/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions client/state/data-layer/wpcom/sites/rewind/api-transformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) }
Expand Down
7 changes: 7 additions & 0 deletions client/state/data-layer/wpcom/sites/rewind/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' ],
};
Expand Down
7 changes: 7 additions & 0 deletions client/state/data-layer/wpcom/sites/rewind/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface RewindState {
state: string;
rewind?: {
status: 'queued' | 'running' | 'finished' | 'fail';
restoreId?: number;
};
}
33 changes: 33 additions & 0 deletions client/state/selectors/get-in-progress-rewind-entry-details.js
Original file line number Diff line number Diff line change
@@ -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 {};
}

0 comments on commit cf42ff9

Please sign in to comment.