Refactor task tax to use promise chain (https://github.com/woocommerce/woocommerce-admin/pull/4683)
* Show success screen based on conditions instead of step * Use promise chain to handle updating tax settings * Fix up error handling for failed setting updates * Skip store location step if complete address exists * Fix up pending/requesting state logic * Allow opt in to TOS on tax task * Don't complete task from completeStep * Add caption styling to TOS text
This commit is contained in:
parent
1d5e7db33d
commit
8e5291e231
|
@ -696,11 +696,7 @@ BusinessDetails.contextType = CurrencyContext;
|
|||
|
||||
export default compose(
|
||||
withSelect( ( select ) => {
|
||||
const {
|
||||
getSettings,
|
||||
getSettingsError,
|
||||
isGetSettingsRequesting,
|
||||
} = select( SETTINGS_STORE_NAME );
|
||||
const { getSettings, getSettingsError } = select( SETTINGS_STORE_NAME );
|
||||
const { getProfileItems, getOnboardingError } = select(
|
||||
ONBOARDING_STORE_NAME
|
||||
);
|
||||
|
@ -716,7 +712,6 @@ export default compose(
|
|||
isError: Boolean( getOnboardingError( 'updateProfileItems' ) ),
|
||||
profileItems: getProfileItems(),
|
||||
isSettingsError: Boolean( getSettingsError( 'general' ) ),
|
||||
isSettingsRequesting: isGetSettingsRequesting( 'general' ),
|
||||
settings,
|
||||
isInstallingActivating:
|
||||
isPluginsRequesting( 'installPlugins' ) ||
|
||||
|
|
|
@ -237,11 +237,7 @@ StoreDetails.contextType = CurrencyContext;
|
|||
|
||||
export default compose(
|
||||
withSelect( ( select ) => {
|
||||
const {
|
||||
getSettings,
|
||||
getSettingsError,
|
||||
isGetSettingsRequesting,
|
||||
} = select( SETTINGS_STORE_NAME );
|
||||
const { getSettings, getSettingsError } = select( SETTINGS_STORE_NAME );
|
||||
const { getOnboardingError, getProfileItems } = select(
|
||||
ONBOARDING_STORE_NAME
|
||||
);
|
||||
|
@ -253,12 +249,10 @@ export default compose(
|
|||
|
||||
const { general: settings = {} } = getSettings( 'general' );
|
||||
const isSettingsError = Boolean( getSettingsError( 'general' ) );
|
||||
const isSettingsRequesting = isGetSettingsRequesting( 'general' );
|
||||
|
||||
return {
|
||||
isProfileItemsError,
|
||||
isSettingsError,
|
||||
isSettingsRequesting,
|
||||
profileItems,
|
||||
settings,
|
||||
};
|
||||
|
|
|
@ -584,3 +584,8 @@
|
|||
border-top-right-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-task__caption {
|
||||
color: $dark-gray-300;
|
||||
margin-top: $gap;
|
||||
}
|
||||
|
|
|
@ -302,13 +302,13 @@ class Shipping extends Component {
|
|||
|
||||
render() {
|
||||
const { isPending, step } = this.state;
|
||||
const { isSettingsRequesting } = this.props;
|
||||
const { isUpdateSettingsRequesting } = this.props;
|
||||
|
||||
return (
|
||||
<div className="woocommerce-task-shipping">
|
||||
<Card className="is-narrow">
|
||||
<Stepper
|
||||
isPending={ isPending || isSettingsRequesting }
|
||||
isPending={ isPending || isUpdateSettingsRequesting }
|
||||
isVertical
|
||||
currentStep={ step }
|
||||
steps={ this.getSteps() }
|
||||
|
@ -321,19 +321,14 @@ class Shipping extends Component {
|
|||
|
||||
export default compose(
|
||||
withSelect( ( select ) => {
|
||||
const {
|
||||
getSettings,
|
||||
getSettingsError,
|
||||
isGetSettingsRequesting,
|
||||
} = select( SETTINGS_STORE_NAME );
|
||||
const { getSettings, isUpdateSettingsRequesting } = select(
|
||||
SETTINGS_STORE_NAME
|
||||
);
|
||||
const { getActivePlugins, isJetpackConnected } = select(
|
||||
PLUGINS_STORE_NAME
|
||||
);
|
||||
|
||||
const { general: settings = {} } = getSettings( 'general' );
|
||||
const isSettingsError = Boolean( getSettingsError( 'general' ) );
|
||||
const isSettingsRequesting = isGetSettingsRequesting( 'general' );
|
||||
|
||||
const countryCode = getCountryCode(
|
||||
settings.woocommerce_default_country
|
||||
);
|
||||
|
@ -348,8 +343,7 @@ export default compose(
|
|||
return {
|
||||
countryCode,
|
||||
countryName,
|
||||
isSettingsError,
|
||||
isSettingsRequesting,
|
||||
isUpdateSettingsRequesting: isUpdateSettingsRequesting( 'general' ),
|
||||
settings,
|
||||
activePlugins,
|
||||
isJetpackConnected: isJetpackConnected(),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { Button, __experimentalText as Text } from '@wordpress/components';
|
||||
import { Component, Fragment } from '@wordpress/element';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { difference, filter } from 'lodash';
|
||||
|
@ -29,6 +29,7 @@ import {
|
|||
* Internal dependencies
|
||||
*/
|
||||
import Connect from 'dashboard/components/connect';
|
||||
import { createNoticesFromResponse } from 'lib/notices';
|
||||
import { getCountryCode } from 'dashboard/utils';
|
||||
import StoreLocation from './steps/location';
|
||||
import { recordEvent, queueRecordEvent } from 'lib/tracks';
|
||||
|
@ -36,24 +37,18 @@ import { recordEvent, queueRecordEvent } from 'lib/tracks';
|
|||
class Tax extends Component {
|
||||
constructor( props ) {
|
||||
super( props );
|
||||
const { hasCompleteAddress, pluginsToActivate } = props;
|
||||
|
||||
this.initialState = {
|
||||
isPending: false,
|
||||
stepIndex: 0,
|
||||
automatedTaxEnabled: true,
|
||||
// Cache the value of pluginsToActivate so that we can show/hide tasks based on it, but not have them update mid task.
|
||||
pluginsToActivate: props.pluginsToActivate,
|
||||
stepIndex: hasCompleteAddress ? 1 : 0,
|
||||
// Cache the value of pluginsToActivate so that we can
|
||||
// show/hide tasks based on it, but not have them update mid task.
|
||||
cachedPluginsToActivate: pluginsToActivate,
|
||||
};
|
||||
|
||||
this.state = this.initialState;
|
||||
|
||||
this.completeStep = this.completeStep.bind( this );
|
||||
this.configureTaxRates = this.configureTaxRates.bind( this );
|
||||
this.updateAutomatedTax = this.updateAutomatedTax.bind( this );
|
||||
this.setIsPending = this.setIsPending.bind( this );
|
||||
this.shouldShowSuccessScreen = this.shouldShowSuccessScreen.bind(
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -65,87 +60,22 @@ class Tax extends Component {
|
|||
}
|
||||
|
||||
shouldShowSuccessScreen() {
|
||||
const { stepIndex } = this.state;
|
||||
const {
|
||||
isJetpackConnected,
|
||||
hasCompleteAddress,
|
||||
pluginsToActivate,
|
||||
generalSettings,
|
||||
} = this.props;
|
||||
const {
|
||||
woocommerce_store_address: storeAddress,
|
||||
woocommerce_default_country: defaultCountry,
|
||||
woocommerce_store_postcode: storePostCode,
|
||||
} = generalSettings;
|
||||
const isCompleteAddress = Boolean(
|
||||
storeAddress && defaultCountry && storePostCode
|
||||
);
|
||||
|
||||
return (
|
||||
stepIndex !== null &&
|
||||
isCompleteAddress &&
|
||||
hasCompleteAddress &&
|
||||
! pluginsToActivate.length &&
|
||||
isJetpackConnected &&
|
||||
this.isTaxJarSupported()
|
||||
);
|
||||
}
|
||||
|
||||
componentDidUpdate( prevProps ) {
|
||||
const { generalSettings, isJetpackConnected, taxSettings } = this.props;
|
||||
const {
|
||||
woocommerce_calc_taxes: calcTaxes,
|
||||
woocommerce_store_address: storeAddress,
|
||||
woocommerce_default_country: defaultCountry,
|
||||
woocommerce_store_postcode: storePostCode,
|
||||
} = generalSettings;
|
||||
const { stepIndex } = this.state;
|
||||
const currentStep = this.getSteps()[ stepIndex ];
|
||||
const currentStepKey = currentStep && currentStep.key;
|
||||
|
||||
if ( stepIndex !== null && this.shouldShowSuccessScreen() ) {
|
||||
/* eslint-disable react/no-did-update-set-state */
|
||||
this.setState( { stepIndex: null } );
|
||||
/* eslint-enable react/no-did-update-set-state */
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
taxSettings.wc_connect_taxes_enabled &&
|
||||
taxSettings.wc_connect_taxes_enabled !==
|
||||
prevProps.taxSettings.wc_connect_taxes_enabled
|
||||
) {
|
||||
/* eslint-disable react/no-did-update-set-state */
|
||||
this.setState( {
|
||||
automatedTaxEnabled:
|
||||
taxSettings.wc_connect_taxes_enabled === 'yes'
|
||||
? true
|
||||
: false,
|
||||
} );
|
||||
/* eslint-enable react/no-did-update-set-state */
|
||||
}
|
||||
|
||||
if ( currentStepKey === 'connect' && isJetpackConnected ) {
|
||||
this.completeStep();
|
||||
}
|
||||
|
||||
const isCompleteAddress = Boolean(
|
||||
storeAddress && defaultCountry && storePostCode
|
||||
);
|
||||
|
||||
if ( currentStepKey === 'store_location' && isCompleteAddress ) {
|
||||
this.completeStep();
|
||||
}
|
||||
|
||||
const {
|
||||
woocommerce_calc_taxes: prevCalcTaxes,
|
||||
} = prevProps.generalSettings;
|
||||
if ( prevCalcTaxes === 'no' && calcTaxes === 'yes' ) {
|
||||
window.location = getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=tax§ion=standard'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
isTaxJarSupported() {
|
||||
const { countryCode, tosAccepted } = this.props;
|
||||
const { countryCode } = this.props;
|
||||
const {
|
||||
automatedTaxSupportedCountries = [],
|
||||
taxJarActivated,
|
||||
|
@ -153,7 +83,6 @@ class Tax extends Component {
|
|||
|
||||
return (
|
||||
! taxJarActivated && // WCS integration doesn't work with the official TaxJar plugin.
|
||||
tosAccepted &&
|
||||
automatedTaxSupportedCountries.includes( countryCode )
|
||||
);
|
||||
}
|
||||
|
@ -165,12 +94,10 @@ class Tax extends Component {
|
|||
|
||||
if ( nextStep ) {
|
||||
this.setState( { stepIndex: stepIndex + 1 } );
|
||||
} else {
|
||||
getHistory().push( getNewPath( {}, '/', {} ) );
|
||||
}
|
||||
}
|
||||
|
||||
async configureTaxRates() {
|
||||
async manuallyConfigureTaxRates() {
|
||||
const {
|
||||
generalSettings,
|
||||
updateAndPersistSettingsForGroup,
|
||||
|
@ -178,82 +105,87 @@ class Tax extends Component {
|
|||
|
||||
if ( generalSettings.woocommerce_calc_taxes !== 'yes' ) {
|
||||
this.setState( { isPending: true } );
|
||||
await updateAndPersistSettingsForGroup( 'general', {
|
||||
updateAndPersistSettingsForGroup( 'general', {
|
||||
general: {
|
||||
...generalSettings,
|
||||
woocommerce_calc_taxes: 'yes',
|
||||
},
|
||||
} );
|
||||
} )
|
||||
.then( () => this.redirectToTaxSettings() )
|
||||
.catch( ( error ) => createNoticesFromResponse( error ) );
|
||||
} else {
|
||||
this.redirectToTaxSettings();
|
||||
}
|
||||
|
||||
window.location = getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=tax§ion=standard&wc_onboarding_active_task=tax'
|
||||
);
|
||||
}
|
||||
|
||||
async updateAutomatedTax() {
|
||||
updateAutomatedTax( isEnabling ) {
|
||||
const {
|
||||
createNotice,
|
||||
updateAndPersistSettingsForGroup,
|
||||
generalSettings,
|
||||
taxSettings,
|
||||
} = this.props;
|
||||
const { automatedTaxEnabled } = this.state;
|
||||
|
||||
await updateAndPersistSettingsForGroup( 'tax', {
|
||||
tax: {
|
||||
...taxSettings,
|
||||
wc_connect_taxes_enabled: automatedTaxEnabled ? 'yes' : 'no',
|
||||
},
|
||||
} );
|
||||
|
||||
await updateAndPersistSettingsForGroup( 'general', {
|
||||
general: {
|
||||
...generalSettings,
|
||||
woocommerce_calc_taxes: 'yes',
|
||||
},
|
||||
} );
|
||||
|
||||
if (
|
||||
! this.props.isTaxSettingsError &&
|
||||
! this.props.isGeneralSettingsError
|
||||
) {
|
||||
// @todo This is a workaround to force the task to mark as complete.
|
||||
// This should probably be updated to use wc-api so we can fetch tax rates.
|
||||
setSetting( 'onboarding', {
|
||||
...getSetting( 'onboarding', {} ),
|
||||
isTaxComplete: true,
|
||||
Promise.all( [
|
||||
updateAndPersistSettingsForGroup( 'tax', {
|
||||
tax: {
|
||||
...taxSettings,
|
||||
wc_connect_taxes_enabled: isEnabling ? 'yes' : 'no',
|
||||
},
|
||||
} ),
|
||||
updateAndPersistSettingsForGroup( 'general', {
|
||||
general: {
|
||||
...generalSettings,
|
||||
woocommerce_calc_taxes: 'yes',
|
||||
},
|
||||
} ),
|
||||
] )
|
||||
.then( () => {
|
||||
// @todo This is a workaround to force the task to mark as complete.
|
||||
// This should probably be updated to use wc-api so we can fetch tax rates.
|
||||
setSetting( 'onboarding', {
|
||||
...getSetting( 'onboarding', {} ),
|
||||
isTaxComplete: true,
|
||||
} );
|
||||
if ( isEnabling ) {
|
||||
createNotice(
|
||||
'success',
|
||||
__(
|
||||
"You're awesome! One less item on your to-do list ✅",
|
||||
'woocommerce-admin'
|
||||
)
|
||||
);
|
||||
getHistory().push( getNewPath( {}, '/', {} ) );
|
||||
} else {
|
||||
this.redirectToTaxSettings();
|
||||
}
|
||||
} )
|
||||
.catch( () => {
|
||||
createNotice(
|
||||
'error',
|
||||
__(
|
||||
'There was a problem updating your tax settings.',
|
||||
'woocommerce-admin'
|
||||
)
|
||||
);
|
||||
} );
|
||||
createNotice(
|
||||
'success',
|
||||
__(
|
||||
"You're awesome! One less item on your to-do list ✅",
|
||||
'woocommerce-admin'
|
||||
)
|
||||
);
|
||||
if ( automatedTaxEnabled ) {
|
||||
getHistory().push( getNewPath( {}, '/', {} ) );
|
||||
} else {
|
||||
this.configureTaxRates();
|
||||
}
|
||||
} else {
|
||||
createNotice(
|
||||
'error',
|
||||
__(
|
||||
'There was a problem updating your tax settings.',
|
||||
'woocommerce-admin'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setIsPending( value ) {
|
||||
this.setState( { isPending: value } );
|
||||
redirectToTaxSettings() {
|
||||
window.location = getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=tax§ion=standard&wc_onboarding_active_task=tax'
|
||||
);
|
||||
}
|
||||
|
||||
getSteps() {
|
||||
const { generalSettings, isJetpackConnected } = this.props;
|
||||
const { isPending, pluginsToActivate } = this.state;
|
||||
const {
|
||||
generalSettings,
|
||||
isJetpackConnected,
|
||||
isPending,
|
||||
tosAccepted,
|
||||
updateOptions,
|
||||
} = this.props;
|
||||
const { cachedPluginsToActivate } = this.state;
|
||||
|
||||
const steps = [
|
||||
{
|
||||
|
@ -273,12 +205,7 @@ class Tax extends Component {
|
|||
recordEvent( 'tasklist_tax_set_location', {
|
||||
country,
|
||||
} );
|
||||
if ( this.shouldShowSuccessScreen() ) {
|
||||
this.setState( { stepIndex: null } );
|
||||
// Only complete step if another update hasn't already shown succes screen.
|
||||
} else if ( this.state.stepIndex !== null ) {
|
||||
this.completeStep();
|
||||
}
|
||||
this.completeStep();
|
||||
} }
|
||||
isSettingsRequesting={ false }
|
||||
settings={ generalSettings }
|
||||
|
@ -297,31 +224,63 @@ class Tax extends Component {
|
|||
'woocommerce-admin'
|
||||
),
|
||||
content: (
|
||||
<Plugins
|
||||
onComplete={ () => {
|
||||
recordEvent( 'tasklist_tax_install_extensions', {
|
||||
install_extensions: true,
|
||||
} );
|
||||
this.completeStep();
|
||||
} }
|
||||
onSkip={ () => {
|
||||
queueRecordEvent(
|
||||
'tasklist_tax_install_extensions',
|
||||
{
|
||||
install_extensions: false,
|
||||
}
|
||||
);
|
||||
window.location.href = getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=tax§ion=standard'
|
||||
);
|
||||
} }
|
||||
skipText={ __(
|
||||
'Set up tax rates manually',
|
||||
'woocommerce-admin'
|
||||
<Fragment>
|
||||
<Plugins
|
||||
onComplete={ () => {
|
||||
recordEvent(
|
||||
'tasklist_tax_install_extensions',
|
||||
{
|
||||
install_extensions: true,
|
||||
}
|
||||
);
|
||||
updateOptions( {
|
||||
woocommerce_setup_jetpack_opted_in: true,
|
||||
} );
|
||||
this.completeStep();
|
||||
} }
|
||||
onSkip={ () => {
|
||||
queueRecordEvent(
|
||||
'tasklist_tax_install_extensions',
|
||||
{
|
||||
install_extensions: false,
|
||||
}
|
||||
);
|
||||
this.redirectToTaxSettings();
|
||||
} }
|
||||
skipText={ __(
|
||||
'Set up tax rates manually',
|
||||
'woocommerce-admin'
|
||||
) }
|
||||
/>
|
||||
{ ! tosAccepted && (
|
||||
<Text
|
||||
variant="caption"
|
||||
className="woocommerce-task__caption"
|
||||
>
|
||||
{ interpolateComponents( {
|
||||
mixedString: __(
|
||||
'By installing Jetpack and WooCommerce Services you agree to the {{link}}Terms of Service{{/link}}.',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
components: {
|
||||
link: (
|
||||
<Link
|
||||
href={
|
||||
'https://wordpress.com/tos/'
|
||||
}
|
||||
target="_blank"
|
||||
type="external"
|
||||
/>
|
||||
),
|
||||
},
|
||||
} ) }
|
||||
</Text>
|
||||
) }
|
||||
/>
|
||||
</Fragment>
|
||||
),
|
||||
visible: pluginsToActivate.length && this.isTaxJarSupported(),
|
||||
visible:
|
||||
( cachedPluginsToActivate.length || ! tosAccepted ) &&
|
||||
this.isTaxJarSupported(),
|
||||
},
|
||||
{
|
||||
key: 'connect',
|
||||
|
@ -333,7 +292,6 @@ class Tax extends Component {
|
|||
content: (
|
||||
<Connect
|
||||
{ ...this.props }
|
||||
setIsPending={ this.setIsPending }
|
||||
onConnect={ () => {
|
||||
recordEvent( 'tasklist_tax_connect_store', {
|
||||
connect: true,
|
||||
|
@ -343,9 +301,7 @@ class Tax extends Component {
|
|||
queueRecordEvent( 'tasklist_tax_connect_store', {
|
||||
connect: false,
|
||||
} );
|
||||
window.location.href = getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=tax§ion=standard'
|
||||
);
|
||||
this.manuallyConfigureTaxRates();
|
||||
} }
|
||||
skipText={ __(
|
||||
'Set up tax rates manually',
|
||||
|
@ -365,11 +321,12 @@ class Tax extends Component {
|
|||
content: (
|
||||
<Fragment>
|
||||
<Button
|
||||
disabled={ isPending }
|
||||
isPrimary
|
||||
isBusy={ isPending }
|
||||
onClick={ () => {
|
||||
recordEvent( 'tasklist_tax_config_rates' );
|
||||
this.configureTaxRates();
|
||||
this.manuallyConfigureTaxRates();
|
||||
} }
|
||||
>
|
||||
{ __( 'Configure', 'woocommerce-admin' ) }
|
||||
|
@ -405,21 +362,14 @@ class Tax extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { isPending, stepIndex } = this.state;
|
||||
const { isTaxSettingsRequesting, taxSettings } = this.props;
|
||||
const { stepIndex } = this.state;
|
||||
const { isPending, isResolving } = this.props;
|
||||
const step = this.getSteps()[ stepIndex ];
|
||||
|
||||
return (
|
||||
<div className="woocommerce-task-tax">
|
||||
<Card className="is-narrow">
|
||||
{ step ? (
|
||||
<Stepper
|
||||
isPending={ isPending || isTaxSettingsRequesting }
|
||||
isVertical={ true }
|
||||
currentStep={ step.key }
|
||||
steps={ this.getSteps() }
|
||||
/>
|
||||
) : (
|
||||
{ this.shouldShowSuccessScreen() ? (
|
||||
<div className="woocommerce-task-tax__success">
|
||||
<span
|
||||
className="woocommerce-task-tax__success-icon"
|
||||
|
@ -444,11 +394,9 @@ class Tax extends Component {
|
|||
} ) }
|
||||
</p>
|
||||
<Button
|
||||
disabled={ isPending }
|
||||
isPrimary
|
||||
isBusy={
|
||||
Object.keys( taxSettings ).length &&
|
||||
isTaxSettingsRequesting
|
||||
}
|
||||
isBusy={ isPending }
|
||||
onClick={ () => {
|
||||
recordEvent(
|
||||
'tasklist_tax_setup_automated_proceed',
|
||||
|
@ -456,15 +404,14 @@ class Tax extends Component {
|
|||
setup_automatically: true,
|
||||
}
|
||||
);
|
||||
this.setState(
|
||||
{ automatedTaxEnabled: true },
|
||||
this.updateAutomatedTax
|
||||
);
|
||||
this.updateAutomatedTax( true );
|
||||
} }
|
||||
>
|
||||
{ __( 'Yes please', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
<Button
|
||||
disabled={ isPending }
|
||||
isBusy={ isPending }
|
||||
onClick={ () => {
|
||||
recordEvent(
|
||||
'tasklist_tax_setup_automated_proceed',
|
||||
|
@ -472,10 +419,7 @@ class Tax extends Component {
|
|||
setup_automatically: false,
|
||||
}
|
||||
);
|
||||
this.setState(
|
||||
{ automatedTaxEnabled: false },
|
||||
this.updateAutomatedTax
|
||||
);
|
||||
this.updateAutomatedTax( false );
|
||||
} }
|
||||
>
|
||||
{ __(
|
||||
|
@ -484,6 +428,13 @@ class Tax extends Component {
|
|||
) }
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<Stepper
|
||||
isPending={ isPending || isResolving }
|
||||
isVertical={ true }
|
||||
currentStep={ step.key }
|
||||
steps={ this.getSteps() }
|
||||
/>
|
||||
) }
|
||||
</Card>
|
||||
</div>
|
||||
|
@ -493,26 +444,30 @@ class Tax extends Component {
|
|||
|
||||
export default compose(
|
||||
withSelect( ( select ) => {
|
||||
const {
|
||||
getSettings,
|
||||
getSettingsError,
|
||||
isGetSettingsRequesting,
|
||||
} = select( SETTINGS_STORE_NAME );
|
||||
const { getOption } = select( OPTIONS_STORE_NAME );
|
||||
const { getActivePlugins, isJetpackConnected } = select(
|
||||
PLUGINS_STORE_NAME
|
||||
const { getSettings, isUpdateSettingsRequesting } = select(
|
||||
SETTINGS_STORE_NAME
|
||||
);
|
||||
const { getOption } = select( OPTIONS_STORE_NAME );
|
||||
const {
|
||||
getActivePlugins,
|
||||
isJetpackConnected,
|
||||
isPluginsRequesting,
|
||||
} = select( PLUGINS_STORE_NAME );
|
||||
|
||||
const { general: generalSettings = {} } = getSettings( 'general' );
|
||||
const isGeneralSettingsError = Boolean( getSettingsError( 'general' ) );
|
||||
const countryCode = getCountryCode(
|
||||
generalSettings.woocommerce_default_country
|
||||
);
|
||||
const {
|
||||
woocommerce_store_address: storeAddress,
|
||||
woocommerce_default_country: defaultCountry,
|
||||
woocommerce_store_postcode: storePostCode,
|
||||
} = generalSettings;
|
||||
const hasCompleteAddress = Boolean(
|
||||
storeAddress && defaultCountry && storePostCode
|
||||
);
|
||||
|
||||
const { tax: taxSettings = {} } = getSettings( 'tax' );
|
||||
const isTaxSettingsError = Boolean( getSettingsError( 'tax' ) );
|
||||
const isTaxSettingsRequesting = isGetSettingsRequesting( 'tax' );
|
||||
|
||||
const activePlugins = getActivePlugins();
|
||||
const pluginsToActivate = difference(
|
||||
[ 'jetpack', 'woocommerce-services' ],
|
||||
|
@ -523,20 +478,26 @@ export default compose(
|
|||
connectOptions.tos_accepted ||
|
||||
getOption( 'woocommerce_setup_jetpack_opted_in' );
|
||||
|
||||
const isPending =
|
||||
isUpdateSettingsRequesting( 'tax' ) ||
|
||||
isUpdateSettingsRequesting( 'general' );
|
||||
const isResolving = isPluginsRequesting( 'getJetpackConnectUrl' );
|
||||
|
||||
return {
|
||||
isGeneralSettingsError,
|
||||
generalSettings,
|
||||
countryCode,
|
||||
taxSettings,
|
||||
isTaxSettingsError,
|
||||
isTaxSettingsRequesting,
|
||||
generalSettings,
|
||||
hasCompleteAddress,
|
||||
isJetpackConnected: isJetpackConnected(),
|
||||
isPending,
|
||||
isResolving,
|
||||
pluginsToActivate,
|
||||
taxSettings,
|
||||
tosAccepted,
|
||||
};
|
||||
} ),
|
||||
withDispatch( ( dispatch ) => {
|
||||
const { createNotice } = dispatch( 'core/notices' );
|
||||
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||
const { updateAndPersistSettingsForGroup } = dispatch(
|
||||
SETTINGS_STORE_NAME
|
||||
);
|
||||
|
@ -544,6 +505,7 @@ export default compose(
|
|||
return {
|
||||
createNotice,
|
||||
updateAndPersistSettingsForGroup,
|
||||
updateOptions,
|
||||
};
|
||||
} )
|
||||
)( Tax );
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* External Dependencies
|
||||
*/
|
||||
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { apiFetch, select } from '@wordpress/data-controls';
|
||||
import { concat } from 'lodash';
|
||||
|
||||
|
@ -65,11 +66,16 @@ export function* persistSettingsForGroup( group ) {
|
|||
}
|
||||
|
||||
// get data slice for keys
|
||||
const dirtyData = yield select( STORE_NAME, 'getSettingsForGroup', group, dirtyKeys );
|
||||
const dirtyData = yield select(
|
||||
STORE_NAME,
|
||||
'getSettingsForGroup',
|
||||
group,
|
||||
dirtyKeys
|
||||
);
|
||||
const url = `${ NAMESPACE }/settings/${ group }/batch`;
|
||||
|
||||
const update = dirtyKeys.reduce( ( updates, key ) => {
|
||||
const u = Object.keys( dirtyData[ key ] ).map( k => {
|
||||
const u = Object.keys( dirtyData[ key ] ).map( ( k ) => {
|
||||
return { id: k, value: dirtyData[ key ][ k ] };
|
||||
} );
|
||||
return concat( updates, u );
|
||||
|
@ -80,16 +86,25 @@ export function* persistSettingsForGroup( group ) {
|
|||
method: 'POST',
|
||||
data: { update },
|
||||
} );
|
||||
|
||||
yield setIsRequesting( group, false );
|
||||
|
||||
if ( ! results ) {
|
||||
throw new Error( 'settings did not update' );
|
||||
throw new Error(
|
||||
__(
|
||||
'There was a problem updating your settings.',
|
||||
'woocommerce-admin'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// remove dirtyKeys from map - note we're only doing this if there is no error.
|
||||
yield clearIsDirty( group );
|
||||
} catch ( e ) {
|
||||
yield updateErrorForGroup( group, null, e );
|
||||
yield setIsRequesting( group, false );
|
||||
throw e;
|
||||
}
|
||||
// finally set the persisting state
|
||||
yield setIsRequesting( group, false );
|
||||
}
|
||||
|
||||
export function clearSettings() {
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
*/
|
||||
import { getResourceName, getResourcePrefix } from '../utils';
|
||||
|
||||
export const getSettingsGroupNames = state => {
|
||||
export const getSettingsGroupNames = ( state ) => {
|
||||
const groupNames = new Set(
|
||||
Object.keys( state ).map( resourceName => {
|
||||
Object.keys( state ).map( ( resourceName ) => {
|
||||
return getResourcePrefix( resourceName );
|
||||
} )
|
||||
);
|
||||
|
@ -14,11 +14,11 @@ export const getSettingsGroupNames = state => {
|
|||
|
||||
export const getSettings = ( state, group ) => {
|
||||
const settings = {};
|
||||
const settingIds = state[ group ] && state[ group ].data || [];
|
||||
const settingIds = ( state[ group ] && state[ group ].data ) || [];
|
||||
if ( settingIds.length === 0 ) {
|
||||
return settings;
|
||||
}
|
||||
settingIds.forEach( id => {
|
||||
settingIds.forEach( ( id ) => {
|
||||
settings[ id ] = state[ getResourceName( group, id ) ].data;
|
||||
} );
|
||||
return settings;
|
||||
|
@ -47,7 +47,7 @@ export const getSettingsForGroup = ( state, group, keys ) => {
|
|||
}, {} );
|
||||
};
|
||||
|
||||
export const isGetSettingsRequesting = ( state, group ) => {
|
||||
export const isUpdateSettingsRequesting = ( state, group ) => {
|
||||
return state[ group ] && Boolean( state[ group ].isRequesting );
|
||||
};
|
||||
|
||||
|
@ -70,9 +70,16 @@ export const isGetSettingsRequesting = ( state, group ) => {
|
|||
* @return {*} The value present in the settings state for the given
|
||||
* name.
|
||||
*/
|
||||
export function getSetting( state, group, name, fallback = false, filter = val => val ) {
|
||||
export function getSetting(
|
||||
state,
|
||||
group,
|
||||
name,
|
||||
fallback = false,
|
||||
filter = ( val ) => val
|
||||
) {
|
||||
const resourceName = getResourceName( group, name );
|
||||
const value = ( state[ resourceName ] && state[ resourceName ].data ) || fallback;
|
||||
const value =
|
||||
( state[ resourceName ] && state[ resourceName ].data ) || fallback;
|
||||
return filter( value, fallback );
|
||||
}
|
||||
|
||||
|
@ -86,7 +93,7 @@ export const getLastSettingsErrorForGroup = ( state, group ) => {
|
|||
|
||||
export const getSettingsError = ( state, group, id ) => {
|
||||
if ( ! id ) {
|
||||
return state[ group ] && state[ group ].error || false;
|
||||
return ( state[ group ] && state[ group ].error ) || false;
|
||||
}
|
||||
return state[ getResourceName( group, id ) ].error || false;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
|
@ -7,18 +6,23 @@ import { STORE_NAME } from './constants';
|
|||
import { useCallback } from '@wordpress/element';
|
||||
|
||||
export const useSettings = ( group, settingsKeys = [] ) => {
|
||||
const { requestedSettings, settingsError, isRequesting, isDirty } = useSelect(
|
||||
select => {
|
||||
const {
|
||||
requestedSettings,
|
||||
settingsError,
|
||||
isRequesting,
|
||||
isDirty,
|
||||
} = useSelect(
|
||||
( select ) => {
|
||||
const {
|
||||
getLastSettingsErrorForGroup,
|
||||
getSettingsForGroup,
|
||||
getIsDirty,
|
||||
isGetSettingsRequesting,
|
||||
isUpdateSettingsRequesting,
|
||||
} = select( STORE_NAME );
|
||||
return {
|
||||
requestedSettings: getSettingsForGroup( group, settingsKeys ),
|
||||
settingsError: Boolean( getLastSettingsErrorForGroup( group ) ),
|
||||
isRequesting: isGetSettingsRequesting( group ),
|
||||
isRequesting: isUpdateSettingsRequesting( group ),
|
||||
isDirty: getIsDirty( group, settingsKeys ),
|
||||
};
|
||||
},
|
||||
|
@ -35,14 +39,11 @@ export const useSettings = ( group, settingsKeys = [] ) => {
|
|||
},
|
||||
[ group ]
|
||||
);
|
||||
const persistSettings = useCallback(
|
||||
() => {
|
||||
// this action would simply persist all settings marked as dirty in the
|
||||
// store state and then remove the dirty record in the isDirtyMap
|
||||
persistSettingsForGroup( group );
|
||||
},
|
||||
[ group ]
|
||||
);
|
||||
const persistSettings = useCallback( () => {
|
||||
// this action would simply persist all settings marked as dirty in the
|
||||
// store state and then remove the dirty record in the isDirtyMap
|
||||
persistSettingsForGroup( group );
|
||||
}, [ group ] );
|
||||
const updateAndPersistSettings = useCallback(
|
||||
( name, data ) => {
|
||||
updateAndPersistSettingsForGroup( group, { [ name ]: data } );
|
||||
|
|
Loading…
Reference in New Issue