Skip to content

Commit

Permalink
Make the UI react when theats are being fixed or ignored
Browse files Browse the repository at this point in the history
  • Loading branch information
rcanepa committed Mar 25, 2020
1 parent 2024fe2 commit 183d119
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 52 deletions.
60 changes: 19 additions & 41 deletions client/landing/jetpack-cloud/components/scan-threats/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import React from 'react';
import { connect } from 'react-redux';
import { numberFormat, translate } from 'i18n-calypso';
import { isEmpty } from 'lodash';
import { Button } from '@automattic/components';

/**
* Internal dependencies
*/
import { Button } from '@automattic/components';
import FixAllThreatsDialog from '../../components/fix-all-threats-dialog';
import SecurityIcon from 'landing/jetpack-cloud/components/security-icon';
import ThreatDialog from 'landing/jetpack-cloud/components/threat-dialog';
import ThreatItem from 'landing/jetpack-cloud/components/threat-item';
import { Threat, ThreatAction } from 'landing/jetpack-cloud/components/threat-item/types';
Expand All @@ -28,13 +29,11 @@ interface Props {
};
threats: Array< Threat >;
userHasCredentials: boolean;
updateState?: Function;
}

type ScanThreatsState = 'threats-found' | 'fixing-threats';

const ThreatsFound = ( { site, threats, userHasCredentials, updateState }: Props ) => {
const [ selectedThreat, setSelectedThreat ] = React.useState< Threat | undefined >();
const ScanThreats = ( { site, threats, userHasCredentials }: Props ) => {
const [ fixingThreats, setFixingThreats ] = React.useState< Array< Threat > >( [] );
const [ selectedThreat, setSelectedThreat ] = React.useState< Threat >( threats[ 0 ] );
const [ showThreatDialog, setShowThreatDialog ] = React.useState( false );
const [ showFixAllThreatsDialog, setShowFixAllThreatsDialog ] = React.useState( false );
const [ actionToPerform, setActionToPerform ] = React.useState< ThreatAction >( 'fix' );
Expand All @@ -50,25 +49,26 @@ const ThreatsFound = ( { site, threats, userHasCredentials, updateState }: Props
}, [] );

const closeDialog = React.useCallback( () => {
setSelectedThreat( undefined );
setShowThreatDialog( false );
}, [] );

const confirmAction = () => {
const confirmAction = React.useCallback( () => {
window.alert(
`We are going to ${ actionToPerform } threat ${ selectedThreat?.id } on site ${ site.name }`
);
closeDialog();
};
setFixingThreats( stateThreats => [ ...stateThreats, selectedThreat ] );
}, [ actionToPerform, closeDialog, selectedThreat, site ] );

const confirmFixAllThreats = () => {
const confirmFixAllThreats = React.useCallback( () => {
window.alert( `Starting to fix ${ threats.length } threats found...` );
setShowFixAllThreatsDialog( false );
updateState && updateState();
};
setFixingThreats( threats );
}, [ threats ] );

return (
<>
<SecurityIcon icon="error" />
<h1 className="scan-threats scan__header">{ translate( 'Your site may be at risk' ) }</h1>
<p>
{ translate(
Expand Down Expand Up @@ -99,10 +99,15 @@ const ThreatsFound = ( { site, threats, userHasCredentials, updateState }: Props
<Button
className="scan-threats__fix-all-threats-button"
onClick={ openFixAllThreatsDialog }
disabled={ fixingThreats.length === threats.length }
>
{ translate( 'Fix all' ) }
</Button>
<Button className="scan-threats__options-button" onClick={ openFixAllThreatsDialog }>
<Button
className="scan-threats__options-button"
onClick={ openFixAllThreatsDialog }
disabled={ fixingThreats.length === threats.length }
>
...
</Button>
</div>
Expand All @@ -112,6 +117,7 @@ const ThreatsFound = ( { site, threats, userHasCredentials, updateState }: Props
threat={ threat }
onFixThreat={ () => openDialog( 'fix', threat ) }
onIgnoreThreat={ () => openDialog( 'ignore', threat ) }
isFixing={ !! fixingThreats.find( t => t.id === threat.id ) }
/>
) ) }
</div>
Expand All @@ -138,34 +144,6 @@ const ThreatsFound = ( { site, threats, userHasCredentials, updateState }: Props
);
};

const ScanThreats = ( { site, threats, userHasCredentials }: Props ) => {
// In the future, we should compute the initial state from props instead of
// having it defined here.
const [ state, setState ] = React.useState< ScanThreatsState >( 'threats-found' );

const setFixingThreatsState = React.useCallback( () => {
setState( 'fixing-threats' );
}, [] );

const renderCurrentState = React.useCallback( () => {
switch ( state ) {
case 'threats-found':
return (
<ThreatsFound
site={ site }
threats={ threats }
userHasCredentials={ userHasCredentials }
updateState={ setFixingThreatsState }
/>
);
case 'fixing-threats':
return <h1>Fixing threats</h1>;
}
}, [ threats, site, state, userHasCredentials, setFixingThreatsState ] );

return renderCurrentState();
};

const mapStateToProps = ( state, { site } ) => {
return {
userHasCredentials: ! isEmpty( getJetpackCredentials( state, site.ID, 'main' ) ),
Expand Down
18 changes: 13 additions & 5 deletions client/landing/jetpack-cloud/components/threat-item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface Props {
threat: Threat;
onFixThreat: Function;
onIgnoreThreat: Function;
isFixing: boolean;
}

class ThreatItem extends Component< Props > {
Expand All @@ -32,20 +33,22 @@ class ThreatItem extends Component< Props > {
*
* @param {string} className A class for the button
*/
renderFixThreatButton( className ) {
renderFixThreatButton( className: string ) {
const { onFixThreat, isFixing } = this.props;
return (
<Button
className={ classnames( 'threat-item__fix-button', className ) }
compact
onClick={ this.props.onFixThreat }
className={ classnames( 'threat-item__fix-button', className ) }
onClick={ onFixThreat }
disabled={ isFixing }
>
{ translate( 'Fix threat' ) }
</Button>
);
}

render() {
const { threat, onIgnoreThreat } = this.props;
const { threat, onIgnoreThreat, isFixing } = this.props;
const fixThreatCTA = this.renderFixThreatButton( 'is-summary' );

return (
Expand All @@ -67,7 +70,12 @@ class ThreatItem extends Component< Props > {

<div className="threat-item__buttons">
{ this.renderFixThreatButton( 'is-details' ) }
<Button className="threat-item__ignore-button" compact onClick={ onIgnoreThreat }>
<Button
className="threat-item__ignore-button"
compact
onClick={ onIgnoreThreat }
disabled={ isFixing }
>
{ translate( 'Ignore threat' ) }
</Button>
</div>
Expand Down
7 changes: 1 addition & 6 deletions client/landing/jetpack-cloud/sections/scan/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,7 @@ class ScanPage extends Component {

renderThreats() {
const { threats, site } = this.props;
return (
<>
<SecurityIcon icon="error" />
<ScanThreats className="scan__threats" threats={ threats } site={ site } />
</>
);
return <ScanThreats className="scan__threats" threats={ threats } site={ site } />;
}

renderScanError() {
Expand Down

0 comments on commit 183d119

Please sign in to comment.