Add plugin and jetpack wc-api methods to shipping task (https://github.com/woocommerce/woocommerce-admin/pull/2778)
* Add shipping labels step * Add jetpack connection selectors to wc-api * Add plugin install and activation methods to wc-api * Add shipping connect step * Add busy cursor CSS to buttons
This commit is contained in:
parent
f4d7936b17
commit
234e4d513c
|
@ -2,20 +2,19 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Button } from 'newspack-components';
|
||||
import { Component, Fragment } from '@wordpress/element';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
import { forEach } from 'lodash';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { difference } from 'lodash';
|
||||
import { withDispatch } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal depdencies
|
||||
*/
|
||||
import { H, Stepper, Card } from '@woocommerce/components';
|
||||
import { NAMESPACE } from 'wc-api/onboarding/constants';
|
||||
import { recordEvent } from 'lib/tracks';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
const plugins = [ 'jetpack', 'woocommerce-services' ];
|
||||
|
||||
|
@ -25,138 +24,53 @@ class Plugins extends Component {
|
|||
|
||||
this.state = {
|
||||
step: 'install',
|
||||
isPending: true,
|
||||
isError: false,
|
||||
pluginsInstalled: 0,
|
||||
pluginsActivated: 0,
|
||||
connectUrl: '',
|
||||
};
|
||||
|
||||
this.activatePlugins = this.activatePlugins.bind( this );
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.installPlugins();
|
||||
this.props.installPlugins( plugins );
|
||||
}
|
||||
|
||||
componentDidUpdate( prevProps, prevState ) {
|
||||
componentDidUpdate( prevProps ) {
|
||||
const { createNotice, errors, installedPlugins, jetpackConnectUrl } = this.props;
|
||||
|
||||
if ( jetpackConnectUrl ) {
|
||||
window.location = jetpackConnectUrl;
|
||||
}
|
||||
|
||||
const newErrors = difference( errors, prevProps.errors );
|
||||
newErrors.map( error => createNotice( 'error', error ) );
|
||||
|
||||
if (
|
||||
this.state.pluginsInstalled !== prevState.pluginsInstalled &&
|
||||
this.state.pluginsInstalled === plugins.length
|
||||
prevProps.installedPlugins.length !== plugins.length &&
|
||||
installedPlugins.length === plugins.length
|
||||
) {
|
||||
/* eslint-disable react/no-did-update-set-state */
|
||||
this.setState( {
|
||||
step: 'activate',
|
||||
isPending: false,
|
||||
} );
|
||||
this.setState( { step: 'activate' } );
|
||||
/* eslint-enable react/no-did-update-set-state */
|
||||
}
|
||||
|
||||
if (
|
||||
this.state.pluginsActivated !== prevState.pluginsActivated &&
|
||||
this.state.pluginsActivated === plugins.length
|
||||
) {
|
||||
this.connectJetpack();
|
||||
}
|
||||
}
|
||||
|
||||
installPlugins() {
|
||||
forEach( plugins, async plugin => {
|
||||
const response = await this.doPluginAction( 'install', plugin );
|
||||
if ( 'success' === response.status ) {
|
||||
this.setState( state => ( {
|
||||
pluginsInstalled: state.pluginsInstalled + 1,
|
||||
} ) );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
activatePlugins( event ) {
|
||||
async activatePlugins( event ) {
|
||||
event.preventDefault();
|
||||
|
||||
// Avoid double activating.
|
||||
const { isPending } = this.state;
|
||||
if ( isPending ) {
|
||||
const { isRequesting } = this.props;
|
||||
if ( isRequesting ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.setState( {
|
||||
isPending: true,
|
||||
} );
|
||||
|
||||
recordEvent( 'storeprofiler_install_plugin' );
|
||||
|
||||
forEach( plugins, async plugin => {
|
||||
const response = await this.doPluginAction( 'activate', plugin );
|
||||
if ( 'success' === response.status ) {
|
||||
this.setState( state => ( {
|
||||
pluginsActivated: state.pluginsActivated + 1,
|
||||
} ) );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
getErrorMessage( action, plugin ) {
|
||||
return 'install' === action
|
||||
? sprintf(
|
||||
__( 'There was an error installing %s. Please try again.', 'woocommerce-admin' ),
|
||||
this.getPluginName( plugin )
|
||||
)
|
||||
: sprintf(
|
||||
__( 'There was an error activating %s. Please try again.', 'woocommerce-admin' ),
|
||||
this.getPluginName( plugin )
|
||||
);
|
||||
}
|
||||
|
||||
async doPluginAction( action, plugin ) {
|
||||
try {
|
||||
const pluginResponse = await apiFetch( {
|
||||
path: `${ NAMESPACE }/onboarding/plugins/${ action }`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
plugin,
|
||||
},
|
||||
} );
|
||||
return pluginResponse;
|
||||
} catch ( err ) {
|
||||
this.props.createNotice( 'error', this.getErrorMessage( action, plugin ) );
|
||||
this.setState( {
|
||||
isPending: false,
|
||||
isError: true,
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
async connectJetpack() {
|
||||
try {
|
||||
const connectResponse = await apiFetch( {
|
||||
path: `${ NAMESPACE }/onboarding/plugins/connect-jetpack`,
|
||||
} );
|
||||
if ( connectResponse && connectResponse.connectAction ) {
|
||||
window.location = connectResponse.connectAction;
|
||||
return;
|
||||
}
|
||||
throw new Error();
|
||||
} catch ( err ) {
|
||||
this.props.createNotice( 'error', this.getErrorMessage( 'activate', 'jetpack' ) );
|
||||
this.setState( {
|
||||
isPending: false,
|
||||
isError: true,
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
getPluginName( plugin ) {
|
||||
switch ( plugin ) {
|
||||
case 'jetpack':
|
||||
return __( 'Jetpack', 'woocommerce-admin' );
|
||||
case 'woocommerce-services':
|
||||
return __( 'WooCommerce Services', 'woocommerce-admin' );
|
||||
}
|
||||
this.props.activatePlugins( plugins );
|
||||
}
|
||||
|
||||
render() {
|
||||
const { step, isPending, isError } = this.state;
|
||||
const { hasErrors, isRequesting } = this.props;
|
||||
const { step } = this.state;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<H className="woocommerce-profile-wizard__header-title">
|
||||
|
@ -167,7 +81,7 @@ class Plugins extends Component {
|
|||
<Stepper
|
||||
isVertical={ true }
|
||||
currentStep={ step }
|
||||
isPending={ isPending }
|
||||
isPending={ isRequesting && ! hasErrors }
|
||||
steps={ [
|
||||
{
|
||||
label: __( 'Install Jetpack and WooCommerce Services', 'woocommerce-admin' ),
|
||||
|
@ -181,18 +95,17 @@ class Plugins extends Component {
|
|||
/>
|
||||
|
||||
<div className="woocommerce-profile-wizard__plugins-actions">
|
||||
{ isError && (
|
||||
{ hasErrors && (
|
||||
<Button isPrimary onClick={ () => location.reload() }>
|
||||
{ __( 'Retry', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
) }
|
||||
|
||||
{ ! isError &&
|
||||
'activate' === step && (
|
||||
<Button isPrimary isBusy={ isPending } onClick={ this.activatePlugins }>
|
||||
{ __( 'Activate & continue', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
) }
|
||||
{ ! ( hasErrors && 'activate' === step ) && (
|
||||
<Button isPrimary isBusy={ isRequesting } onClick={ this.activatePlugins }>
|
||||
{ __( 'Activate & continue', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
) }
|
||||
</div>
|
||||
</Card>
|
||||
</Fragment>
|
||||
|
@ -201,10 +114,64 @@ class Plugins extends Component {
|
|||
}
|
||||
|
||||
export default compose(
|
||||
withSelect( select => {
|
||||
const {
|
||||
getJetpackConnectUrl,
|
||||
isGetJetpackConnectUrlRequesting,
|
||||
getJetpackConnectUrlError,
|
||||
getPluginInstallations,
|
||||
getPluginInstallationErrors,
|
||||
getPluginActivations,
|
||||
getPluginActivationErrors,
|
||||
isPluginActivateRequesting,
|
||||
isPluginInstallRequesting,
|
||||
} = select( 'wc-api' );
|
||||
|
||||
const isRequesting =
|
||||
isPluginActivateRequesting() || isPluginInstallRequesting() || getJetpackConnectUrlError();
|
||||
|
||||
const activationErrors = getPluginActivationErrors( plugins );
|
||||
const activatedPlugins = Object.keys( getPluginActivations( plugins ) );
|
||||
const installationErrors = getPluginInstallationErrors( plugins );
|
||||
const installedPlugins = Object.keys( getPluginInstallations( plugins ) );
|
||||
|
||||
const isJetpackConnectUrlRequesting = isGetJetpackConnectUrlRequesting();
|
||||
const jetpackConnectUrlError = getJetpackConnectUrlError();
|
||||
let jetpackConnectUrl = null;
|
||||
if ( activatedPlugins.includes( 'jetpack' ) ) {
|
||||
jetpackConnectUrl = getJetpackConnectUrl();
|
||||
}
|
||||
|
||||
const errors = [];
|
||||
Object.keys( activationErrors ).map( plugin =>
|
||||
errors.push( activationErrors[ plugin ].message )
|
||||
);
|
||||
Object.keys( installationErrors ).map( plugin =>
|
||||
errors.push( installationErrors[ plugin ].message )
|
||||
);
|
||||
if ( jetpackConnectUrlError ) {
|
||||
errors.push( jetpackConnectUrlError );
|
||||
}
|
||||
const hasErrors = Boolean( errors.length );
|
||||
|
||||
return {
|
||||
activatedPlugins,
|
||||
installedPlugins,
|
||||
jetpackConnectUrl,
|
||||
isJetpackConnectUrlRequesting,
|
||||
errors,
|
||||
hasErrors,
|
||||
isRequesting,
|
||||
};
|
||||
} ),
|
||||
withDispatch( dispatch => {
|
||||
const { createNotice } = dispatch( 'core/notices' );
|
||||
const { activatePlugins, installPlugins } = dispatch( 'wc-api' );
|
||||
|
||||
return {
|
||||
activatePlugins,
|
||||
createNotice,
|
||||
installPlugins,
|
||||
};
|
||||
} )
|
||||
)( Plugins );
|
||||
|
|
|
@ -194,6 +194,10 @@
|
|||
|
||||
.muriel-button.is-button {
|
||||
height: 48px;
|
||||
|
||||
&.is-busy {
|
||||
cursor: progress;
|
||||
}
|
||||
}
|
||||
|
||||
.muriel-checkbox input[type='checkbox']:checked {
|
||||
|
|
|
@ -16,9 +16,15 @@
|
|||
margin-right: auto;
|
||||
}
|
||||
|
||||
.muriel-button.is-button {
|
||||
.muriel-button.components-button {
|
||||
height: 40px;
|
||||
margin: 0;
|
||||
min-width: 106px;
|
||||
margin: $gap $gap-smaller 0 0;
|
||||
justify-content: center;
|
||||
|
||||
&:not(.is-primary) {
|
||||
color: $muriel-hot-pink-500;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-list {
|
||||
|
@ -65,10 +71,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.woocommerce-shipping-rates {
|
||||
margin-bottom: $gap;
|
||||
}
|
||||
|
||||
.woocommerce-shipping-rate {
|
||||
display: flex;
|
||||
padding-top: $gap-small;
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/** @format */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Button } from 'newspack-components';
|
||||
import { Component, Fragment } from '@wordpress/element';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { withDispatch } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
class Connect extends Component {
|
||||
constructor() {
|
||||
super( ...arguments );
|
||||
|
||||
this.connectJetpack = this.connectJetpack.bind( this );
|
||||
}
|
||||
|
||||
componentDidUpdate( prevProps ) {
|
||||
const { createNotice, error } = this.props;
|
||||
|
||||
if ( error && error !== prevProps.error ) {
|
||||
createNotice( 'error', error );
|
||||
}
|
||||
}
|
||||
|
||||
async connectJetpack() {
|
||||
const { jetpackConnectUrl } = this.props;
|
||||
window.location = jetpackConnectUrl;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { hasErrors, isRequesting } = this.props;
|
||||
|
||||
return hasErrors ? (
|
||||
<Button isPrimary onClick={ () => location.reload() }>
|
||||
{ __( 'Retry', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
) : (
|
||||
<Fragment>
|
||||
<Button isBusy={ isRequesting } isPrimary onClick={ this.connectJetpack }>
|
||||
{ __( 'Connect', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSelect( select => {
|
||||
const {
|
||||
getJetpackConnectUrl,
|
||||
isGetJetpackConnectUrlRequesting,
|
||||
getJetpackConnectUrlError,
|
||||
} = select( 'wc-api' );
|
||||
|
||||
const isRequesting = isGetJetpackConnectUrlRequesting();
|
||||
const error = getJetpackConnectUrlError();
|
||||
const jetpackConnectUrl = getJetpackConnectUrl();
|
||||
|
||||
return {
|
||||
error,
|
||||
isRequesting,
|
||||
jetpackConnectUrl,
|
||||
};
|
||||
} ),
|
||||
withDispatch( dispatch => {
|
||||
const { createNotice } = dispatch( 'core/notices' );
|
||||
|
||||
return {
|
||||
createNotice,
|
||||
};
|
||||
} )
|
||||
)( Connect );
|
|
@ -18,7 +18,9 @@ import { getHistory, getNewPath } from '@woocommerce/navigation';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Connect from './connect';
|
||||
import StoreLocation from './location';
|
||||
import ShippingLabels from './labels';
|
||||
import ShippingRates from './rates';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
|
@ -137,6 +139,8 @@ class Shipping extends Component {
|
|||
}
|
||||
|
||||
getSteps() {
|
||||
const { countryCode } = this.props;
|
||||
|
||||
const steps = [
|
||||
{
|
||||
key: 'store_location',
|
||||
|
@ -161,6 +165,27 @@ class Shipping extends Component {
|
|||
),
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
key: 'label_printing',
|
||||
label: __( 'Enable shipping label printing', 'woocommerce-admin' ),
|
||||
description: __(
|
||||
'With WooCommerce Services and Jetpack you can save time at the' +
|
||||
'Post Office by printing your shipping labels at home',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
content: <ShippingLabels completeStep={ this.completeStep } { ...this.props } />,
|
||||
visible: [ 'US', 'GB', 'CA', 'AU' ].includes( countryCode ),
|
||||
},
|
||||
{
|
||||
key: 'connect',
|
||||
label: __( 'Connect your store', 'woocommerce-admin' ),
|
||||
description: __(
|
||||
'Connect your store to WordPress.com to enable label printing',
|
||||
'woocommerce-admin'
|
||||
),
|
||||
content: <Connect completeStep={ this.completeStep } { ...this.props } />,
|
||||
visible: 'US' === countryCode,
|
||||
},
|
||||
];
|
||||
|
||||
return filter( steps, step => step.visible );
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/** @format */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Button } from 'newspack-components';
|
||||
import { Component, Fragment } from '@wordpress/element';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { difference } from 'lodash';
|
||||
import { withDispatch } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* WooCommerce dependencies
|
||||
*/
|
||||
import { getHistory, getNewPath } from '@woocommerce/navigation';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
const plugins = [ 'jetpack', 'woocommerce-services' ];
|
||||
|
||||
class ShippingLabels extends Component {
|
||||
constructor() {
|
||||
super( ...arguments );
|
||||
|
||||
this.installAndActivatePlugins = this.installAndActivatePlugins.bind( this );
|
||||
}
|
||||
|
||||
componentDidUpdate( prevProps ) {
|
||||
const {
|
||||
activatedPlugins,
|
||||
activatePlugins,
|
||||
completeStep,
|
||||
createNotice,
|
||||
errors,
|
||||
installedPlugins,
|
||||
isRequesting,
|
||||
} = this.props;
|
||||
|
||||
const newErrors = difference( errors, prevProps.errors );
|
||||
newErrors.map( error => createNotice( 'error', error ) );
|
||||
|
||||
if (
|
||||
! isRequesting &&
|
||||
installedPlugins.length === plugins.length &&
|
||||
activatedPlugins.length !== plugins.length &&
|
||||
prevProps.installedPlugins.length !== installedPlugins.length
|
||||
) {
|
||||
activatePlugins( plugins );
|
||||
}
|
||||
|
||||
if ( activatedPlugins.length === plugins.length ) {
|
||||
createNotice(
|
||||
'success',
|
||||
__( 'Plugins were successfully installed and activated.', 'woocommerce-admin' )
|
||||
);
|
||||
completeStep();
|
||||
}
|
||||
}
|
||||
|
||||
async installAndActivatePlugins( event ) {
|
||||
event.preventDefault();
|
||||
|
||||
// Avoid double activating.
|
||||
const { isRequesting, installPlugins } = this.props;
|
||||
if ( isRequesting ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
installPlugins( plugins );
|
||||
}
|
||||
|
||||
skipInstaller() {
|
||||
getHistory().push( getNewPath( {}, '/', {} ) );
|
||||
}
|
||||
|
||||
render() {
|
||||
const { hasErrors, isRequesting } = this.props;
|
||||
|
||||
return hasErrors ? (
|
||||
<Button isPrimary onClick={ () => location.reload() }>
|
||||
{ __( 'Retry', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
) : (
|
||||
<Fragment>
|
||||
<Button isBusy={ isRequesting } isPrimary onClick={ this.installAndActivatePlugins }>
|
||||
{ __( 'Install & enable', 'woocommerce-admin' ) }
|
||||
</Button>
|
||||
<Button onClick={ this.skipInstaller }>{ __( 'No thanks', 'woocommerce-admin' ) }</Button>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSelect( select => {
|
||||
const {
|
||||
getPluginInstallations,
|
||||
getPluginInstallationErrors,
|
||||
getPluginActivations,
|
||||
getPluginActivationErrors,
|
||||
isPluginActivateRequesting,
|
||||
isPluginInstallRequesting,
|
||||
} = select( 'wc-api' );
|
||||
|
||||
const isRequesting = isPluginActivateRequesting() || isPluginInstallRequesting();
|
||||
|
||||
const activationErrors = getPluginActivationErrors( plugins );
|
||||
const activatedPlugins = Object.keys( getPluginActivations( plugins ) );
|
||||
const installationErrors = getPluginInstallationErrors( plugins );
|
||||
const installedPlugins = Object.keys( getPluginInstallations( plugins ) );
|
||||
|
||||
const errors = [];
|
||||
Object.keys( activationErrors ).map( plugin =>
|
||||
errors.push( activationErrors[ plugin ].message )
|
||||
);
|
||||
Object.keys( installationErrors ).map( plugin =>
|
||||
errors.push( installationErrors[ plugin ].message )
|
||||
);
|
||||
const hasErrors = Boolean( errors.length );
|
||||
|
||||
return {
|
||||
activatedPlugins,
|
||||
installedPlugins,
|
||||
errors,
|
||||
hasErrors,
|
||||
isRequesting,
|
||||
};
|
||||
} ),
|
||||
withDispatch( dispatch => {
|
||||
const { createNotice } = dispatch( 'core/notices' );
|
||||
const { activatePlugins, installPlugins } = dispatch( 'wc-api' );
|
||||
|
||||
return {
|
||||
activatePlugins,
|
||||
createNotice,
|
||||
installPlugins,
|
||||
};
|
||||
} )
|
||||
)( ShippingLabels );
|
|
@ -1,3 +1,18 @@
|
|||
/** @format */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
/**
|
||||
* Onboarding namespace.
|
||||
*/
|
||||
export const NAMESPACE = '/wc-admin/v1';
|
||||
|
||||
/**
|
||||
* Plugin slugs and names as key/value pairs.
|
||||
*/
|
||||
export const pluginNames = {
|
||||
jetpack: __( 'Jetpack', 'woocommerce-admin' ),
|
||||
'woocommerce-services': __( 'WooCommerce Services', 'woocommerce-admin' ),
|
||||
};
|
||||
|
|
|
@ -7,6 +7,22 @@ const updateProfileItems = operations => fields => {
|
|||
} );
|
||||
};
|
||||
|
||||
const installPlugins = operations => plugins => {
|
||||
const resourceKey = 'plugin-install';
|
||||
operations.update( [ resourceKey ], {
|
||||
[ resourceKey ]: plugins,
|
||||
} );
|
||||
};
|
||||
|
||||
const activatePlugins = operations => plugins => {
|
||||
const resourceKey = 'plugin-activate';
|
||||
operations.update( [ resourceKey ], {
|
||||
[ resourceKey ]: plugins,
|
||||
} );
|
||||
};
|
||||
|
||||
export default {
|
||||
activatePlugins,
|
||||
installPlugins,
|
||||
updateProfileItems,
|
||||
};
|
||||
|
|
|
@ -3,20 +3,28 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { getResourceName } from '../utils';
|
||||
import { NAMESPACE } from './constants';
|
||||
import { NAMESPACE, pluginNames } from './constants';
|
||||
|
||||
function read( resourceNames, fetch = apiFetch ) {
|
||||
return [ ...readProfileItems( resourceNames, fetch ) ];
|
||||
return [
|
||||
...readProfileItems( resourceNames, fetch ),
|
||||
...readJetpackConnectUrl( resourceNames, fetch ),
|
||||
];
|
||||
}
|
||||
|
||||
function update( resourceNames, data, fetch = apiFetch ) {
|
||||
return [ ...updateProfileItems( resourceNames, data, fetch ) ];
|
||||
return [
|
||||
...activatePlugins( resourceNames, data, fetch ),
|
||||
...installPlugins( resourceNames, data, fetch ),
|
||||
...updateProfileItems( resourceNames, data, fetch ),
|
||||
];
|
||||
}
|
||||
|
||||
function readProfileItems( resourceNames, fetch ) {
|
||||
|
@ -90,6 +98,92 @@ function profileItemToResource( items ) {
|
|||
return resources;
|
||||
}
|
||||
|
||||
function readJetpackConnectUrl( resourceNames, fetch ) {
|
||||
const resourceName = 'jetpack-connect-url';
|
||||
|
||||
if ( resourceNames.includes( resourceName ) ) {
|
||||
const url = NAMESPACE + '/onboarding/plugins/connect-jetpack';
|
||||
|
||||
return [
|
||||
fetch( {
|
||||
path: url,
|
||||
} )
|
||||
.then( response => {
|
||||
return { [ resourceName ]: { data: response.connectAction } };
|
||||
} )
|
||||
.catch( error => {
|
||||
error.message = getPluginErrorMessage( 'activate', 'jetpack' );
|
||||
return { [ resourceName ]: { error } };
|
||||
} ),
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function doPluginActions( fetch, action, plugins ) {
|
||||
const resourceName = [ `plugin-${ action }` ];
|
||||
|
||||
return plugins.map( async plugin => {
|
||||
return fetch( {
|
||||
path: `${ NAMESPACE }/onboarding/plugins/${ action }`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
plugin,
|
||||
},
|
||||
} )
|
||||
.then( response => {
|
||||
return {
|
||||
[ resourceName ]: { data: plugins },
|
||||
[ getResourceName( resourceName, plugin ) ]: { data: response },
|
||||
};
|
||||
} )
|
||||
.catch( error => {
|
||||
error.message = getPluginErrorMessage( action, plugin );
|
||||
return {
|
||||
[ resourceName ]: { data: plugins },
|
||||
[ getResourceName( resourceName, plugin ) ]: { error },
|
||||
};
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
function getPluginErrorMessage( action, plugin ) {
|
||||
const pluginName = pluginNames[ plugin ] || plugin;
|
||||
|
||||
return 'install' === action
|
||||
? sprintf(
|
||||
__( 'There was an error installing %s. Please try again.', 'woocommerce-admin' ),
|
||||
pluginName
|
||||
)
|
||||
: sprintf(
|
||||
__( 'There was an error activating %s. Please try again.', 'woocommerce-admin' ),
|
||||
pluginName
|
||||
);
|
||||
}
|
||||
|
||||
function installPlugins( resourceNames, data, fetch ) {
|
||||
const resourceName = 'plugin-install';
|
||||
|
||||
if ( resourceNames.includes( resourceName ) ) {
|
||||
const plugins = data[ resourceName ];
|
||||
return doPluginActions( fetch, 'install', plugins );
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function activatePlugins( resourceNames, data, fetch ) {
|
||||
const resourceName = 'plugin-activate';
|
||||
|
||||
if ( resourceNames.includes( resourceName ) ) {
|
||||
const plugins = data[ resourceName ];
|
||||
return doPluginActions( fetch, 'activate', plugins );
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
export default {
|
||||
read,
|
||||
update,
|
||||
|
|
|
@ -43,8 +43,113 @@ const isGetProfileItemsRequesting = getResource => () => {
|
|||
return lastRequested > lastReceived;
|
||||
};
|
||||
|
||||
const getJetpackConnectUrl = ( getResource, requireResource ) => (
|
||||
requirement = DEFAULT_REQUIREMENT
|
||||
) => {
|
||||
return requireResource( requirement, 'jetpack-connect-url' ).data;
|
||||
};
|
||||
|
||||
const getJetpackConnectUrlError = getResource => () => {
|
||||
return getResource( 'jetpack-connect-url' ).error;
|
||||
};
|
||||
|
||||
const isGetJetpackConnectUrlRequesting = getResource => () => {
|
||||
const { lastReceived, lastRequested } = getResource( 'jetpack-connect-url' );
|
||||
|
||||
if ( isNil( lastRequested ) || isNil( lastReceived ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return lastRequested > lastReceived;
|
||||
};
|
||||
|
||||
const getPluginInstallations = getResource => plugins => {
|
||||
const resourceName = 'plugin-install';
|
||||
|
||||
const installations = {};
|
||||
plugins.forEach( plugin => {
|
||||
const data = getResource( getResourceName( resourceName, plugin ) ).data;
|
||||
if ( data ) {
|
||||
installations[ plugin ] = data;
|
||||
}
|
||||
} );
|
||||
|
||||
return installations;
|
||||
};
|
||||
|
||||
const getPluginActivations = getResource => plugins => {
|
||||
const resourceName = 'plugin-activate';
|
||||
|
||||
const activations = {};
|
||||
plugins.forEach( plugin => {
|
||||
const data = getResource( getResourceName( resourceName, plugin ) ).data;
|
||||
if ( data ) {
|
||||
activations[ plugin ] = data;
|
||||
}
|
||||
} );
|
||||
|
||||
return activations;
|
||||
};
|
||||
|
||||
const getPluginActivationErrors = getResource => plugins => {
|
||||
const resourceName = 'plugin-activate';
|
||||
|
||||
const errors = {};
|
||||
plugins.forEach( plugin => {
|
||||
const error = getResource( getResourceName( resourceName, plugin ) ).error;
|
||||
if ( error ) {
|
||||
errors[ plugin ] = error;
|
||||
}
|
||||
} );
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
const getPluginInstallationErrors = getResource => plugins => {
|
||||
const resourceName = 'plugin-install';
|
||||
|
||||
const errors = {};
|
||||
plugins.forEach( plugin => {
|
||||
const error = getResource( getResourceName( resourceName, plugin ) ).error;
|
||||
if ( error ) {
|
||||
errors[ plugin ] = error;
|
||||
}
|
||||
} );
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
const isPluginActivateRequesting = getResource => () => {
|
||||
const { lastReceived, lastRequested } = getResource( 'plugin-activate' );
|
||||
|
||||
if ( ! isNil( lastRequested ) && isNil( lastReceived ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return lastRequested > lastReceived;
|
||||
};
|
||||
|
||||
const isPluginInstallRequesting = getResource => () => {
|
||||
const { lastReceived, lastRequested } = getResource( 'plugin-install' );
|
||||
|
||||
if ( ! isNil( lastRequested ) && isNil( lastReceived ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return lastRequested > lastReceived;
|
||||
};
|
||||
|
||||
export default {
|
||||
getProfileItems,
|
||||
getProfileItemsError,
|
||||
isGetProfileItemsRequesting,
|
||||
getJetpackConnectUrl,
|
||||
getJetpackConnectUrlError,
|
||||
isGetJetpackConnectUrlRequesting,
|
||||
getPluginActivations,
|
||||
getPluginInstallations,
|
||||
getPluginInstallationErrors,
|
||||
getPluginActivationErrors,
|
||||
isPluginActivateRequesting,
|
||||
isPluginInstallRequesting,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue