-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Store: If TaxJar plugin is active, do not show core settings #19535
Changes from 5 commits
df0e9f4
9d1f3d8
337513a
e7c566c
580b518
806731b
8d4fab1
4dc1307
2e6ebd3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,207 +9,92 @@ import PropTypes from 'prop-types'; | |
import { bindActionCreators } from 'redux'; | ||
import classNames from 'classnames'; | ||
import { connect } from 'react-redux'; | ||
import { find, isEmpty } from 'lodash'; | ||
import { localize } from 'i18n-calypso'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import ActionHeader from 'woocommerce/components/action-header'; | ||
import { | ||
areSettingsGeneralLoaded, | ||
areTaxCalculationsEnabled, | ||
} from 'woocommerce/state/sites/settings/general/selectors'; | ||
import { | ||
areTaxSettingsLoaded, | ||
getPricesIncludeTax, | ||
getShippingIsTaxFree, | ||
} from 'woocommerce/state/sites/settings/tax/selectors'; | ||
import ExtendedHeader from 'woocommerce/components/extended-header'; | ||
import { updateTaxesEnabledSetting } from 'woocommerce/state/sites/settings/general/actions'; | ||
import QuerySettingsGeneral from 'woocommerce/components/query-settings-general'; | ||
import { fetchTaxRates } from 'woocommerce/state/sites/meta/taxrates/actions'; | ||
import { fetchTaxSettings, updateTaxSettings } from 'woocommerce/state/sites/settings/tax/actions'; | ||
import { getLink } from 'woocommerce/lib/nav-utils'; | ||
import { fetchPlugins } from 'state/plugins/installed/actions'; | ||
import { getPlugins, isRequesting } from 'state/plugins/installed/selectors'; | ||
import { getSelectedSiteWithFallback } from 'woocommerce/state/sites/selectors'; | ||
import Main from 'components/main'; | ||
import TaxSettingsSaveButton from './save-button'; | ||
import SettingsNavigation from '../navigation'; | ||
import { successNotice, errorNotice } from 'state/notices/actions'; | ||
import StoreAddress from 'woocommerce/components/store-address'; | ||
import TaxesOptions from './taxes-options'; | ||
import TaxesRates from './taxes-rates'; | ||
import SettingsTaxesPlaceholder from './taxes-placeholder'; | ||
import SettingsTaxesTaxJar from './taxes-taxjar'; | ||
import SettingsTaxesWooCommerceServices from './taxes-wcs'; | ||
|
||
class SettingsTaxes extends Component { | ||
constructor( props ) { | ||
super( props ); | ||
this.state = { | ||
isSaving: false, | ||
pricesIncludeTaxes: props.pricesIncludeTaxes, | ||
shippingIsTaxable: props.shippingIsTaxable, | ||
taxesEnabled: props.taxesEnabled, | ||
userBeganEditing: false, | ||
}; | ||
} | ||
|
||
static propTypes = { | ||
site: PropTypes.shape( { | ||
slug: PropTypes.string, | ||
ID: PropTypes.number, | ||
} ), | ||
className: PropTypes.string, | ||
isRequestingSitePlugins: PropTypes.bool, | ||
siteId: PropTypes.number, | ||
sitePluginsLoaded: PropTypes.bool, | ||
siteSlug: PropTypes.string, | ||
taxJarPluginActive: PropTypes.bool, | ||
}; | ||
|
||
componentDidMount = () => { | ||
const { site } = this.props; | ||
const { isRequestingSitePlugins, siteId, sitePluginsLoaded } = this.props; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic is duplicated in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 4dc1307 |
||
|
||
if ( site && site.ID ) { | ||
this.props.fetchTaxSettings( site.ID ); | ||
if ( siteId && ! isRequestingSitePlugins && ! sitePluginsLoaded ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only thing that I thought could go awry here is that potentially site plugins could become stale in the context of this component. Since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you are on the Settings > Taxes page, then go to Plugins and install and activate TaxJar, then return to the Settings > Taxes page, you'll have this problem too. I'll come up with a fix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It isn't super critical imho, but figured it is worth noting. Could be handled in a subsequent PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, in 2e6ebd3 I made a change so that if you install/activate TaxJar from Calypso and return to the Taxes Settings view (in the same tab/window), at least we'll update appropriately. It doesn't solve the problem of navigating to wp-admin in a separate tab/window and messing there, but it is a start. I've written #19928 for the case where they use another window/tab to deactivate/activate the TaxJar plugin. |
||
this.props.fetchPlugins( [ siteId ] ); | ||
} | ||
}; | ||
|
||
componentWillReceiveProps = newProps => { | ||
if ( ! this.state.userBeganEditing ) { | ||
const { site } = this.props; | ||
const newSiteId = ( newProps.site && newProps.site.ID ) || null; | ||
const oldSiteId = ( site && site.ID ) || null; | ||
if ( oldSiteId !== newSiteId ) { | ||
this.props.fetchTaxSettings( newSiteId ); | ||
} | ||
const { isRequestingSitePlugins, siteId, sitePluginsLoaded } = newProps; | ||
|
||
this.setState( { | ||
pricesIncludeTaxes: newProps.pricesIncludeTaxes, | ||
shippingIsTaxable: newProps.shippingIsTaxable, | ||
taxesEnabled: newProps.taxesEnabled, | ||
} ); | ||
if ( siteId && ! isRequestingSitePlugins && ! sitePluginsLoaded ) { | ||
this.props.fetchPlugins( [ siteId ] ); | ||
} | ||
}; | ||
|
||
onEnabledChange = () => { | ||
this.setState( { taxesEnabled: ! this.state.taxesEnabled, userBeganEditing: true } ); | ||
}; | ||
|
||
onCheckboxChange = event => { | ||
const option = event.target.name; | ||
const value = event.target.checked; | ||
this.setState( { [ option ]: value, userBeganEditing: true } ); | ||
}; | ||
|
||
pageHasChanges = () => { | ||
return this.state.userBeganEditing; | ||
}; | ||
|
||
onSave = ( event, onSuccessExtra ) => { | ||
const { site, translate } = this.props; | ||
|
||
event.preventDefault(); | ||
this.setState( { isSaving: true } ); | ||
|
||
const onSuccess = () => { | ||
this.setState( { isSaving: false, userBeganEditing: false } ); | ||
if ( onSuccessExtra ) { | ||
onSuccessExtra(); | ||
} | ||
return successNotice( translate( 'Settings updated successfully.' ), { | ||
duration: 4000, | ||
displayOnNextPage: true, | ||
} ); | ||
}; | ||
|
||
const onFailure = () => { | ||
this.setState( { isSaving: false } ); | ||
return errorNotice( | ||
translate( 'There was a problem saving your changes. Please try again.' ) | ||
); | ||
}; | ||
|
||
// TODO - chain these | ||
|
||
this.props.updateTaxesEnabledSetting( site.ID, this.state.taxesEnabled ); | ||
|
||
this.props.updateTaxSettings( | ||
site.ID, | ||
this.state.pricesIncludeTaxes || false, | ||
! this.state.shippingIsTaxable, // note the inversion | ||
onSuccess, | ||
onFailure | ||
); | ||
}; | ||
|
||
onAddressChange = address => { | ||
const { site } = this.props; | ||
this.props.fetchTaxRates( site.ID, address, true ); | ||
}; | ||
|
||
render = () => { | ||
const { className, loaded, site, translate } = this.props; | ||
const { className, site, siteId, sitePluginsLoaded, siteSlug, taxJarPluginActive } = this.props; | ||
|
||
if ( ! loaded ) { | ||
// TODO placeholder | ||
return <QuerySettingsGeneral siteId={ site.ID } />; | ||
} | ||
|
||
const breadcrumbs = [ | ||
<a href={ getLink( '/store/settings/:site/', site ) }>{ translate( 'Settings' ) }</a>, | ||
<span>{ translate( 'Taxes' ) }</span>, | ||
]; | ||
const renderTaxesByTaxJar = taxJarPluginActive; | ||
const renderTaxesByWCS = sitePluginsLoaded && ! taxJarPluginActive; | ||
const renderPlaceholder = ! renderTaxesByTaxJar && ! renderTaxesByWCS; | ||
|
||
return ( | ||
<Main className={ classNames( 'settings-taxes', className ) }> | ||
<ActionHeader breadcrumbs={ breadcrumbs }> | ||
<TaxSettingsSaveButton onSave={ this.onSave } /> | ||
</ActionHeader> | ||
<SettingsNavigation activeSection="taxes" /> | ||
<div className="taxes__nexus"> | ||
<ExtendedHeader | ||
label={ translate( 'Store Address' ) } | ||
description={ translate( | ||
'The address of where your business is located for tax purposes.' | ||
) } | ||
/> | ||
<StoreAddress | ||
className="taxes__store-address" | ||
onSetAddress={ this.onAddressChange } | ||
showLabel={ false } | ||
/> | ||
</div> | ||
<TaxesRates | ||
taxesEnabled={ this.state.taxesEnabled } | ||
onEnabledChange={ this.onEnabledChange } | ||
site={ site } | ||
/> | ||
<TaxesOptions | ||
onCheckboxChange={ this.onCheckboxChange } | ||
pricesIncludeTaxes={ this.state.pricesIncludeTaxes } | ||
shippingIsTaxable={ this.state.shippingIsTaxable } | ||
/> | ||
{ renderPlaceholder && <SettingsTaxesPlaceholder siteSlug={ siteSlug } /> } | ||
{ renderTaxesByTaxJar && <SettingsTaxesTaxJar site={ site } /> } | ||
{ renderTaxesByWCS && ( | ||
<SettingsTaxesWooCommerceServices siteId={ siteId } siteSlug={ siteSlug } /> | ||
) } | ||
</Main> | ||
); | ||
}; | ||
} | ||
|
||
function mapStateToProps( state ) { | ||
const loaded = areTaxSettingsLoaded( state ) && areSettingsGeneralLoaded( state ); | ||
const site = getSelectedSiteWithFallback( state ); | ||
const pricesIncludeTaxes = getPricesIncludeTax( state ); | ||
const shippingIsTaxable = ! getShippingIsTaxFree( state ); // note the inversion | ||
const taxesEnabled = areTaxCalculationsEnabled( state ); | ||
const siteId = site ? site.ID : null; | ||
const siteSlug = site ? site.slug : ''; | ||
|
||
const isRequestingSitePlugins = site ? isRequesting( state, siteId ) : false; | ||
const sitePlugins = site ? getPlugins( state, [ site.ID ] ) : []; | ||
const sitePluginsLoaded = ! isEmpty( sitePlugins ); | ||
const taxJarPluginActive = !! find( sitePlugins, { | ||
slug: 'taxjar-simplified-taxes-for-woocommerce', | ||
active: true, | ||
} ); | ||
|
||
return { | ||
loaded, | ||
pricesIncludeTaxes, | ||
shippingIsTaxable, | ||
isRequestingSitePlugins, | ||
site, | ||
taxesEnabled, | ||
siteId, | ||
sitePluginsLoaded, | ||
siteSlug, | ||
taxJarPluginActive, | ||
}; | ||
} | ||
|
||
function mapDispatchToProps( dispatch ) { | ||
return bindActionCreators( | ||
{ | ||
fetchTaxRates, | ||
fetchTaxSettings, | ||
updateTaxesEnabledSetting, | ||
updateTaxSettings, | ||
fetchPlugins, | ||
}, | ||
dispatch | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* External dependencies | ||
* | ||
* @format | ||
*/ | ||
|
||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { localize } from 'i18n-calypso'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import ActionHeader from 'woocommerce/components/action-header'; | ||
import { getLink } from 'woocommerce/lib/nav-utils'; | ||
import SettingsNavigation from '../navigation'; | ||
|
||
const SettingsTaxesPlaceholder = ( { siteSlug, translate } ) => { | ||
const breadcrumbs = [ | ||
<a href={ getLink( '/store/settings/:site/', { slug: siteSlug } ) }> | ||
{ translate( 'Settings' ) } | ||
</a>, | ||
<span>{ translate( 'Taxes' ) }</span>, | ||
]; | ||
|
||
return ( | ||
<div> | ||
<ActionHeader breadcrumbs={ breadcrumbs } /> | ||
<SettingsNavigation activeSection="taxes" /> | ||
<div className="taxes__placeholder card" /> | ||
</div> | ||
); | ||
}; | ||
|
||
SettingsTaxesPlaceholder.propTypes = { | ||
siteSlug: PropTypes.string.isRequired, | ||
translate: PropTypes.func.isRequired, | ||
}; | ||
|
||
export default localize( SettingsTaxesPlaceholder ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,25 +41,21 @@ import QuerySettingsGeneral from 'woocommerce/components/query-settings-general' | |
class TaxesRates extends Component { | ||
static propTypes = { | ||
onEnabledChange: PropTypes.func.isRequired, | ||
site: PropTypes.shape( { | ||
slug: PropTypes.string, | ||
} ), | ||
siteId: PropTypes.number.isRequired, | ||
}; | ||
|
||
componentDidMount = () => { | ||
const { address, loadedSettingsGeneral, loadedTaxRates, site } = this.props; | ||
const { address, loadedSettingsGeneral, loadedTaxRates, siteId } = this.props; | ||
|
||
if ( site && site.ID ) { | ||
if ( loadedSettingsGeneral && ! loadedTaxRates ) { | ||
this.props.fetchTaxRates( site.ID, address ); | ||
} | ||
if ( loadedSettingsGeneral && ! loadedTaxRates ) { | ||
this.props.fetchTaxRates( siteId, address ); | ||
} | ||
}; | ||
|
||
componentWillReceiveProps = nextProps => { | ||
if ( nextProps.loadedSettingsGeneral ) { | ||
if ( ! nextProps.loadedTaxRates ) { | ||
this.props.fetchTaxRates( nextProps.site.ID, nextProps.address ); | ||
this.props.fetchTaxRates( nextProps.siteId, nextProps.address ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could these two There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 4dc1307 |
||
} | ||
} | ||
}; | ||
|
@@ -263,8 +259,8 @@ class TaxesRates extends Component { | |
return ( | ||
<div className="taxes__taxes-taxjar-notice"> | ||
{ translate( | ||
'Sales tax calculations are provided by a third party: TaxJar. By enabling this option, ' + | ||
'TaxJar will have access to some of your data.' | ||
'Sales tax calculations are provided by WooCommerce Services. When this option is enabled, ' + | ||
'WooCommerce Services will share some of your data with a third party.' | ||
) } | ||
<ExternalLink | ||
icon | ||
|
@@ -280,7 +276,7 @@ class TaxesRates extends Component { | |
|
||
render = () => { | ||
const { | ||
site, | ||
siteId, | ||
loadedSettingsGeneral, | ||
loadedTaxRates, | ||
onEnabledChange, | ||
|
@@ -289,7 +285,7 @@ class TaxesRates extends Component { | |
} = this.props; | ||
|
||
if ( ! loadedSettingsGeneral ) { | ||
return <QuerySettingsGeneral siteId={ site && site.ID } />; | ||
return <QuerySettingsGeneral siteId={ siteId } />; | ||
} | ||
|
||
if ( ! loadedTaxRates ) { | ||
|
@@ -317,15 +313,11 @@ class TaxesRates extends Component { | |
} | ||
|
||
function mapStateToProps( state, ownProps ) { | ||
let siteId = undefined; | ||
if ( ownProps.site ) { | ||
siteId = ownProps.site.ID; | ||
} | ||
const address = getStoreLocation( state, siteId ); | ||
const loadedSettingsGeneral = areSettingsGeneralLoaded( state, siteId ); | ||
const areTaxesEnabled = areTaxCalculationsEnabled( state, siteId ); | ||
const loadedTaxRates = areTaxRatesLoaded( state, siteId ); | ||
const taxRates = getTaxRates( state, siteId ); | ||
const address = getStoreLocation( state, ownProps.siteId ); | ||
const loadedSettingsGeneral = areSettingsGeneralLoaded( state, ownProps.siteId ); | ||
const areTaxesEnabled = areTaxCalculationsEnabled( state, ownProps.siteId ); | ||
const loadedTaxRates = areTaxRatesLoaded( state, ownProps.siteId ); | ||
const taxRates = getTaxRates( state, ownProps.siteId ); | ||
|
||
return { | ||
address, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing
isRequestingSitePlugins
, andsiteSlug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 8659592