Options: Add data store (https://github.com/woocommerce/woocommerce-admin/pull/4144)
This commit is contained in:
parent
9be6bdd841
commit
41eeb4f9f9
|
@ -4,7 +4,7 @@
|
||||||
import { __, sprintf } from '@wordpress/i18n';
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
import { Fragment, Suspense, lazy, useState } from '@wordpress/element';
|
import { Fragment, Suspense, lazy, useState } from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import { partial, get } from 'lodash';
|
import { partial } from 'lodash';
|
||||||
import { Dropdown, Button, Icon } from '@wordpress/components';
|
import { Dropdown, Button, Icon } from '@wordpress/components';
|
||||||
import { applyFilters } from '@wordpress/hooks';
|
import { applyFilters } from '@wordpress/hooks';
|
||||||
import { Icon as WPIcon, plusCircleFilled } from '@wordpress/icons';
|
import { Icon as WPIcon, plusCircleFilled } from '@wordpress/icons';
|
||||||
|
@ -15,6 +15,7 @@ import { Icon as WPIcon, plusCircleFilled } from '@wordpress/icons';
|
||||||
import { H, Spinner } from '@woocommerce/components';
|
import { H, Spinner } from '@woocommerce/components';
|
||||||
import {
|
import {
|
||||||
SETTINGS_STORE_NAME,
|
SETTINGS_STORE_NAME,
|
||||||
|
OPTIONS_STORE_NAME,
|
||||||
useUserPreferences,
|
useUserPreferences,
|
||||||
} from '@woocommerce/data';
|
} from '@woocommerce/data';
|
||||||
|
|
||||||
|
@ -329,8 +330,7 @@ const CustomizableDashboard = ( {
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getOptions } = select( 'wc-api' );
|
const { getOption } = select( OPTIONS_STORE_NAME );
|
||||||
|
|
||||||
const { woocommerce_default_date_range: defaultDateRange } = select(
|
const { woocommerce_default_date_range: defaultDateRange } = select(
|
||||||
SETTINGS_STORE_NAME
|
SETTINGS_STORE_NAME
|
||||||
).getSetting( 'wc_admin', 'wcAdminSettings' );
|
).getSetting( 'wc_admin', 'wcAdminSettings' );
|
||||||
|
@ -340,16 +340,13 @@ export default compose(
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( isOnboardingEnabled() ) {
|
if ( isOnboardingEnabled() ) {
|
||||||
const options = getOptions( [
|
withSelectData.homepageEnabled =
|
||||||
'woocommerce_task_list_complete',
|
window.wcAdminFeatures.homepage &&
|
||||||
'woocommerce_task_list_hidden',
|
getOption( 'woocommerce_homescreen_enabled' ) === 'yes';
|
||||||
] );
|
|
||||||
withSelectData.taskListHidden =
|
withSelectData.taskListHidden =
|
||||||
get( options, [ 'woocommerce_task_list_hidden' ], 'no' ) ===
|
getOption( 'woocommerce_task_list_hidden' ) === 'yes';
|
||||||
'yes';
|
|
||||||
withSelectData.taskListComplete =
|
withSelectData.taskListComplete =
|
||||||
get( options, [ 'woocommerce_task_list_complete' ], 'no' ) ===
|
getOption( 'woocommerce_task_list_complete' ) === 'yes';
|
||||||
'yes';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return withSelectData;
|
return withSelectData;
|
||||||
|
|
|
@ -51,6 +51,7 @@ export function getProductIdsForCart(
|
||||||
installedPlugins
|
installedPlugins
|
||||||
) {
|
) {
|
||||||
const onboarding = getSetting( 'onboarding', {} );
|
const onboarding = getSetting( 'onboarding', {} );
|
||||||
|
const productIds = [];
|
||||||
|
|
||||||
// The population of onboarding.productTypes only happens if the task list should be shown
|
// The population of onboarding.productTypes only happens if the task list should be shown
|
||||||
// so bail early if it isn't present.
|
// so bail early if it isn't present.
|
||||||
|
@ -58,7 +59,6 @@ export function getProductIdsForCart(
|
||||||
return productIds;
|
return productIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
const productIds = [];
|
|
||||||
const productTypes = profileItems.product_types || [];
|
const productTypes = profileItems.product_types || [];
|
||||||
|
|
||||||
productTypes.forEach( ( productType ) => {
|
productTypes.forEach( ( productType ) => {
|
||||||
|
|
|
@ -11,9 +11,13 @@ import {
|
||||||
} from '@wordpress/element';
|
} from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { get } from 'lodash';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommerce dependencies
|
||||||
|
*/
|
||||||
|
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
|
@ -21,9 +25,9 @@ import QuickLinks from '../quick-links';
|
||||||
import StatsOverview from './stats-overview';
|
import StatsOverview from './stats-overview';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
import { isOnboardingEnabled } from 'dashboard/utils';
|
import { isOnboardingEnabled } from 'dashboard/utils';
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
import TaskListPlaceholder from '../task-list/placeholder';
|
import TaskListPlaceholder from '../task-list/placeholder';
|
||||||
import InboxPanel from '../header/activity-panel/panels/inbox';
|
import InboxPanel from '../header/activity-panel/panels/inbox';
|
||||||
|
import withWCApiSelect from 'wc-api/with-select';
|
||||||
|
|
||||||
const TaskList = lazy( () =>
|
const TaskList = lazy( () =>
|
||||||
import( /* webpackChunkName: "task-list" */ '../task-list' )
|
import( /* webpackChunkName: "task-list" */ '../task-list' )
|
||||||
|
@ -138,32 +142,27 @@ Layout.propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withWCApiSelect( ( select ) => {
|
||||||
const {
|
const {
|
||||||
getOptions,
|
|
||||||
getUndoDismissRequesting,
|
getUndoDismissRequesting,
|
||||||
isGetOptionsRequesting,
|
|
||||||
} = select( 'wc-api' );
|
} = select( 'wc-api' );
|
||||||
|
const { isUndoRequesting } = getUndoDismissRequesting();
|
||||||
|
const { getOption, isResolving } = select( OPTIONS_STORE_NAME );
|
||||||
|
|
||||||
if ( isOnboardingEnabled() ) {
|
if ( isOnboardingEnabled() ) {
|
||||||
const options = getOptions( [
|
|
||||||
'woocommerce_task_list_complete',
|
|
||||||
'woocommerce_task_list_hidden',
|
|
||||||
] );
|
|
||||||
const { isUndoRequesting } = getUndoDismissRequesting();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isUndoRequesting,
|
isUndoRequesting,
|
||||||
requestingTaskList: isGetOptionsRequesting( [
|
taskListComplete:
|
||||||
|
getOption( 'woocommerce_task_list_complete' ) === 'yes',
|
||||||
|
taskListHidden:
|
||||||
|
getOption( 'woocommerce_task_list_hidden' ) === 'yes',
|
||||||
|
requestingTaskList:
|
||||||
|
isResolving( 'getOption', [
|
||||||
'woocommerce_task_list_complete',
|
'woocommerce_task_list_complete',
|
||||||
|
] ) ||
|
||||||
|
isResolving( 'getOption', [
|
||||||
'woocommerce_task_list_hidden',
|
'woocommerce_task_list_hidden',
|
||||||
] ),
|
] ),
|
||||||
taskListComplete:
|
|
||||||
get( options, [ 'woocommerce_task_list_complete' ] ) ===
|
|
||||||
'yes',
|
|
||||||
taskListHidden:
|
|
||||||
get( options, [ 'woocommerce_task_list_hidden' ] ) ===
|
|
||||||
'yes',
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { withSelect } from '@wordpress/data';
|
||||||
import { Component, lazy, Suspense } from '@wordpress/element';
|
import { Component, lazy, Suspense } from '@wordpress/element';
|
||||||
import { Router, Route, Switch } from 'react-router-dom';
|
import { Router, Route, Switch } from 'react-router-dom';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { get, isFunction } from 'lodash';
|
import { get, isFunction, identity } from 'lodash';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
|
@ -14,7 +14,12 @@ import { get, isFunction } from 'lodash';
|
||||||
import { useFilters, Spinner } from '@woocommerce/components';
|
import { useFilters, Spinner } from '@woocommerce/components';
|
||||||
import { getHistory } from '@woocommerce/navigation';
|
import { getHistory } from '@woocommerce/navigation';
|
||||||
import { getSetting } from '@woocommerce/wc-admin-settings';
|
import { getSetting } from '@woocommerce/wc-admin-settings';
|
||||||
import { PLUGINS_STORE_NAME, withPluginsHydration } from '@woocommerce/data';
|
import {
|
||||||
|
OPTIONS_STORE_NAME,
|
||||||
|
PLUGINS_STORE_NAME,
|
||||||
|
withPluginsHydration,
|
||||||
|
withOptionsHydration,
|
||||||
|
} from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -25,7 +30,6 @@ import Header from 'header';
|
||||||
import Notices from './notices';
|
import Notices from './notices';
|
||||||
import { recordPageView } from 'lib/tracks';
|
import { recordPageView } from 'lib/tracks';
|
||||||
import TransientNotices from './transient-notices';
|
import TransientNotices from './transient-notices';
|
||||||
import withWCApiSelect from 'wc-api/with-select';
|
|
||||||
const StoreAlerts = lazy( () =>
|
const StoreAlerts = lazy( () =>
|
||||||
import( /* webpackChunkName: "store-alerts" */ './store-alerts' )
|
import( /* webpackChunkName: "store-alerts" */ './store-alerts' )
|
||||||
);
|
);
|
||||||
|
@ -211,13 +215,16 @@ class _PageLayout extends Component {
|
||||||
export const PageLayout = compose(
|
export const PageLayout = compose(
|
||||||
// Use the useFilters HoC so PageLayout is re-rendered when filters are used to add new pages or reports
|
// Use the useFilters HoC so PageLayout is re-rendered when filters are used to add new pages or reports
|
||||||
useFilters( [ PAGES_FILTER, REPORTS_FILTER ] ),
|
useFilters( [ PAGES_FILTER, REPORTS_FILTER ] ),
|
||||||
withWCApiSelect( ( select ) => {
|
window.wcSettings.preloadOptions
|
||||||
const { getOptions } = select( 'wc-api' );
|
? withOptionsHydration( {
|
||||||
const options = getOptions( [ 'woocommerce_homescreen_enabled' ] );
|
...window.wcSettings.preloadOptions,
|
||||||
|
} )
|
||||||
|
: identity,
|
||||||
|
withSelect( ( select ) => {
|
||||||
|
const { getOption } = select( OPTIONS_STORE_NAME );
|
||||||
const homepageEnabled =
|
const homepageEnabled =
|
||||||
window.wcAdminFeatures.homepage &&
|
window.wcAdminFeatures.homepage &&
|
||||||
get( options, [ 'woocommerce_homescreen_enabled' ], false ) ===
|
getOption( 'woocommerce_homescreen_enabled' ) === 'yes';
|
||||||
'yes';
|
|
||||||
return { homepageEnabled };
|
return { homepageEnabled };
|
||||||
} )
|
} )
|
||||||
)( _PageLayout );
|
)( _PageLayout );
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
*/
|
*/
|
||||||
import { getSetting } from '@woocommerce/wc-admin-settings';
|
import { getSetting } from '@woocommerce/wc-admin-settings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommerce dependencies
|
||||||
|
*/
|
||||||
|
import { withOptionsHydration } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
|
@ -26,4 +31,6 @@ const MarketingOverview = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MarketingOverview;
|
export default withOptionsHydration( {
|
||||||
|
...( window.wcSettings.preloadOptions || {} ),
|
||||||
|
} )( MarketingOverview );
|
||||||
|
|
|
@ -2,24 +2,23 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { get } from 'lodash';
|
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import Gridicon from 'gridicons';
|
import Gridicon from 'gridicons';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
*/
|
*/
|
||||||
import { Card } from '@woocommerce/components';
|
import { Card } from '@woocommerce/components';
|
||||||
|
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
import { recordEvent } from 'lib/tracks';
|
import { recordEvent } from 'lib/tracks';
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
import WelcomeImage from './images/welcome.svg';
|
import WelcomeImage from './images/welcome.svg';
|
||||||
|
|
||||||
const WelcomeCard = ( {
|
const WelcomeCard = ( {
|
||||||
|
@ -72,17 +71,17 @@ export { WelcomeCard }
|
||||||
// default export
|
// default export
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getOptions, isUpdateOptionsRequesting } = select( 'wc-api' );
|
const { getOption, isOptionsUpdating } = select( OPTIONS_STORE_NAME );
|
||||||
const hideOptionName = 'woocommerce_marketing_overview_welcome_hidden';
|
const isUpdateRequesting = isOptionsUpdating();
|
||||||
const options = getOptions( [ hideOptionName ] );
|
|
||||||
const isHidden = get( options, [ hideOptionName ], 'no' ) === 'yes';
|
|
||||||
const isUpdateRequesting = Boolean( isUpdateOptionsRequesting( [ hideOptionName ] ) );
|
|
||||||
return {
|
return {
|
||||||
isHidden: isHidden || isUpdateRequesting,
|
isHidden:
|
||||||
|
getOption( 'woocommerce_marketing_overview_welcome_hidden' ) ===
|
||||||
|
'yes' || isUpdateRequesting,
|
||||||
};
|
};
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
return {
|
return {
|
||||||
updateOptions,
|
updateOptions,
|
||||||
};
|
};
|
||||||
|
|
|
@ -247,7 +247,9 @@ const hydrateSettings =
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getNotes } = select( 'wc-api' );
|
const { getNotes } = select( 'wc-api' );
|
||||||
const { getProfileItems, getOnboardingError } = select( ONBOARDING_STORE_NAME );
|
const { getProfileItems, getOnboardingError } = select(
|
||||||
|
ONBOARDING_STORE_NAME
|
||||||
|
);
|
||||||
const { getActivePlugins } = select( PLUGINS_STORE_NAME );
|
const { getActivePlugins } = select( PLUGINS_STORE_NAME );
|
||||||
|
|
||||||
const notesQuery = {
|
const notesQuery = {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { __, _n, sprintf } from '@wordpress/i18n';
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import { Component } from '@wordpress/element';
|
import { Component } from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
import { filter } from 'lodash';
|
import { filter } from 'lodash';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,6 +17,7 @@ import {
|
||||||
pluginNames,
|
pluginNames,
|
||||||
ONBOARDING_STORE_NAME,
|
ONBOARDING_STORE_NAME,
|
||||||
PLUGINS_STORE_NAME,
|
PLUGINS_STORE_NAME,
|
||||||
|
OPTIONS_STORE_NAME
|
||||||
} from '@woocommerce/data';
|
} from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +29,6 @@ import ManagementIcon from './images/management';
|
||||||
import SalesTaxIcon from './images/sales_tax';
|
import SalesTaxIcon from './images/sales_tax';
|
||||||
import ShippingLabels from './images/shipping_labels';
|
import ShippingLabels from './images/shipping_labels';
|
||||||
import SpeedIcon from './images/speed';
|
import SpeedIcon from './images/speed';
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
import { recordEvent } from 'lib/tracks';
|
import { recordEvent } from 'lib/tracks';
|
||||||
|
|
||||||
class Benefits extends Component {
|
class Benefits extends Component {
|
||||||
|
@ -108,12 +108,12 @@ class Benefits extends Component {
|
||||||
goToNextStep();
|
goToNextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
async startPluginInstall() {
|
startPluginInstall() {
|
||||||
const { updateProfileItems, updateOptions } = this.props;
|
const { updateProfileItems, updateOptions } = this.props;
|
||||||
|
|
||||||
this.setState( { isInstalling: true } );
|
this.setState( { isInstalling: true } );
|
||||||
|
|
||||||
await updateOptions( {
|
updateOptions( {
|
||||||
woocommerce_setup_jetpack_opted_in: true,
|
woocommerce_setup_jetpack_opted_in: true,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ export default compose(
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { updateProfileItems } = dispatch( ONBOARDING_STORE_NAME );
|
const { updateProfileItems } = dispatch( ONBOARDING_STORE_NAME );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { Component } from '@wordpress/element';
|
import { Component } from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
import { get } from 'lodash';
|
|
||||||
import interpolateComponents from 'interpolate-components';
|
import interpolateComponents from 'interpolate-components';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
@ -14,11 +13,15 @@ import {
|
||||||
Modal,
|
Modal,
|
||||||
} from '@wordpress/components';
|
} from '@wordpress/components';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommerce dependencies
|
||||||
|
*/
|
||||||
|
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { Link } from '@woocommerce/components';
|
import { Link } from '@woocommerce/components';
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
|
|
||||||
class UsageModal extends Component {
|
class UsageModal extends Component {
|
||||||
constructor( props ) {
|
constructor( props ) {
|
||||||
|
@ -159,20 +162,15 @@ class UsageModal extends Component {
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const {
|
const {
|
||||||
getOptions,
|
getOption,
|
||||||
getOptionsError,
|
getOptionsUpdatingError,
|
||||||
isUpdateOptionsRequesting,
|
isOptionsUpdating,
|
||||||
} = select( 'wc-api' );
|
} = select( OPTIONS_STORE_NAME );
|
||||||
|
|
||||||
const options = getOptions( [ 'woocommerce_allow_tracking' ] );
|
|
||||||
const allowTracking =
|
const allowTracking =
|
||||||
get( options, [ 'woocommerce_allow_tracking' ], false ) === 'yes';
|
getOption( 'woocommerce_allow_tracking' ) === 'yes';
|
||||||
const isRequesting = Boolean(
|
const isRequesting = Boolean( isOptionsUpdating() );
|
||||||
isUpdateOptionsRequesting( [ 'woocommerce_allow_tracking' ] )
|
const hasErrors = Boolean( getOptionsUpdatingError() );
|
||||||
);
|
|
||||||
const hasErrors = Boolean(
|
|
||||||
getOptionsError( [ 'woocommerce_allow_tracking' ] )
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
allowTracking,
|
allowTracking,
|
||||||
|
@ -182,7 +180,7 @@ export default compose(
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createNotice,
|
createNotice,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { Component, cloneElement, Fragment } from '@wordpress/element';
|
import { Component, cloneElement, Fragment } from '@wordpress/element';
|
||||||
import { get, isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {
|
import {
|
||||||
|
@ -21,7 +21,11 @@ import { Icon, check, chevronRight } from '@wordpress/icons';
|
||||||
*/
|
*/
|
||||||
import { H, List, EllipsisMenu } from '@woocommerce/components';
|
import { H, List, EllipsisMenu } from '@woocommerce/components';
|
||||||
import { updateQueryString } from '@woocommerce/navigation';
|
import { updateQueryString } from '@woocommerce/navigation';
|
||||||
import { ONBOARDING_STORE_NAME, PLUGINS_STORE_NAME } from '@woocommerce/data';
|
import {
|
||||||
|
PLUGINS_STORE_NAME,
|
||||||
|
OPTIONS_STORE_NAME,
|
||||||
|
ONBOARDING_STORE_NAME,
|
||||||
|
} from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -118,7 +122,7 @@ class TaskDashboard extends Component {
|
||||||
|
|
||||||
return getAllTasks( {
|
return getAllTasks( {
|
||||||
profileItems,
|
profileItems,
|
||||||
options: taskListPayments,
|
taskListPayments,
|
||||||
query,
|
query,
|
||||||
toggleCartModal: this.toggleCartModal.bind( this ),
|
toggleCartModal: this.toggleCartModal.bind( this ),
|
||||||
installedPlugins,
|
installedPlugins,
|
||||||
|
@ -383,7 +387,7 @@ class TaskDashboard extends Component {
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select, props ) => {
|
withSelect( ( select, props ) => {
|
||||||
const { getProfileItems } = select( ONBOARDING_STORE_NAME );
|
const { getProfileItems } = select( ONBOARDING_STORE_NAME );
|
||||||
const { getOptions } = select( 'wc-api' );
|
const { getOption } = select( OPTIONS_STORE_NAME );
|
||||||
const {
|
const {
|
||||||
getActivePlugins,
|
getActivePlugins,
|
||||||
getInstalledPlugins,
|
getInstalledPlugins,
|
||||||
|
@ -391,28 +395,18 @@ export default compose(
|
||||||
} = select( PLUGINS_STORE_NAME );
|
} = select( PLUGINS_STORE_NAME );
|
||||||
const profileItems = getProfileItems();
|
const profileItems = getProfileItems();
|
||||||
|
|
||||||
const options = getOptions( [
|
const modalDismissed =
|
||||||
'woocommerce_task_list_welcome_modal_dismissed',
|
getOption( 'woocommerce_task_list_welcome_modal_dismissed' ) ||
|
||||||
'woocommerce_task_list_hidden',
|
false;
|
||||||
'woocommerce_task_list_tracked_completed_tasks',
|
const taskListPayments = getOption( 'woocommerce_task_list_payments' );
|
||||||
] );
|
const trackedCompletedTasks =
|
||||||
const modalDismissed = get(
|
getOption( 'woocommerce_task_list_tracked_completed_tasks' ) || [];
|
||||||
options,
|
const payments = getOption( 'woocommerce_task_list_payments' );
|
||||||
[ 'woocommerce_task_list_welcome_modal_dismissed' ],
|
|
||||||
false
|
|
||||||
);
|
|
||||||
const taskListPayments = getOptions( [
|
|
||||||
'woocommerce_task_list_payments',
|
|
||||||
] );
|
|
||||||
const trackedCompletedTasks = get(
|
|
||||||
options,
|
|
||||||
[ 'woocommerce_task_list_tracked_completed_tasks' ],
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
const installedPlugins = getInstalledPlugins();
|
const installedPlugins = getInstalledPlugins();
|
||||||
const tasks = getAllTasks( {
|
const tasks = getAllTasks( {
|
||||||
profileItems,
|
profileItems,
|
||||||
options: getOptions( [ 'woocommerce_task_list_payments' ] ),
|
options: payments,
|
||||||
query: props.query,
|
query: props.query,
|
||||||
installedPlugins,
|
installedPlugins,
|
||||||
} );
|
} );
|
||||||
|
@ -437,7 +431,7 @@ export default compose(
|
||||||
};
|
};
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
return {
|
return {
|
||||||
updateOptions,
|
updateOptions,
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { applyFilters } from '@wordpress/hooks';
|
import { applyFilters } from '@wordpress/hooks';
|
||||||
import { get } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
|
@ -25,7 +24,7 @@ import Payments from './tasks/payments';
|
||||||
|
|
||||||
export function getAllTasks( {
|
export function getAllTasks( {
|
||||||
profileItems,
|
profileItems,
|
||||||
options,
|
taskListPayments,
|
||||||
query,
|
query,
|
||||||
toggleCartModal,
|
toggleCartModal,
|
||||||
installedPlugins,
|
installedPlugins,
|
||||||
|
@ -55,15 +54,11 @@ export function getAllTasks( {
|
||||||
installedPlugins
|
installedPlugins
|
||||||
);
|
);
|
||||||
|
|
||||||
const paymentsCompleted = get(
|
const paymentsCompleted = Boolean(
|
||||||
options,
|
taskListPayments && taskListPayments.completed
|
||||||
[ 'woocommerce_task_list_payments', 'completed' ],
|
|
||||||
false
|
|
||||||
);
|
);
|
||||||
const paymentsSkipped = get(
|
const paymentsSkipped = Boolean(
|
||||||
options,
|
taskListPayments && taskListPayments.skipped
|
||||||
[ 'woocommerce_task_list_payments', 'skipped' ],
|
|
||||||
false
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const tasks = [
|
const tasks = [
|
||||||
|
|
|
@ -6,8 +6,8 @@ import apiFetch from '@wordpress/api-fetch';
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component, Fragment } from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import { difference, filter } from 'lodash';
|
import { filter } from 'lodash';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
|
@ -20,13 +20,13 @@ import {
|
||||||
} from '@woocommerce/components';
|
} from '@woocommerce/components';
|
||||||
import { getHistory, getNewPath } from '@woocommerce/navigation';
|
import { getHistory, getNewPath } from '@woocommerce/navigation';
|
||||||
import { getSetting, setSetting } from '@woocommerce/wc-admin-settings';
|
import { getSetting, setSetting } from '@woocommerce/wc-admin-settings';
|
||||||
|
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { queueRecordEvent, recordEvent } from 'lib/tracks';
|
import { queueRecordEvent, recordEvent } from 'lib/tracks';
|
||||||
import { WC_ADMIN_NAMESPACE } from 'wc-api/constants';
|
import { WC_ADMIN_NAMESPACE } from 'wc-api/constants';
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
|
|
||||||
class Appearance extends Component {
|
class Appearance extends Component {
|
||||||
constructor( props ) {
|
constructor( props ) {
|
||||||
|
@ -43,7 +43,9 @@ class Appearance extends Component {
|
||||||
isPending: false,
|
isPending: false,
|
||||||
logo: null,
|
logo: null,
|
||||||
stepIndex: 0,
|
stepIndex: 0,
|
||||||
storeNoticeText: props.options.woocommerce_demo_store_notice || '',
|
isUpdatingLogo: false,
|
||||||
|
isUpdatingNotice: false,
|
||||||
|
storeNoticeText: props.demoStoreNotice || '',
|
||||||
};
|
};
|
||||||
|
|
||||||
this.completeStep = this.completeStep.bind( this );
|
this.completeStep = this.completeStep.bind( this );
|
||||||
|
@ -63,18 +65,9 @@ class Appearance extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidUpdate( prevProps ) {
|
componentDidUpdate( prevProps ) {
|
||||||
const { isPending, logo, stepIndex } = this.state;
|
const { isPending, logo } = this.state;
|
||||||
const {
|
const { demoStoreNotice } = this.props;
|
||||||
createNotice,
|
|
||||||
errors,
|
|
||||||
hasErrors,
|
|
||||||
isRequesting,
|
|
||||||
options,
|
|
||||||
} = this.props;
|
|
||||||
const step = this.getSteps()[ stepIndex ].key;
|
|
||||||
const isRequestSuccessful =
|
|
||||||
! isRequesting && prevProps.isRequesting && ! hasErrors;
|
|
||||||
|
|
||||||
if ( logo && ! logo.url && ! isPending ) {
|
if ( logo && ! logo.url && ! isPending ) {
|
||||||
/* eslint-disable react/no-did-update-set-state */
|
/* eslint-disable react/no-did-update-set-state */
|
||||||
|
@ -93,38 +86,15 @@ class Appearance extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
options.woocommerce_demo_store_notice &&
|
demoStoreNotice &&
|
||||||
prevProps.options.woocommerce_demo_store_notice !==
|
prevProps.demoStoreNotice !== demoStoreNotice
|
||||||
options.woocommerce_demo_store_notice
|
|
||||||
) {
|
) {
|
||||||
/* eslint-disable react/no-did-update-set-state */
|
/* eslint-disable react/no-did-update-set-state */
|
||||||
this.setState( {
|
this.setState( {
|
||||||
storeNoticeText: options.woocommerce_demo_store_notice,
|
storeNoticeText: demoStoreNotice,
|
||||||
} );
|
} );
|
||||||
/* eslint-enable react/no-did-update-set-state */
|
/* eslint-enable react/no-did-update-set-state */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( step === 'logo' && isRequestSuccessful ) {
|
|
||||||
createNotice(
|
|
||||||
'success',
|
|
||||||
__( 'Store logo updated sucessfully.', 'woocommerce-admin' )
|
|
||||||
);
|
|
||||||
this.completeStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( step === 'notice' && isRequestSuccessful ) {
|
|
||||||
createNotice(
|
|
||||||
'success',
|
|
||||||
__(
|
|
||||||
"🎨 Your store is looking great! Don't forget to continue personalizing it.",
|
|
||||||
'woocommerce-admin'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
this.completeStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
const newErrors = difference( errors, prevProps.errors );
|
|
||||||
newErrors.map( ( error ) => createNotice( 'error', error ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
completeStep() {
|
completeStep() {
|
||||||
|
@ -222,8 +192,8 @@ class Appearance extends Component {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLogo() {
|
async updateLogo() {
|
||||||
const { updateOptions } = this.props;
|
const { updateOptions, createNotice } = this.props;
|
||||||
const { logo } = this.state;
|
const { logo } = this.state;
|
||||||
const { stylesheet, themeMods } = getSetting( 'onboarding', {} );
|
const { stylesheet, themeMods } = getSetting( 'onboarding', {} );
|
||||||
const updatedThemeMods = {
|
const updatedThemeMods = {
|
||||||
|
@ -238,13 +208,25 @@ class Appearance extends Component {
|
||||||
themeMods: updatedThemeMods,
|
themeMods: updatedThemeMods,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
updateOptions( {
|
this.setState( { isUpdatingLogo: true } );
|
||||||
|
const update = await updateOptions( {
|
||||||
[ `theme_mods_${ stylesheet }` ]: updatedThemeMods,
|
[ `theme_mods_${ stylesheet }` ]: updatedThemeMods,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
if ( update.success ) {
|
||||||
|
this.setState( { isUpdatingLogo: false } );
|
||||||
|
createNotice(
|
||||||
|
'success',
|
||||||
|
__( 'Store logo updated sucessfully.', 'woocommerce-admin' )
|
||||||
|
);
|
||||||
|
this.completeStep();
|
||||||
|
} else {
|
||||||
|
createNotice( 'error', update.message );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNotice() {
|
async updateNotice() {
|
||||||
const { updateOptions } = this.props;
|
const { updateOptions, createNotice } = this.props;
|
||||||
const { storeNoticeText } = this.state;
|
const { storeNoticeText } = this.state;
|
||||||
|
|
||||||
recordEvent( 'tasklist_appearance_set_store_notice', {
|
recordEvent( 'tasklist_appearance_set_store_notice', {
|
||||||
|
@ -256,16 +238,36 @@ class Appearance extends Component {
|
||||||
isAppearanceComplete: true,
|
isAppearanceComplete: true,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
updateOptions( {
|
this.setState( { isUpdatingNotice: true } );
|
||||||
|
const update = await updateOptions( {
|
||||||
woocommerce_task_list_appearance_complete: true,
|
woocommerce_task_list_appearance_complete: true,
|
||||||
woocommerce_demo_store: storeNoticeText.length ? 'yes' : 'no',
|
woocommerce_demo_store: storeNoticeText.length ? 'yes' : 'no',
|
||||||
woocommerce_demo_store_notice: storeNoticeText,
|
woocommerce_demo_store_notice: storeNoticeText,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
if ( update.success ) {
|
||||||
|
this.setState( { isUpdatingNotice: false } );
|
||||||
|
createNotice(
|
||||||
|
'success',
|
||||||
|
__(
|
||||||
|
"🎨 Your store is looking great! Don't forget to continue personalizing it.",
|
||||||
|
'woocommerce-admin'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
this.completeStep();
|
||||||
|
} else {
|
||||||
|
createNotice( 'error', update.message );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getSteps() {
|
getSteps() {
|
||||||
const { isDirty, isPending, logo, storeNoticeText } = this.state;
|
const {
|
||||||
const { isRequesting } = this.props;
|
isDirty,
|
||||||
|
isPending,
|
||||||
|
logo,
|
||||||
|
storeNoticeText,
|
||||||
|
isUpdatingLogo,
|
||||||
|
} = this.state;
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
{
|
{
|
||||||
|
@ -340,7 +342,7 @@ class Appearance extends Component {
|
||||||
<Button
|
<Button
|
||||||
disabled={ ! logo && ! isDirty }
|
disabled={ ! logo && ! isDirty }
|
||||||
onClick={ this.updateLogo }
|
onClick={ this.updateLogo }
|
||||||
isBusy={ isRequesting }
|
isBusy={ isUpdatingLogo }
|
||||||
isPrimary
|
isPrimary
|
||||||
>
|
>
|
||||||
{ __( 'Proceed', 'woocommerce-admin' ) }
|
{ __( 'Proceed', 'woocommerce-admin' ) }
|
||||||
|
@ -388,8 +390,12 @@ class Appearance extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isPending, stepIndex } = this.state;
|
const {
|
||||||
const { isRequesting, hasErrors } = this.props;
|
isPending,
|
||||||
|
stepIndex,
|
||||||
|
isUpdatingLogo,
|
||||||
|
isUpdatingNotice,
|
||||||
|
} = this.state;
|
||||||
const currentStep = this.getSteps()[ stepIndex ].key;
|
const currentStep = this.getSteps()[ stepIndex ].key;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -397,7 +403,7 @@ class Appearance extends Component {
|
||||||
<Card className="is-narrow">
|
<Card className="is-narrow">
|
||||||
<Stepper
|
<Stepper
|
||||||
isPending={
|
isPending={
|
||||||
( isRequesting && ! hasErrors ) || isPending
|
isUpdatingNotice || isUpdatingLogo || isPending
|
||||||
}
|
}
|
||||||
isVertical
|
isVertical
|
||||||
currentStep={ currentStep }
|
currentStep={ currentStep }
|
||||||
|
@ -411,49 +417,15 @@ class Appearance extends Component {
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const {
|
const { getOption } = select( OPTIONS_STORE_NAME );
|
||||||
getOptions,
|
|
||||||
getOptionsError,
|
|
||||||
isUpdateOptionsRequesting,
|
|
||||||
} = select( 'wc-api' );
|
|
||||||
const { stylesheet } = getSetting( 'onboarding', {} );
|
|
||||||
|
|
||||||
const options = getOptions( [
|
return {
|
||||||
'woocommerce_demo_store',
|
demoStoreNotice: getOption( 'woocommerce_demo_store_notice' ),
|
||||||
'woocommerce_demo_store_notice',
|
};
|
||||||
] );
|
|
||||||
const errors = [];
|
|
||||||
const uploadLogoError = getOptionsError( [
|
|
||||||
`theme_mods_${ stylesheet }`,
|
|
||||||
] );
|
|
||||||
const storeNoticeError = getOptionsError( [
|
|
||||||
'woocommerce_demo_store',
|
|
||||||
'woocommerce_demo_store_notice',
|
|
||||||
] );
|
|
||||||
if ( uploadLogoError ) {
|
|
||||||
errors.push( uploadLogoError.message );
|
|
||||||
}
|
|
||||||
if ( storeNoticeError ) {
|
|
||||||
errors.push( storeNoticeError.message );
|
|
||||||
}
|
|
||||||
const hasErrors = Boolean( errors.length );
|
|
||||||
const isRequesting =
|
|
||||||
Boolean(
|
|
||||||
isUpdateOptionsRequesting( [ `theme_mods_${ stylesheet }` ] )
|
|
||||||
) ||
|
|
||||||
Boolean(
|
|
||||||
isUpdateOptionsRequesting( [
|
|
||||||
'woocommerce_task_list_appearance_complete',
|
|
||||||
'woocommerce_demo_store',
|
|
||||||
'woocommerce_demo_store_notice',
|
|
||||||
] )
|
|
||||||
);
|
|
||||||
|
|
||||||
return { errors, getOptionsError, hasErrors, isRequesting, options };
|
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createNotice,
|
createNotice,
|
||||||
|
|
|
@ -5,17 +5,13 @@ import { __ } from '@wordpress/i18n';
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component, Fragment } from '@wordpress/element';
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
*/
|
*/
|
||||||
import { Form, H, TextControl } from '@woocommerce/components';
|
import { Form, H, TextControl } from '@woocommerce/components';
|
||||||
|
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
|
|
||||||
class PayFast extends Component {
|
class PayFast extends Component {
|
||||||
getInitialConfigValues = () => {
|
getInitialConfigValues = () => {
|
||||||
|
@ -42,16 +38,17 @@ class PayFast extends Component {
|
||||||
return errors;
|
return errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidUpdate( prevProps ) {
|
updateSettings = async ( values ) => {
|
||||||
const {
|
const { updateOptions, createNotice, markConfigured } = this.props;
|
||||||
createNotice,
|
|
||||||
isOptionsRequesting,
|
|
||||||
hasOptionsError,
|
|
||||||
markConfigured,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if ( prevProps.isOptionsRequesting && ! isOptionsRequesting ) {
|
const update = await updateOptions( {
|
||||||
if ( ! hasOptionsError ) {
|
woocommerce_bacs_settings: {
|
||||||
|
enabled: 'yes',
|
||||||
|
},
|
||||||
|
woocommerce_bacs_accounts: [ values ],
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( update.success ) {
|
||||||
markConfigured( 'bacs' );
|
markConfigured( 'bacs' );
|
||||||
createNotice(
|
createNotice(
|
||||||
'success',
|
'success',
|
||||||
|
@ -69,18 +66,6 @@ class PayFast extends Component {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSettings = ( values ) => {
|
|
||||||
const { updateOptions } = this.props;
|
|
||||||
|
|
||||||
updateOptions( {
|
|
||||||
woocommerce_bacs_settings: {
|
|
||||||
enabled: 'yes',
|
|
||||||
},
|
|
||||||
woocommerce_bacs_accounts: [ values ],
|
|
||||||
} );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -171,28 +156,16 @@ class PayFast extends Component {
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getOptionsError, isUpdateOptionsRequesting } = select(
|
const { isOptionsUpdating } = select( OPTIONS_STORE_NAME );
|
||||||
'wc-api'
|
const isOptionsRequesting = isOptionsUpdating();
|
||||||
);
|
|
||||||
const isOptionsRequesting = Boolean(
|
|
||||||
isUpdateOptionsRequesting( [
|
|
||||||
'woocommerce_bacs_settings',
|
|
||||||
'woocommerce_bacs_accounts',
|
|
||||||
] )
|
|
||||||
);
|
|
||||||
const hasOptionsError = getOptionsError( [
|
|
||||||
'woocommerce_bacs_settings',
|
|
||||||
'woocommerce_bacs_accounts',
|
|
||||||
] );
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasOptionsError,
|
|
||||||
isOptionsRequesting,
|
isOptionsRequesting,
|
||||||
};
|
};
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createNotice,
|
createNotice,
|
||||||
|
|
|
@ -19,8 +19,9 @@ import {
|
||||||
} from '@woocommerce/navigation';
|
} from '@woocommerce/navigation';
|
||||||
import {
|
import {
|
||||||
ONBOARDING_STORE_NAME,
|
ONBOARDING_STORE_NAME,
|
||||||
pluginNames,
|
OPTIONS_STORE_NAME,
|
||||||
PLUGINS_STORE_NAME,
|
PLUGINS_STORE_NAME,
|
||||||
|
pluginNames,
|
||||||
} from '@woocommerce/data';
|
} from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,32 +54,15 @@ class Payments extends Component {
|
||||||
if ( prevProps === this.props ) {
|
if ( prevProps === this.props ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { createNotice, errors, methods, requesting } = this.props;
|
const { methods } = this.props;
|
||||||
|
|
||||||
let recommendedMethod = 'stripe';
|
let recommendedMethod = 'stripe';
|
||||||
methods.forEach( ( method ) => {
|
methods.forEach( ( method ) => {
|
||||||
const { key, title, visible } = method;
|
const { key, visible } = method;
|
||||||
|
|
||||||
if ( key === 'wcpay' && visible ) {
|
if ( key === 'wcpay' && visible ) {
|
||||||
recommendedMethod = 'wcpay';
|
recommendedMethod = 'wcpay';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
prevProps.requesting[ key ] &&
|
|
||||||
! requesting[ key ] &&
|
|
||||||
errors[ key ]
|
|
||||||
) {
|
|
||||||
createNotice(
|
|
||||||
'error',
|
|
||||||
sprintf(
|
|
||||||
__(
|
|
||||||
'There was a problem updating settings for %s',
|
|
||||||
'woocommerce-admin'
|
|
||||||
),
|
|
||||||
title
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if ( this.state.recommendedMethod !== recommendedMethod ) {
|
if ( this.state.recommendedMethod !== recommendedMethod ) {
|
||||||
|
@ -88,10 +72,10 @@ class Payments extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
completeTask() {
|
async completeTask() {
|
||||||
const { createNotice, methods, updateOptions } = this.props;
|
const { createNotice, methods, updateOptions } = this.props;
|
||||||
|
|
||||||
updateOptions( {
|
const update = await updateOptions( {
|
||||||
woocommerce_task_list_payments: {
|
woocommerce_task_list_payments: {
|
||||||
completed: 1,
|
completed: 1,
|
||||||
timestamp: Math.floor( Date.now() / 1000 ),
|
timestamp: Math.floor( Date.now() / 1000 ),
|
||||||
|
@ -104,6 +88,7 @@ class Payments extends Component {
|
||||||
.map( ( method ) => method.key ),
|
.map( ( method ) => method.key ),
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
if ( update.success ) {
|
||||||
createNotice(
|
createNotice(
|
||||||
'success',
|
'success',
|
||||||
__(
|
__(
|
||||||
|
@ -113,6 +98,15 @@ class Payments extends Component {
|
||||||
);
|
);
|
||||||
|
|
||||||
getHistory().push( getNewPath( {}, '/', {} ) );
|
getHistory().push( getNewPath( {}, '/', {} ) );
|
||||||
|
} else {
|
||||||
|
createNotice(
|
||||||
|
'error',
|
||||||
|
__(
|
||||||
|
'There was a problem updating settings',
|
||||||
|
'woocommerce-admin'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skipTask() {
|
skipTask() {
|
||||||
|
@ -218,8 +212,8 @@ class Payments extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const currentMethod = this.getCurrentMethod();
|
const currentMethod = this.getCurrentMethod();
|
||||||
const { methods, query } = this.props;
|
|
||||||
const { enabledMethods, recommendedMethod } = this.state;
|
const { enabledMethods, recommendedMethod } = this.state;
|
||||||
|
const { methods, query, requesting } = this.props;
|
||||||
const configuredMethods = methods.filter(
|
const configuredMethods = methods.filter(
|
||||||
( method ) => method.isConfigured
|
( method ) => method.isConfigured
|
||||||
).length;
|
).length;
|
||||||
|
@ -344,7 +338,11 @@ class Payments extends Component {
|
||||||
) }
|
) }
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button isPrimary onClick={ this.completeTask }>
|
<Button
|
||||||
|
isPrimary
|
||||||
|
isBusy={ requesting }
|
||||||
|
onClick={ this.completeTask }
|
||||||
|
>
|
||||||
{ __( 'Done', 'woocommerce-admin' ) }
|
{ __( 'Done', 'woocommerce-admin' ) }
|
||||||
</Button>
|
</Button>
|
||||||
) }
|
) }
|
||||||
|
@ -357,18 +355,15 @@ class Payments extends Component {
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getProfileItems } = select( ONBOARDING_STORE_NAME );
|
const { getProfileItems } = select( ONBOARDING_STORE_NAME );
|
||||||
const {
|
const { getOption, isOptionsUpdating } = select( OPTIONS_STORE_NAME );
|
||||||
getOptions,
|
|
||||||
getUpdateOptionsError,
|
|
||||||
isUpdateOptionsRequesting,
|
|
||||||
} = select( 'wc-api' );
|
|
||||||
|
|
||||||
const { getActivePlugins, isJetpackConnected } = select(
|
const { getActivePlugins, isJetpackConnected } = select(
|
||||||
PLUGINS_STORE_NAME
|
PLUGINS_STORE_NAME
|
||||||
);
|
);
|
||||||
|
|
||||||
const activePlugins = getActivePlugins();
|
const activePlugins = getActivePlugins();
|
||||||
const profileItems = getProfileItems();
|
const profileItems = getProfileItems();
|
||||||
const options = getOptions( [
|
|
||||||
|
const optionNames = [
|
||||||
'woocommerce_default_country',
|
'woocommerce_default_country',
|
||||||
'woocommerce_woocommerce_payments_settings',
|
'woocommerce_woocommerce_payments_settings',
|
||||||
'woocommerce_stripe_settings',
|
'woocommerce_stripe_settings',
|
||||||
|
@ -381,7 +376,12 @@ export default compose(
|
||||||
'woocommerce_cod_settings',
|
'woocommerce_cod_settings',
|
||||||
'woocommerce_bacs_settings',
|
'woocommerce_bacs_settings',
|
||||||
'woocommerce_bacs_accounts',
|
'woocommerce_bacs_accounts',
|
||||||
] );
|
];
|
||||||
|
|
||||||
|
const options = optionNames.reduce( ( result, name ) => {
|
||||||
|
result[ name ] = getOption( name );
|
||||||
|
return result;
|
||||||
|
}, {} );
|
||||||
const countryCode = getCountryCode(
|
const countryCode = getCountryCode(
|
||||||
options.woocommerce_default_country
|
options.woocommerce_default_country
|
||||||
);
|
);
|
||||||
|
@ -394,20 +394,10 @@ export default compose(
|
||||||
profileItems,
|
profileItems,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
const errors = {};
|
const requesting = isOptionsUpdating();
|
||||||
const requesting = {};
|
|
||||||
methods.forEach( ( method ) => {
|
|
||||||
errors[ method.key ] = Boolean(
|
|
||||||
getUpdateOptionsError( [ method.optionName ] )
|
|
||||||
);
|
|
||||||
requesting[ method.key ] = Boolean(
|
|
||||||
isUpdateOptionsRequesting( [ method.optionName ] )
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
countryCode,
|
countryCode,
|
||||||
errors,
|
|
||||||
profileItems,
|
profileItems,
|
||||||
activePlugins,
|
activePlugins,
|
||||||
options,
|
options,
|
||||||
|
@ -417,7 +407,7 @@ export default compose(
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
return {
|
return {
|
||||||
createNotice,
|
createNotice,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
|
|
|
@ -6,17 +6,13 @@ import { Component, Fragment } from '@wordpress/element';
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import interpolateComponents from 'interpolate-components';
|
import interpolateComponents from 'interpolate-components';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
*/
|
*/
|
||||||
import { Form, Link, Stepper, TextControl } from '@woocommerce/components';
|
import { Form, Link, Stepper, TextControl } from '@woocommerce/components';
|
||||||
|
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
|
|
||||||
class PayFast extends Component {
|
class PayFast extends Component {
|
||||||
getInitialConfigValues = () => {
|
getInitialConfigValues = () => {
|
||||||
|
@ -54,16 +50,22 @@ class PayFast extends Component {
|
||||||
return errors;
|
return errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidUpdate( prevProps ) {
|
updateSettings = async ( values ) => {
|
||||||
const {
|
const { updateOptions, createNotice, markConfigured } = this.props;
|
||||||
createNotice,
|
|
||||||
isOptionsRequesting,
|
|
||||||
hasOptionsError,
|
|
||||||
markConfigured,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if ( prevProps.isOptionsRequesting && ! isOptionsRequesting ) {
|
// Because the PayFast extension only works with the South African Rand
|
||||||
if ( ! hasOptionsError ) {
|
// currency, force the store to use it while setting the PayFast settings
|
||||||
|
const update = await updateOptions( {
|
||||||
|
woocommerce_currency: 'ZAR',
|
||||||
|
woocommerce_payfast_settings: {
|
||||||
|
merchant_id: values.merchant_id,
|
||||||
|
merchant_key: values.merchant_key,
|
||||||
|
pass_phrase: values.pass_phrase,
|
||||||
|
enabled: 'yes',
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( update.success ) {
|
||||||
markConfigured( 'payfast' );
|
markConfigured( 'payfast' );
|
||||||
createNotice(
|
createNotice(
|
||||||
'success',
|
'success',
|
||||||
|
@ -78,23 +80,6 @@ class PayFast extends Component {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSettings = ( values ) => {
|
|
||||||
const { updateOptions } = this.props;
|
|
||||||
|
|
||||||
// Because the PayFast extension only works with the South African Rand
|
|
||||||
// currency, force the store to use it while setting the PayFast settings
|
|
||||||
updateOptions( {
|
|
||||||
woocommerce_currency: 'ZAR',
|
|
||||||
woocommerce_payfast_settings: {
|
|
||||||
merchant_id: values.merchant_id,
|
|
||||||
merchant_key: values.merchant_key,
|
|
||||||
pass_phrase: values.pass_phrase,
|
|
||||||
enabled: 'yes',
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
renderConnectStep() {
|
renderConnectStep() {
|
||||||
|
@ -190,28 +175,16 @@ class PayFast extends Component {
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getOptionsError, isUpdateOptionsRequesting } = select(
|
const { isOptionsUpdating } = select( OPTIONS_STORE_NAME );
|
||||||
'wc-api'
|
const isOptionsRequesting = isOptionsUpdating();
|
||||||
);
|
|
||||||
const isOptionsRequesting = Boolean(
|
|
||||||
isUpdateOptionsRequesting( [
|
|
||||||
'woocommerce_currency',
|
|
||||||
'woocommerce_payfast_settings',
|
|
||||||
] )
|
|
||||||
);
|
|
||||||
const hasOptionsError = getOptionsError( [
|
|
||||||
'woocommerce_currency',
|
|
||||||
'woocommerce_payfast_settings',
|
|
||||||
] );
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasOptionsError,
|
|
||||||
isOptionsRequesting,
|
isOptionsRequesting,
|
||||||
};
|
};
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createNotice,
|
createNotice,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Button } from '@wordpress/components';
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component, Fragment } from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import interpolateComponents from 'interpolate-components';
|
import interpolateComponents from 'interpolate-components';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
|
@ -15,8 +15,7 @@ import { withDispatch } from '@wordpress/data';
|
||||||
import { Form, Link, Stepper, TextControl } from '@woocommerce/components';
|
import { Form, Link, Stepper, TextControl } from '@woocommerce/components';
|
||||||
import { getQuery } from '@woocommerce/navigation';
|
import { getQuery } from '@woocommerce/navigation';
|
||||||
import { WC_ADMIN_NAMESPACE } from 'wc-api/constants';
|
import { WC_ADMIN_NAMESPACE } from 'wc-api/constants';
|
||||||
import withSelect from 'wc-api/with-select';
|
import { PLUGINS_STORE_NAME, OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
import { PLUGINS_STORE_NAME } from '@woocommerce/data';
|
|
||||||
|
|
||||||
class PayPal extends Component {
|
class PayPal extends Component {
|
||||||
constructor( props ) {
|
constructor( props ) {
|
||||||
|
@ -119,13 +118,12 @@ class PayPal extends Component {
|
||||||
async updateSettings( values ) {
|
async updateSettings( values ) {
|
||||||
const {
|
const {
|
||||||
createNotice,
|
createNotice,
|
||||||
isSettingsError,
|
|
||||||
options,
|
options,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
markConfigured,
|
markConfigured,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
await updateOptions( {
|
const update = await updateOptions( {
|
||||||
woocommerce_ppec_paypal_settings: {
|
woocommerce_ppec_paypal_settings: {
|
||||||
...options.woocommerce_ppec_paypal_settings,
|
...options.woocommerce_ppec_paypal_settings,
|
||||||
api_username: values.api_username,
|
api_username: values.api_username,
|
||||||
|
@ -134,7 +132,7 @@ class PayPal extends Component {
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if ( ! isSettingsError ) {
|
if ( update.success ) {
|
||||||
createNotice(
|
createNotice(
|
||||||
'success',
|
'success',
|
||||||
__( 'PayPal connected successfully.', 'woocommerce-admin' )
|
__( 'PayPal connected successfully.', 'woocommerce-admin' )
|
||||||
|
@ -178,7 +176,7 @@ class PayPal extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderManualConfig() {
|
renderManualConfig() {
|
||||||
const { isOptionsRequesting } = this.props;
|
const { isOptionsUpdating } = this.props;
|
||||||
const link = (
|
const link = (
|
||||||
<Link
|
<Link
|
||||||
href="https://docs.woocommerce.com/document/paypal-express-checkout/#section-8"
|
href="https://docs.woocommerce.com/document/paypal-express-checkout/#section-8"
|
||||||
|
@ -225,7 +223,7 @@ class PayPal extends Component {
|
||||||
<Button
|
<Button
|
||||||
onClick={ handleSubmit }
|
onClick={ handleSubmit }
|
||||||
isPrimary
|
isPrimary
|
||||||
disabled={ isOptionsRequesting }
|
isBusy={ isOptionsUpdating }
|
||||||
>
|
>
|
||||||
{ __( 'Proceed', 'woocommerce-admin' ) }
|
{ __( 'Proceed', 'woocommerce-admin' ) }
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -291,23 +289,20 @@ PayPal.defaultProps = {
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getOptions, isGetOptionsRequesting } = select( 'wc-api' );
|
const { getOption, isOptionsUpdating } = select( OPTIONS_STORE_NAME );
|
||||||
const { getActivePlugins } = select( PLUGINS_STORE_NAME );
|
const { getActivePlugins } = select( PLUGINS_STORE_NAME );
|
||||||
const options = getOptions( [ 'woocommerce_ppec_paypal_settings' ] );
|
const options = getOption( 'woocommerce_ppec_paypal_settings' );
|
||||||
const isOptionsRequesting = Boolean(
|
|
||||||
isGetOptionsRequesting( [ 'woocommerce_ppec_paypal_settings' ] )
|
|
||||||
);
|
|
||||||
const activePlugins = getActivePlugins();
|
const activePlugins = getActivePlugins();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activePlugins,
|
activePlugins,
|
||||||
options,
|
options,
|
||||||
isOptionsRequesting,
|
isOptionsUpdating: isOptionsUpdating(),
|
||||||
};
|
};
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
return {
|
return {
|
||||||
createNotice,
|
createNotice,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { __ } from '@wordpress/i18n';
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component, Fragment } from '@wordpress/element';
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,9 +13,9 @@ import { compose } from '@wordpress/compose';
|
||||||
*/
|
*/
|
||||||
import { getQuery } from '@woocommerce/navigation';
|
import { getQuery } from '@woocommerce/navigation';
|
||||||
import { WC_ADMIN_NAMESPACE } from 'wc-api/constants';
|
import { WC_ADMIN_NAMESPACE } from 'wc-api/constants';
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
import { Stepper } from '@woocommerce/components';
|
import { Stepper } from '@woocommerce/components';
|
||||||
import { getAdminLink } from '@woocommerce/wc-admin-settings';
|
import { getAdminLink } from '@woocommerce/wc-admin-settings';
|
||||||
|
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
|
|
||||||
class Square extends Component {
|
class Square extends Component {
|
||||||
constructor( props ) {
|
constructor( props ) {
|
||||||
|
@ -145,15 +145,11 @@ class Square extends Component {
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getOptions, isGetOptionsRequesting } = select( 'wc-api' );
|
const { getOption, isResolving } = select( OPTIONS_STORE_NAME );
|
||||||
const options = getOptions( [
|
const options = getOption( 'woocommerce_square_credit_card_settings' );
|
||||||
|
const optionsIsRequesting = isResolving( 'getOption', [
|
||||||
'woocommerce_square_credit_card_settings',
|
'woocommerce_square_credit_card_settings',
|
||||||
] );
|
] );
|
||||||
const optionsIsRequesting = Boolean(
|
|
||||||
isGetOptionsRequesting( [
|
|
||||||
'woocommerce_square_credit_card_settings',
|
|
||||||
] )
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
options,
|
options,
|
||||||
|
@ -162,7 +158,7 @@ export default compose(
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
return {
|
return {
|
||||||
createNotice,
|
createNotice,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
|
|
|
@ -5,10 +5,9 @@ import { __ } from '@wordpress/i18n';
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component, Fragment } from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
import interpolateComponents from 'interpolate-components';
|
import interpolateComponents from 'interpolate-components';
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import { get } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
|
@ -17,8 +16,7 @@ import { Form, Link, Stepper, TextControl } from '@woocommerce/components';
|
||||||
import { getAdminLink } from '@woocommerce/wc-admin-settings';
|
import { getAdminLink } from '@woocommerce/wc-admin-settings';
|
||||||
import { getQuery } from '@woocommerce/navigation';
|
import { getQuery } from '@woocommerce/navigation';
|
||||||
import { WCS_NAMESPACE } from 'wc-api/constants';
|
import { WCS_NAMESPACE } from 'wc-api/constants';
|
||||||
import withSelect from 'wc-api/with-select';
|
import { PLUGINS_STORE_NAME, OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
import { PLUGINS_STORE_NAME } from '@woocommerce/data';
|
|
||||||
|
|
||||||
class Stripe extends Component {
|
class Stripe extends Component {
|
||||||
constructor( props ) {
|
constructor( props ) {
|
||||||
|
@ -54,26 +52,7 @@ class Stripe extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate( prevProps ) {
|
componentDidUpdate( prevProps ) {
|
||||||
const {
|
const { activePlugins } = this.props;
|
||||||
activePlugins,
|
|
||||||
createNotice,
|
|
||||||
isOptionsRequesting,
|
|
||||||
hasOptionsError,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if ( prevProps.isOptionsRequesting && ! isOptionsRequesting ) {
|
|
||||||
if ( ! hasOptionsError ) {
|
|
||||||
this.completeMethod();
|
|
||||||
} else {
|
|
||||||
createNotice(
|
|
||||||
'error',
|
|
||||||
__(
|
|
||||||
'There was a problem saving your payment setings',
|
|
||||||
'woocommerce-admin'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
! prevProps.activePlugins.includes(
|
! prevProps.activePlugins.includes(
|
||||||
|
@ -154,10 +133,10 @@ class Stripe extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSettings( values ) {
|
async updateSettings( values ) {
|
||||||
const { updateOptions, stripeSettings } = this.props;
|
const { updateOptions, stripeSettings, createNotice } = this.props;
|
||||||
|
|
||||||
updateOptions( {
|
const update = await updateOptions( {
|
||||||
woocommerce_stripe_settings: {
|
woocommerce_stripe_settings: {
|
||||||
...stripeSettings,
|
...stripeSettings,
|
||||||
publishable_key: values.publishable_key,
|
publishable_key: values.publishable_key,
|
||||||
|
@ -165,6 +144,18 @@ class Stripe extends Component {
|
||||||
enabled: 'yes',
|
enabled: 'yes',
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
if ( update.success ) {
|
||||||
|
this.completeMethod();
|
||||||
|
} else {
|
||||||
|
createNotice(
|
||||||
|
'error',
|
||||||
|
__(
|
||||||
|
'There was a problem saving your payment setings',
|
||||||
|
'woocommerce-admin'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getInitialConfigValues() {
|
getInitialConfigValues() {
|
||||||
|
@ -194,7 +185,7 @@ class Stripe extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderManualConfig() {
|
renderManualConfig() {
|
||||||
const { isOptionsRequesting } = this.props;
|
const { isOptionsUpdating } = this.props;
|
||||||
const stripeHelp = interpolateComponents( {
|
const stripeHelp = interpolateComponents( {
|
||||||
mixedString: __(
|
mixedString: __(
|
||||||
'Your API details can be obtained from your {{docsLink}}Stripe account{{/docsLink}}. Don’t have a Stripe account? {{registerLink}}Create one.{{/registerLink}}',
|
'Your API details can be obtained from your {{docsLink}}Stripe account{{/docsLink}}. Don’t have a Stripe account? {{registerLink}}Create one.{{/registerLink}}',
|
||||||
|
@ -246,7 +237,7 @@ class Stripe extends Component {
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
isPrimary
|
isPrimary
|
||||||
isBusy={ isOptionsRequesting }
|
isBusy={ isOptionsUpdating }
|
||||||
onClick={ handleSubmit }
|
onClick={ handleSubmit }
|
||||||
>
|
>
|
||||||
{ __( 'Proceed', 'woocommerce-admin' ) }
|
{ __( 'Proceed', 'woocommerce-admin' ) }
|
||||||
|
@ -294,14 +285,14 @@ class Stripe extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { installStep, isOptionsRequesting } = this.props;
|
const { installStep, isOptionsUpdating } = this.props;
|
||||||
const { isPending } = this.state;
|
const { isPending } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stepper
|
<Stepper
|
||||||
isVertical
|
isVertical
|
||||||
isPending={
|
isPending={
|
||||||
! installStep.isComplete || isOptionsRequesting || isPending
|
! installStep.isComplete || isOptionsUpdating || isPending
|
||||||
}
|
}
|
||||||
currentStep={ installStep.isComplete ? 'connect' : 'install' }
|
currentStep={ installStep.isComplete ? 'connect' : 'install' }
|
||||||
steps={ [ installStep, this.getConnectStep() ] }
|
steps={ [ installStep, this.getConnectStep() ] }
|
||||||
|
@ -312,38 +303,21 @@ class Stripe extends Component {
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const {
|
const { getOption, isOptionsUpdating } = select( OPTIONS_STORE_NAME );
|
||||||
getOptions,
|
|
||||||
getOptionsError,
|
|
||||||
isUpdateOptionsRequesting,
|
|
||||||
} = select( 'wc-api' );
|
|
||||||
const { getActivePlugins, isJetpackConnected } = select(
|
const { getActivePlugins, isJetpackConnected } = select(
|
||||||
PLUGINS_STORE_NAME
|
PLUGINS_STORE_NAME
|
||||||
);
|
);
|
||||||
const options = getOptions( [ 'woocommerce_stripe_settings' ] );
|
|
||||||
const stripeSettings = get(
|
|
||||||
options,
|
|
||||||
[ 'woocommerce_stripe_settings' ],
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
const isOptionsRequesting = Boolean(
|
|
||||||
isUpdateOptionsRequesting( [ 'woocommerce_stripe_settings' ] )
|
|
||||||
);
|
|
||||||
const hasOptionsError = getOptionsError( [
|
|
||||||
'woocommerce_stripe_settings',
|
|
||||||
] );
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activePlugins: getActivePlugins(),
|
activePlugins: getActivePlugins(),
|
||||||
hasOptionsError,
|
|
||||||
isJetpackConnected: isJetpackConnected(),
|
isJetpackConnected: isJetpackConnected(),
|
||||||
isOptionsRequesting,
|
isOptionsUpdating: isOptionsUpdating(),
|
||||||
stripeSettings,
|
stripeSettings: getOption( 'woocommerce_stripe_settings' ) || [],
|
||||||
};
|
};
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
return {
|
return {
|
||||||
createNotice,
|
createNotice,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { __ } from '@wordpress/i18n';
|
||||||
import { Button } from '@wordpress/components';
|
import { Button } from '@wordpress/components';
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component, Fragment } from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import { difference, filter, get } from 'lodash';
|
import { difference, filter } from 'lodash';
|
||||||
import interpolateComponents from 'interpolate-components';
|
import interpolateComponents from 'interpolate-components';
|
||||||
import { withDispatch, withSelect } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
|
|
||||||
|
@ -19,7 +19,11 @@ import {
|
||||||
getSetting,
|
getSetting,
|
||||||
setSetting,
|
setSetting,
|
||||||
} from '@woocommerce/wc-admin-settings';
|
} from '@woocommerce/wc-admin-settings';
|
||||||
import { SETTINGS_STORE_NAME, PLUGINS_STORE_NAME } from '@woocommerce/data';
|
import {
|
||||||
|
SETTINGS_STORE_NAME,
|
||||||
|
PLUGINS_STORE_NAME,
|
||||||
|
OPTIONS_STORE_NAME,
|
||||||
|
} from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -27,7 +31,6 @@ import { SETTINGS_STORE_NAME, PLUGINS_STORE_NAME } from '@woocommerce/data';
|
||||||
import Connect from 'dashboard/components/connect';
|
import Connect from 'dashboard/components/connect';
|
||||||
import { getCountryCode } from 'dashboard/utils';
|
import { getCountryCode } from 'dashboard/utils';
|
||||||
import StoreLocation from './steps/location';
|
import StoreLocation from './steps/location';
|
||||||
import withWCApiSelect from 'wc-api/with-select';
|
|
||||||
import { recordEvent, queueRecordEvent } from 'lib/tracks';
|
import { recordEvent, queueRecordEvent } from 'lib/tracks';
|
||||||
|
|
||||||
class Tax extends Component {
|
class Tax extends Component {
|
||||||
|
@ -491,38 +494,16 @@ class Tax extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withWCApiSelect( ( select ) => {
|
|
||||||
const { getOptions } = select( 'wc-api' );
|
|
||||||
|
|
||||||
const { getActivePlugins, isJetpackConnected } = select(
|
|
||||||
PLUGINS_STORE_NAME
|
|
||||||
);
|
|
||||||
const activePlugins = getActivePlugins();
|
|
||||||
const pluginsToActivate = difference(
|
|
||||||
[ 'jetpack', 'woocommerce-services' ],
|
|
||||||
activePlugins
|
|
||||||
);
|
|
||||||
const options = getOptions( [
|
|
||||||
'wc_connect_options',
|
|
||||||
'woocommerce_setup_jetpack_opted_in',
|
|
||||||
] );
|
|
||||||
const connectOptions = get( options, 'wc_connect_options', {} );
|
|
||||||
const tosAccepted =
|
|
||||||
connectOptions.tos_accepted ||
|
|
||||||
options.woocommerce_setup_jetpack_opted_in;
|
|
||||||
|
|
||||||
return {
|
|
||||||
isJetpackConnected: isJetpackConnected(),
|
|
||||||
pluginsToActivate,
|
|
||||||
tosAccepted,
|
|
||||||
};
|
|
||||||
} ),
|
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const {
|
const {
|
||||||
getSettings,
|
getSettings,
|
||||||
getSettingsError,
|
getSettingsError,
|
||||||
isGetSettingsRequesting,
|
isGetSettingsRequesting,
|
||||||
} = select( SETTINGS_STORE_NAME );
|
} = select( SETTINGS_STORE_NAME );
|
||||||
|
const { getOption } = select( OPTIONS_STORE_NAME );
|
||||||
|
const { getActivePlugins, isJetpackConnected } = select(
|
||||||
|
PLUGINS_STORE_NAME
|
||||||
|
);
|
||||||
|
|
||||||
const { general: generalSettings = {} } = getSettings( 'general' );
|
const { general: generalSettings = {} } = getSettings( 'general' );
|
||||||
const isGeneralSettingsError = Boolean( getSettingsError( 'general' ) );
|
const isGeneralSettingsError = Boolean( getSettingsError( 'general' ) );
|
||||||
|
@ -537,6 +518,16 @@ export default compose(
|
||||||
const isTaxSettingsError = Boolean( getSettingsError( 'tax' ) );
|
const isTaxSettingsError = Boolean( getSettingsError( 'tax' ) );
|
||||||
const isTaxSettingsRequesting = isGetSettingsRequesting( 'tax' );
|
const isTaxSettingsRequesting = isGetSettingsRequesting( 'tax' );
|
||||||
|
|
||||||
|
const activePlugins = getActivePlugins();
|
||||||
|
const pluginsToActivate = difference(
|
||||||
|
[ 'jetpack', 'woocommerce-services' ],
|
||||||
|
activePlugins
|
||||||
|
);
|
||||||
|
const connectOptions = getOption( 'wc_connect_options' ) || {};
|
||||||
|
const tosAccepted =
|
||||||
|
connectOptions.tos_accepted ||
|
||||||
|
getOption( 'woocommerce_setup_jetpack_opted_in' );
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isGeneralSettingsError,
|
isGeneralSettingsError,
|
||||||
isGeneralSettingsRequesting,
|
isGeneralSettingsRequesting,
|
||||||
|
@ -545,6 +536,9 @@ export default compose(
|
||||||
taxSettings,
|
taxSettings,
|
||||||
isTaxSettingsError,
|
isTaxSettingsError,
|
||||||
isTaxSettingsRequesting,
|
isTaxSettingsRequesting,
|
||||||
|
isJetpackConnected: isJetpackConnected(),
|
||||||
|
pluginsToActivate,
|
||||||
|
tosAccepted,
|
||||||
};
|
};
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import operations from './operations';
|
|
||||||
import selectors from './selectors';
|
|
||||||
import mutations from './mutations';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
operations,
|
|
||||||
selectors,
|
|
||||||
mutations,
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { getResourceName } from '../utils';
|
|
||||||
|
|
||||||
const updateOptions = ( operations ) => ( options ) => {
|
|
||||||
const resourceName = getResourceName(
|
|
||||||
'options-update',
|
|
||||||
Object.keys( options )
|
|
||||||
);
|
|
||||||
operations.update( [ resourceName ], { [ resourceName ]: options } );
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
updateOptions,
|
|
||||||
};
|
|
|
@ -1,84 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { getResourceIdentifier, getResourceName } from '../utils';
|
|
||||||
import { WC_ADMIN_NAMESPACE } from '../constants';
|
|
||||||
|
|
||||||
function read( resourceNames, fetch = apiFetch ) {
|
|
||||||
return [ ...readOptions( resourceNames, fetch ) ];
|
|
||||||
}
|
|
||||||
|
|
||||||
function update( resourceNames, data, fetch = apiFetch ) {
|
|
||||||
return [ ...updateOptions( resourceNames, data, fetch ) ];
|
|
||||||
}
|
|
||||||
|
|
||||||
function readOptions( resourceNames, fetch ) {
|
|
||||||
const filteredNames = resourceNames.filter( ( name ) => {
|
|
||||||
return name.startsWith( 'options' );
|
|
||||||
} );
|
|
||||||
|
|
||||||
return filteredNames.map( async ( resourceName ) => {
|
|
||||||
const optionNames = getResourceIdentifier( resourceName );
|
|
||||||
const url =
|
|
||||||
WC_ADMIN_NAMESPACE + '/options?options=' + optionNames.join( ',' );
|
|
||||||
|
|
||||||
return fetch( { path: url } )
|
|
||||||
.then( optionsToResource )
|
|
||||||
.catch( ( error ) => {
|
|
||||||
return { [ resourceName ]: { error: String( error.message ) } };
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateOptions( resourceNames, data, fetch ) {
|
|
||||||
const url = WC_ADMIN_NAMESPACE + '/options';
|
|
||||||
|
|
||||||
const filteredNames = resourceNames.filter( ( name ) => {
|
|
||||||
return name.startsWith( 'options-update' );
|
|
||||||
} );
|
|
||||||
|
|
||||||
return filteredNames.map( async ( resourceName ) => {
|
|
||||||
return fetch( {
|
|
||||||
path: url,
|
|
||||||
method: 'POST',
|
|
||||||
data: data[ resourceName ],
|
|
||||||
} )
|
|
||||||
.then( () => optionsToResource( data[ resourceName ], true ) )
|
|
||||||
.catch( ( error ) => {
|
|
||||||
return { [ resourceName ]: { data: {}, error } };
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
function optionsToResource( options, updateResource = false ) {
|
|
||||||
const optionNames = Object.keys( options );
|
|
||||||
const resourceName = getResourceName(
|
|
||||||
updateResource ? 'options-update' : 'options',
|
|
||||||
optionNames
|
|
||||||
);
|
|
||||||
const resources = {};
|
|
||||||
|
|
||||||
optionNames.forEach(
|
|
||||||
( optionName ) =>
|
|
||||||
( resources[ getResourceName( 'options', optionName ) ] = {
|
|
||||||
data: options[ optionName ],
|
|
||||||
} )
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
[ resourceName ]: {
|
|
||||||
data: optionNames,
|
|
||||||
},
|
|
||||||
...resources,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
read,
|
|
||||||
update,
|
|
||||||
};
|
|
|
@ -1,81 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { isNil } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WooCommerce dependencies
|
|
||||||
*/
|
|
||||||
import { getSetting } from '@woocommerce/wc-admin-settings';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { DEFAULT_REQUIREMENT } from '../constants';
|
|
||||||
import { getResourceName } from '../utils';
|
|
||||||
|
|
||||||
const getOptions = ( getResource, requireResource ) => (
|
|
||||||
optionNames,
|
|
||||||
requirement = DEFAULT_REQUIREMENT
|
|
||||||
) => {
|
|
||||||
const resourceName = getResourceName( 'options', optionNames );
|
|
||||||
const options = {};
|
|
||||||
|
|
||||||
const names =
|
|
||||||
requireResource( requirement, resourceName ).data || optionNames;
|
|
||||||
|
|
||||||
names.forEach( ( name ) => {
|
|
||||||
const data = getSetting(
|
|
||||||
'preloadOptions',
|
|
||||||
{},
|
|
||||||
( po ) =>
|
|
||||||
getResource( getResourceName( 'options', name ) ).data ||
|
|
||||||
po[ name ]
|
|
||||||
);
|
|
||||||
if ( data ) {
|
|
||||||
options[ name ] = data;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getOptionsError = ( getResource ) => ( optionNames ) => {
|
|
||||||
return getResource( getResourceName( 'options', optionNames ) ).error;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getUpdateOptionsError = ( getResource ) => ( optionNames ) => {
|
|
||||||
return getResource( getResourceName( 'options-update', optionNames ) )
|
|
||||||
.error;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isGetOptionsRequesting = ( getResource ) => ( optionNames ) => {
|
|
||||||
const { lastReceived, lastRequested } = getResource(
|
|
||||||
getResourceName( 'options', optionNames )
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( isNil( lastRequested ) || isNil( lastReceived ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lastRequested > lastReceived;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isUpdateOptionsRequesting = ( getResource ) => ( optionNames ) => {
|
|
||||||
const { lastReceived, lastRequested } = getResource(
|
|
||||||
getResourceName( 'options-update', optionNames )
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( ! isNil( lastRequested ) && isNil( lastReceived ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lastRequested > lastReceived;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getOptions,
|
|
||||||
getOptionsError,
|
|
||||||
getUpdateOptionsError,
|
|
||||||
isGetOptionsRequesting,
|
|
||||||
isUpdateOptionsRequesting,
|
|
||||||
};
|
|
|
@ -5,7 +5,6 @@ import reportExport from './export';
|
||||||
import items from './items';
|
import items from './items';
|
||||||
import imports from './imports';
|
import imports from './imports';
|
||||||
import notes from './notes';
|
import notes from './notes';
|
||||||
import options from './options';
|
|
||||||
import reportItems from './reports/items';
|
import reportItems from './reports/items';
|
||||||
import reportStats from './reports/stats';
|
import reportStats from './reports/stats';
|
||||||
import reviews from './reviews';
|
import reviews from './reviews';
|
||||||
|
@ -17,13 +16,11 @@ function createWcApiSpec() {
|
||||||
...reportExport.mutations,
|
...reportExport.mutations,
|
||||||
...items.mutations,
|
...items.mutations,
|
||||||
...notes.mutations,
|
...notes.mutations,
|
||||||
...options.mutations,
|
|
||||||
},
|
},
|
||||||
selectors: {
|
selectors: {
|
||||||
...imports.selectors,
|
...imports.selectors,
|
||||||
...items.selectors,
|
...items.selectors,
|
||||||
...notes.selectors,
|
...notes.selectors,
|
||||||
...options.selectors,
|
|
||||||
...reportItems.selectors,
|
...reportItems.selectors,
|
||||||
...reportStats.selectors,
|
...reportStats.selectors,
|
||||||
...reviews.selectors,
|
...reviews.selectors,
|
||||||
|
@ -39,7 +36,6 @@ function createWcApiSpec() {
|
||||||
...imports.operations.read( resourceNames ),
|
...imports.operations.read( resourceNames ),
|
||||||
...items.operations.read( resourceNames ),
|
...items.operations.read( resourceNames ),
|
||||||
...notes.operations.read( resourceNames ),
|
...notes.operations.read( resourceNames ),
|
||||||
...options.operations.read( resourceNames ),
|
|
||||||
...reportItems.operations.read( resourceNames ),
|
...reportItems.operations.read( resourceNames ),
|
||||||
...reportStats.operations.read( resourceNames ),
|
...reportStats.operations.read( resourceNames ),
|
||||||
...reviews.operations.read( resourceNames ),
|
...reviews.operations.read( resourceNames ),
|
||||||
|
@ -50,7 +46,6 @@ function createWcApiSpec() {
|
||||||
...reportExport.operations.update( resourceNames, data ),
|
...reportExport.operations.update( resourceNames, data ),
|
||||||
...items.operations.update( resourceNames, data ),
|
...items.operations.update( resourceNames, data ),
|
||||||
...notes.operations.update( resourceNames, data ),
|
...notes.operations.update( resourceNames, data ),
|
||||||
...options.operations.update( resourceNames, data ),
|
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
remove( resourceNames, data ) {
|
remove( resourceNames, data ) {
|
||||||
|
|
|
@ -7,6 +7,11 @@ import { Button, Modal } from '@wordpress/components';
|
||||||
import { withDispatch } from '@wordpress/data';
|
import { withDispatch } from '@wordpress/data';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommerce dependencies
|
||||||
|
*/
|
||||||
|
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
|
@ -75,7 +80,7 @@ export class DismissModal extends Component {
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { updateOptions } = dispatch( 'wc-api' );
|
const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
|
||||||
return { updateOptions };
|
return { updateOptions };
|
||||||
} )
|
} )
|
||||||
)( DismissModal );
|
)( DismissModal );
|
||||||
|
|
|
@ -12,3 +12,6 @@ export { withOnboardingHydration } from './onboarding/with-onboarding-hydration'
|
||||||
export { USER_STORE_NAME } from './user-preferences';
|
export { USER_STORE_NAME } from './user-preferences';
|
||||||
export { withCurrentUserHydration } from './user-preferences/with-current-user-hydration';
|
export { withCurrentUserHydration } from './user-preferences/with-current-user-hydration';
|
||||||
export { useUserPreferences } from './user-preferences/use-user-preferences';
|
export { useUserPreferences } from './user-preferences/use-user-preferences';
|
||||||
|
|
||||||
|
export { OPTIONS_STORE_NAME } from './options';
|
||||||
|
export { withOptionsHydration } from './options/with-options-hydration';
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
const TYPES = {
|
||||||
|
RECEIVE_OPTIONS: 'RECEIVE_OPTIONS',
|
||||||
|
SET_IS_REQUESTING: 'SET_IS_REQUESTING',
|
||||||
|
SET_IS_UPDATING: 'SET_IS_UPDATING',
|
||||||
|
SET_REQUESTING_ERROR: 'SET_REQUESTING_ERROR',
|
||||||
|
SET_UPDATING_ERROR: 'SET_UPDATING_ERROR',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TYPES;
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* External Dependencies
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { apiFetch } from '@wordpress/data-controls';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal Dependencies
|
||||||
|
*/
|
||||||
|
import TYPES from './action-types';
|
||||||
|
import { WC_ADMIN_NAMESPACE } from '../constants';
|
||||||
|
|
||||||
|
export function receiveOptions( options ) {
|
||||||
|
return {
|
||||||
|
type: TYPES.RECEIVE_OPTIONS,
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setRequestingError( error, name ) {
|
||||||
|
return {
|
||||||
|
type: TYPES.SET_REQUESTING_ERROR,
|
||||||
|
error,
|
||||||
|
name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setUpdatingError( error ) {
|
||||||
|
return {
|
||||||
|
type: TYPES.SET_UPDATING_ERROR,
|
||||||
|
error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setIsUpdating( isUpdating ) {
|
||||||
|
return {
|
||||||
|
type: TYPES.SET_IS_UPDATING,
|
||||||
|
isUpdating,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* updateOptions( data ) {
|
||||||
|
yield setIsUpdating( true );
|
||||||
|
yield receiveOptions( data );
|
||||||
|
|
||||||
|
try {
|
||||||
|
const results = yield apiFetch( {
|
||||||
|
path: WC_ADMIN_NAMESPACE + '/options',
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
} );
|
||||||
|
|
||||||
|
yield setIsUpdating( false );
|
||||||
|
return { success: true, ...results };
|
||||||
|
} catch ( error ) {
|
||||||
|
yield setUpdatingError( error );
|
||||||
|
return { success: false, ...error };
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
export const STORE_NAME = 'wc/admin/options';
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { controls as dataControls } from '@wordpress/data-controls';
|
||||||
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { WC_ADMIN_NAMESPACE } from '../constants';
|
||||||
|
|
||||||
|
let optionNames = [];
|
||||||
|
const fetches = {};
|
||||||
|
|
||||||
|
export const batchFetch = ( optionName ) => {
|
||||||
|
return {
|
||||||
|
type: 'BATCH_FETCH',
|
||||||
|
optionName,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const controls = {
|
||||||
|
...dataControls,
|
||||||
|
BATCH_FETCH( { optionName } ) {
|
||||||
|
optionNames.push( optionName );
|
||||||
|
|
||||||
|
return new Promise( resolve => {
|
||||||
|
setTimeout( function() {
|
||||||
|
const names = optionNames.join(',');
|
||||||
|
if ( fetches[ names ] ) {
|
||||||
|
return fetches[ names ].then( ( result ) => {
|
||||||
|
resolve( result[ optionName ] );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = WC_ADMIN_NAMESPACE + '/options?options=' + names;
|
||||||
|
fetches[ names ] = apiFetch( { path: url } );
|
||||||
|
fetches[names].then( ( result ) => resolve( result ) )
|
||||||
|
|
||||||
|
// Clear option names after all resolved;
|
||||||
|
setTimeout( () => {
|
||||||
|
optionNames = [];
|
||||||
|
// Delete the fetch after to allow wp data to handle cache invalidation.
|
||||||
|
delete fetches[ names ];
|
||||||
|
}, 1 )
|
||||||
|
|
||||||
|
}, 1 );
|
||||||
|
} );
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { registerStore } from '@wordpress/data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { STORE_NAME } from './constants';
|
||||||
|
import * as selectors from './selectors';
|
||||||
|
import * as actions from './actions';
|
||||||
|
import * as resolvers from './resolvers';
|
||||||
|
import { controls } from './controls';
|
||||||
|
import reducer from './reducer';
|
||||||
|
|
||||||
|
registerStore( STORE_NAME, {
|
||||||
|
reducer,
|
||||||
|
actions,
|
||||||
|
controls,
|
||||||
|
selectors,
|
||||||
|
resolvers,
|
||||||
|
} );
|
||||||
|
|
||||||
|
export const OPTIONS_STORE_NAME = STORE_NAME;
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import TYPES from './action-types';
|
||||||
|
|
||||||
|
const optionsReducer = (
|
||||||
|
state = { isUpdating: false, requestingErrors: {} },
|
||||||
|
{ type, options, error, isUpdating, name }
|
||||||
|
) => {
|
||||||
|
switch ( type ) {
|
||||||
|
case TYPES.RECEIVE_OPTIONS:
|
||||||
|
state = {
|
||||||
|
...state,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case TYPES.SET_IS_UPDATING:
|
||||||
|
state = {
|
||||||
|
...state,
|
||||||
|
isUpdating,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case TYPES.SET_REQUESTING_ERROR:
|
||||||
|
state = {
|
||||||
|
...state,
|
||||||
|
requestingErrors: {
|
||||||
|
[ name ]: error,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case TYPES.SET_UPDATING_ERROR:
|
||||||
|
state = {
|
||||||
|
...state,
|
||||||
|
error,
|
||||||
|
updatingError: error,
|
||||||
|
isUpdating: false,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default optionsReducer;
|
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
* External Dependencies
|
||||||
|
*/
|
||||||
|
import { batchFetch } from './controls';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { receiveOptions, setRequestingError } from './actions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request an option value.
|
||||||
|
*
|
||||||
|
* @param {string} name - Option name
|
||||||
|
*/
|
||||||
|
export function* getOption( name ) {
|
||||||
|
try {
|
||||||
|
const result = yield batchFetch( name );
|
||||||
|
yield receiveOptions( result );
|
||||||
|
} catch ( error ) {
|
||||||
|
yield setRequestingError( error, name );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* Get option from state tree.
|
||||||
|
*
|
||||||
|
* @param {Object} state - Reducer state
|
||||||
|
* @param {Array} name - Option name
|
||||||
|
*/
|
||||||
|
export const getOption = ( state, name ) => {
|
||||||
|
return state[ name ];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if an options request resulted in an error.
|
||||||
|
*
|
||||||
|
* @param {Object} state - Reducer state
|
||||||
|
* @param {string} name - Option name
|
||||||
|
*/
|
||||||
|
export const getOptionsRequestingError = ( state, name ) => {
|
||||||
|
return state.requestingErrors[ name ] || false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if options are being updated.
|
||||||
|
*
|
||||||
|
* @param {Object} state - Reducer state
|
||||||
|
*/
|
||||||
|
export const isOptionsUpdating = ( state ) => {
|
||||||
|
return state.isUpdating || false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if an options update resulted in an error.
|
||||||
|
*
|
||||||
|
* @param {Object} state - Reducer state
|
||||||
|
*/
|
||||||
|
export const getOptionsUpdatingError = ( state ) => {
|
||||||
|
return state.updatingError || false;
|
||||||
|
};
|
|
@ -0,0 +1,60 @@
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import reducer from '../reducer';
|
||||||
|
import TYPES from '../action-types';
|
||||||
|
|
||||||
|
const defaultState = { isUpdating: false, requestingErrors: {} };
|
||||||
|
|
||||||
|
describe( 'options reducer', () => {
|
||||||
|
it( 'should return a default state', () => {
|
||||||
|
const state = reducer( undefined, {} );
|
||||||
|
expect( state ).toEqual( defaultState );
|
||||||
|
expect( state ).not.toBe( defaultState );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should handle RECEIVE_OPTIONS', () => {
|
||||||
|
const state = reducer( defaultState, {
|
||||||
|
type: TYPES.RECEIVE_OPTIONS,
|
||||||
|
options: { test_option: 'abc' },
|
||||||
|
} );
|
||||||
|
|
||||||
|
/* eslint-disable dot-notation */
|
||||||
|
expect( state.requestingErrors[ 'test_option' ] ).toBeUndefined();
|
||||||
|
expect( state[ 'test_option' ] ).toBe( 'abc' );
|
||||||
|
/* eslint-enable dot-notation */
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should handle SET_REQUESTING_ERROR', () => {
|
||||||
|
const state = reducer( defaultState, {
|
||||||
|
type: TYPES.SET_REQUESTING_ERROR,
|
||||||
|
error: 'My bad',
|
||||||
|
name: 'test_option'
|
||||||
|
} );
|
||||||
|
|
||||||
|
/* eslint-disable dot-notation */
|
||||||
|
expect( state.requestingErrors[ 'test_option' ] ).toBe( 'My bad' );
|
||||||
|
expect( state[ 'test_option' ] ).toBeUndefined();
|
||||||
|
/* eslint-enable dot-notation */
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should handle SET_UPDATING_ERROR', () => {
|
||||||
|
const state = reducer( defaultState, {
|
||||||
|
type: TYPES.SET_UPDATING_ERROR,
|
||||||
|
error: 'My bad',
|
||||||
|
} );
|
||||||
|
|
||||||
|
expect( state.updatingError ).toBe( 'My bad' );
|
||||||
|
expect( state.isUpdating ).toBe( false );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should handle SET_IS_UPDATING', () => {
|
||||||
|
const state = reducer( defaultState, {
|
||||||
|
type: TYPES.SET_IS_UPDATING,
|
||||||
|
isUpdating: true,
|
||||||
|
} );
|
||||||
|
|
||||||
|
expect( state.isUpdating ).toBe( true );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { useRef } from '@wordpress/element';
|
||||||
|
import { useSelect } from '@wordpress/data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { STORE_NAME } from './constants';
|
||||||
|
|
||||||
|
export const withOptionsHydration = ( data ) => ( OriginalComponent ) => {
|
||||||
|
return ( props ) => {
|
||||||
|
const dataRef = useRef( data );
|
||||||
|
|
||||||
|
useSelect( ( select, registry ) => {
|
||||||
|
if ( ! dataRef.current ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { isResolving, hasFinishedResolution } = select( STORE_NAME );
|
||||||
|
const {
|
||||||
|
startResolution,
|
||||||
|
finishResolution,
|
||||||
|
receiveOptions,
|
||||||
|
} = registry.dispatch( STORE_NAME );
|
||||||
|
const names = Object.keys( dataRef.current );
|
||||||
|
|
||||||
|
names.forEach( ( name ) => {
|
||||||
|
if (
|
||||||
|
! isResolving( 'getOption', [ name ] ) &&
|
||||||
|
! hasFinishedResolution( 'getOption', [ name ] )
|
||||||
|
) {
|
||||||
|
startResolution( 'getOption', [ name ] );
|
||||||
|
receiveOptions( { [ name ]: dataRef.current[ name ] } );
|
||||||
|
finishResolution( 'getOption', [ name ] );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}, [] );
|
||||||
|
|
||||||
|
return <OriginalComponent { ...props } />;
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue