Settings: Better structure to settings page, and protect form changes (https://github.com/woocommerce/woocommerce-admin/pull/2544)

* Add section header for historical import.

* Add alert on unsaved changes.

* The glass is half full. Therefore my state change should be too.

* Update button text.
This commit is contained in:
Timmy Crawford 2019-07-02 13:50:59 -07:00 committed by GitHub
parent 3350605ef2
commit 1814741014
3 changed files with 86 additions and 74 deletions

View File

@ -7,6 +7,11 @@ import { Component, Fragment } from '@wordpress/element';
import { isNil } from 'lodash'; import { isNil } from 'lodash';
import { SECOND } from '@fresh-data/framework'; import { SECOND } from '@fresh-data/framework';
/**
* WooCommerce dependencies
*/
import { SectionHeader } from '@woocommerce/components';
/** /**
* Internal dependencies * Internal dependencies
*/ */
@ -50,45 +55,45 @@ class HistoricalDataLayout extends Component {
return ( return (
<Fragment> <Fragment>
<div className="woocommerce-setting"> <SectionHeader title={ __( 'Import Historical Data', 'woocommerce-admin' ) } />
<div className="woocommerce-setting__label" id="import-historical-data-label"> <div className="woocommerce-settings__wrapper">
{ __( 'Import Historical Data:', 'woocommerce-admin' ) } <div className="woocommerce-setting">
</div> <div className="woocommerce-setting__input">
<div className="woocommerce-setting__input"> <span className="woocommerce-setting__help">
<span className="woocommerce-setting__help"> { __(
{ __( 'This tool populates historical analytics data by processing customers ' +
'This tool populates historical analytics data by processing customers ' + 'and orders created prior to activating WooCommerce Admin.',
'and orders created prior to activating WooCommerce Admin.', 'woocommerce-admin'
'woocommerce-admin' ) }
</span>
{ status !== 'finished' && (
<Fragment>
<HistoricalDataPeriodSelector
dateFormat={ dateFormat }
disabled={ inProgress }
onPeriodChange={ onPeriodChange }
onDateChange={ onDateChange }
value={ period }
/>
<HistoricalDataSkipCheckbox
disabled={ inProgress }
checked={ skipChecked }
onChange={ onSkipChange }
/>
<HistoricalDataProgress
label={ __( 'Registered Customers', 'woocommerce-admin' ) }
progress={ customersProgress }
total={ customersTotal }
/>
<HistoricalDataProgress
label={ __( 'Orders', 'woocommerce-admin' ) }
progress={ ordersProgress }
total={ ordersTotal }
/>
</Fragment>
) } ) }
</span> <HistoricalDataStatus importDate={ importDate } status={ status } />
{ status !== 'finished' && ( </div>
<Fragment>
<HistoricalDataPeriodSelector
dateFormat={ dateFormat }
disabled={ inProgress }
onPeriodChange={ onPeriodChange }
onDateChange={ onDateChange }
value={ period }
/>
<HistoricalDataSkipCheckbox
disabled={ inProgress }
checked={ skipChecked }
onChange={ onSkipChange }
/>
<HistoricalDataProgress
label={ __( 'Registered Customers', 'woocommerce-admin' ) }
progress={ customersProgress }
total={ customersTotal }
/>
<HistoricalDataProgress
label={ __( 'Orders', 'woocommerce-admin' ) }
progress={ ordersProgress }
total={ ordersTotal }
/>
</Fragment>
) }
<HistoricalDataStatus importDate={ importDate } status={ status } />
</div> </div>
</div> </div>
<HistoricalDataActions <HistoricalDataActions

View File

@ -36,9 +36,19 @@ class Settings extends Component {
this.state = { this.state = {
settings, settings,
saving: false, saving: false,
isDirty: false,
}; };
this.handleInputChange = this.handleInputChange.bind( this ); this.handleInputChange = this.handleInputChange.bind( this );
this.warnIfUnsavedChanges = this.warnIfUnsavedChanges.bind( this );
}
componentDidMount() {
window.addEventListener( 'beforeunload', this.warnIfUnsavedChanges );
}
componentWillUnmount() {
window.removeEventListener( 'beforeunload', this.warnIfUnsavedChanges );
} }
componentDidCatch( error ) { componentDidCatch( error ) {
@ -50,6 +60,18 @@ class Settings extends Component {
/* eslint-enable no-console */ /* eslint-enable no-console */
} }
warnIfUnsavedChanges( event ) {
const { isDirty } = this.state;
if ( isDirty ) {
event.returnValue = __(
'You have unsaved changes. If you proceed, they will be lost.',
'woocommerce-admin'
);
return event.returnValue;
}
}
resetDefaults = () => { resetDefaults = () => {
if ( if (
window.confirm( window.confirm(
@ -64,7 +86,8 @@ class Settings extends Component {
componentDidUpdate() { componentDidUpdate() {
const { addNotice, isError, isRequesting } = this.props; const { addNotice, isError, isRequesting } = this.props;
const { saving } = this.state; const { saving, isDirty } = this.state;
let newIsDirtyState = isDirty;
if ( saving && ! isRequesting ) { if ( saving && ! isRequesting ) {
if ( ! isError ) { if ( ! isError ) {
@ -72,6 +95,7 @@ class Settings extends Component {
status: 'success', status: 'success',
message: __( 'Your settings have been successfully saved.', 'woocommerce-admin' ), message: __( 'Your settings have been successfully saved.', 'woocommerce-admin' ),
} ); } );
newIsDirtyState = false;
} else { } else {
addNotice( { addNotice( {
status: 'error', status: 'error',
@ -82,7 +106,7 @@ class Settings extends Component {
} ); } );
} }
/* eslint-disable react/no-did-update-set-state */ /* eslint-disable react/no-did-update-set-state */
this.setState( { saving: false } ); this.setState( { saving: false, isDirty: newIsDirtyState } );
/* eslint-enable react/no-did-update-set-state */ /* eslint-enable react/no-did-update-set-state */
} }
} }
@ -105,7 +129,9 @@ class Settings extends Component {
saveChanges = () => { saveChanges = () => {
this.persistChanges( this.state ); this.persistChanges( this.state );
this.props.updateSettings( { wc_admin: this.state.settings } ); this.props.updateSettings( { wc_admin: this.state.settings } );
this.setState( { saving: true } );
// TODO: remove this optimistic set of isDirty to false once #2541 is resolved.
this.setState( { saving: true, isDirty: false } );
}; };
handleInputChange( e ) { handleInputChange( e ) {
@ -122,7 +148,7 @@ class Settings extends Component {
settings[ name ] = value; settings[ name ] = value;
} }
this.setState( { settings } ); this.setState( { settings, isDirty: true } );
} }
render() { render() {
@ -155,11 +181,11 @@ class Settings extends Component {
{ __( 'Reset Defaults', 'woocommerce-admin' ) } { __( 'Reset Defaults', 'woocommerce-admin' ) }
</Button> </Button>
<Button isPrimary onClick={ this.saveChanges }> <Button isPrimary onClick={ this.saveChanges }>
{ __( 'Save Changes', 'woocommerce-admin' ) } { __( 'Save Settings', 'woocommerce-admin' ) }
</Button> </Button>
</div> </div>
<HistoricalData addNotice={ addNotice } />
</div> </div>
<HistoricalData addNotice={ addNotice } />
</Fragment> </Fragment>
); );
} }

View File

@ -9106,8 +9106,7 @@
}, },
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -9125,13 +9124,11 @@
}, },
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -9144,18 +9141,15 @@
}, },
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -9258,8 +9252,7 @@
}, },
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -9269,7 +9262,6 @@
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -9282,20 +9274,17 @@
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
}, },
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -9312,7 +9301,6 @@
"mkdirp": { "mkdirp": {
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -9385,8 +9373,7 @@
}, },
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -9396,7 +9383,6 @@
"once": { "once": {
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -9472,8 +9458,7 @@
}, },
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -9503,7 +9488,6 @@
"string-width": { "string-width": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -9521,7 +9505,6 @@
"strip-ansi": { "strip-ansi": {
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -9560,13 +9543,11 @@
}, },
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true, "bundled": true
"optional": true
} }
} }
}, },