Add profile onboarding mutators and selectors to wc-api (https://github.com/woocommerce/woocommerce-admin/pull/2310)
* Add onboarding profile selectors and mutators to wc-api * Show onboarding profiler depending on API results * Add initial state hydration for onboarding profile * Add onboarding namespace constant
This commit is contained in:
parent
4c8487abad
commit
3b945b4bba
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Component, Fragment } from '@wordpress/element';
|
||||
import { compose } from '@wordpress/compose';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -17,13 +18,13 @@ import { ReportFilters } from '@woocommerce/components';
|
|||
import StorePerformance from './store-performance';
|
||||
import TaskList from './task-list';
|
||||
import ProfileWizard from './profile-wizard';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
export default class Dashboard extends Component {
|
||||
class Dashboard extends Component {
|
||||
renderDashboardOutput() {
|
||||
const { query, path } = this.props;
|
||||
const { path, profileItems, query } = this.props;
|
||||
|
||||
// @todo This should check a selector client side, with wcSettings.showProfiler as initial state.
|
||||
if ( window.wcAdminFeatures.onboarding && wcSettings.showProfiler ) {
|
||||
if ( window.wcAdminFeatures.onboarding && ! profileItems.skipped && ! profileItems.completed ) {
|
||||
return <ProfileWizard query={ query } />;
|
||||
}
|
||||
|
||||
|
@ -58,3 +59,12 @@ export default class Dashboard extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSelect( select => {
|
||||
const { getProfileItems } = select( 'wc-api' );
|
||||
const profileItems = getProfileItems();
|
||||
|
||||
return { profileItems };
|
||||
} )
|
||||
)( Dashboard );
|
||||
|
|
|
@ -16,6 +16,7 @@ import { updateQueryString } from '@woocommerce/navigation';
|
|||
/**
|
||||
* Internal depdencies
|
||||
*/
|
||||
import { NAMESPACE } from 'wc-api/onboarding/constants';
|
||||
import ProfileWizardHeader from './header';
|
||||
import Plugins from './steps/plugins';
|
||||
import Start from './steps/start';
|
||||
|
@ -105,7 +106,7 @@ class ProfileWizard extends Component {
|
|||
const { addNotice } = this.props;
|
||||
|
||||
return apiFetch( {
|
||||
path: '/wc-admin/v1/onboarding/profile',
|
||||
path: `${ NAMESPACE }/onboarding/profile`,
|
||||
method: 'POST',
|
||||
data: params,
|
||||
} ).catch( error => {
|
||||
|
|
|
@ -14,6 +14,7 @@ import { withDispatch } from '@wordpress/data';
|
|||
* Internal depdencies
|
||||
*/
|
||||
import { H, Stepper, Card } from '@woocommerce/components';
|
||||
import { NAMESPACE } from 'wc-api/onboarding/constants';
|
||||
|
||||
const plugins = [ 'jetpack', 'woocommerce-services' ];
|
||||
|
||||
|
@ -107,7 +108,7 @@ class Plugins extends Component {
|
|||
async doPluginAction( action, plugin ) {
|
||||
try {
|
||||
const pluginResponse = await apiFetch( {
|
||||
path: `/wc-admin/v1/onboarding/plugins/${ action }`,
|
||||
path: `${ NAMESPACE }/onboarding/plugins/${ action }`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
plugin,
|
||||
|
@ -129,7 +130,7 @@ class Plugins extends Component {
|
|||
async connectJetpack() {
|
||||
try {
|
||||
const connectResponse = await apiFetch( {
|
||||
path: '/wc-admin/v1/onboarding/plugins/connect-jetpack',
|
||||
path: `${ NAMESPACE }/onboarding/plugins/connect-jetpack`,
|
||||
} );
|
||||
if ( connectResponse && connectResponse.connectAction ) {
|
||||
window.location = connectResponse.connectAction;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
/** @format */
|
||||
|
||||
export const NAMESPACE = '/wc-admin/v1';
|
|
@ -0,0 +1,13 @@
|
|||
/** @format */
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import operations from './operations';
|
||||
import selectors from './selectors';
|
||||
import mutations from './mutations';
|
||||
|
||||
export default {
|
||||
operations,
|
||||
selectors,
|
||||
mutations,
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
/** @format */
|
||||
|
||||
const updateProfileItems = operations => fields => {
|
||||
const resourceKey = 'onboarding-profile';
|
||||
operations.update( [ resourceKey ], {
|
||||
[ resourceKey ]: fields,
|
||||
} );
|
||||
};
|
||||
|
||||
export default {
|
||||
updateProfileItems,
|
||||
};
|
|
@ -0,0 +1,96 @@
|
|||
/** @format */
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { getResourceName } from '../utils';
|
||||
import { NAMESPACE } from './constants';
|
||||
|
||||
function read( resourceNames, fetch = apiFetch ) {
|
||||
return [ ...readProfileItems( resourceNames, fetch ) ];
|
||||
}
|
||||
|
||||
function update( resourceNames, data, fetch = apiFetch ) {
|
||||
return [ ...updateProfileItems( resourceNames, data, fetch ) ];
|
||||
}
|
||||
|
||||
function readProfileItems( resourceNames, fetch ) {
|
||||
const resourceName = 'onboarding-profile';
|
||||
|
||||
if ( resourceNames.includes( resourceName ) ) {
|
||||
const url = NAMESPACE + '/onboarding/profile';
|
||||
|
||||
return [
|
||||
fetch( { path: url } )
|
||||
.then( profileItemsToResources )
|
||||
.catch( error => {
|
||||
return { [ resourceName ]: { error: String( error.message ) } };
|
||||
} ),
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function updateProfileItems( resourceNames, data, fetch ) {
|
||||
const resourceName = 'onboarding-profile';
|
||||
|
||||
if ( resourceNames.includes( resourceName ) ) {
|
||||
const url = NAMESPACE + '/onboarding/profile';
|
||||
|
||||
return [
|
||||
fetch( {
|
||||
path: url,
|
||||
method: 'POST',
|
||||
data: data[ resourceName ],
|
||||
} )
|
||||
.then( profileItemToResource.bind( null, data[ resourceName ] ) )
|
||||
.catch( error => {
|
||||
return { [ resourceName ]: { error } };
|
||||
} ),
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function profileItemsToResources( items ) {
|
||||
const resourceName = 'onboarding-profile';
|
||||
|
||||
const itemKeys = Object.keys( items );
|
||||
|
||||
const resources = {};
|
||||
itemKeys.forEach( key => {
|
||||
const item = items[ key ];
|
||||
resources[ getResourceName( resourceName, key ) ] = { data: item };
|
||||
} );
|
||||
|
||||
return {
|
||||
[ resourceName ]: {
|
||||
data: itemKeys,
|
||||
},
|
||||
...resources,
|
||||
};
|
||||
}
|
||||
|
||||
function profileItemToResource( items ) {
|
||||
const resourceName = 'onboarding-profile';
|
||||
|
||||
const resources = {};
|
||||
Object.keys( items ).forEach( key => {
|
||||
const item = items[ key ];
|
||||
resources[ getResourceName( resourceName, key ) ] = { data: item };
|
||||
} );
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
export default {
|
||||
read,
|
||||
update,
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
/** @format */
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { isNil } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { DEFAULT_REQUIREMENT } from '../constants';
|
||||
import { getResourceName } from '../utils';
|
||||
|
||||
const getProfileItems = ( getResource, requireResource ) => (
|
||||
requirement = DEFAULT_REQUIREMENT
|
||||
) => {
|
||||
const resourceName = 'onboarding-profile';
|
||||
const ids = requireResource( requirement, resourceName ).data || [];
|
||||
|
||||
if ( ! ids.length ) {
|
||||
return wcSettings.onboardingProfile;
|
||||
}
|
||||
|
||||
const items = {};
|
||||
ids.forEach( id => {
|
||||
items[ id ] = getResource( getResourceName( resourceName, id ) ).data;
|
||||
} );
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
const getProfileItemsError = getResource => () => {
|
||||
return getResource( 'onboarding-profile' ).error;
|
||||
};
|
||||
|
||||
const isGetProfileItemsRequesting = getResource => () => {
|
||||
const { lastReceived, lastRequested } = getResource( 'onboarding-profile' );
|
||||
|
||||
if ( isNil( lastRequested ) || isNil( lastReceived ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return lastRequested > lastReceived;
|
||||
};
|
||||
|
||||
export default {
|
||||
getProfileItems,
|
||||
getProfileItemsError,
|
||||
isGetProfileItemsRequesting,
|
||||
};
|
|
@ -6,6 +6,7 @@
|
|||
import items from './items';
|
||||
import imports from './imports';
|
||||
import notes from './notes';
|
||||
import onboarding from './onboarding';
|
||||
import reportItems from './reports/items';
|
||||
import reportStats from './reports/stats';
|
||||
import reviews from './reviews';
|
||||
|
@ -18,6 +19,7 @@ function createWcApiSpec() {
|
|||
mutations: {
|
||||
...items.mutations,
|
||||
...notes.mutations,
|
||||
...onboarding.mutations,
|
||||
...settings.mutations,
|
||||
...user.mutations,
|
||||
},
|
||||
|
@ -25,6 +27,7 @@ function createWcApiSpec() {
|
|||
...imports.selectors,
|
||||
...items.selectors,
|
||||
...notes.selectors,
|
||||
...onboarding.selectors,
|
||||
...reportItems.selectors,
|
||||
...reportStats.selectors,
|
||||
...reviews.selectors,
|
||||
|
@ -37,6 +40,7 @@ function createWcApiSpec() {
|
|||
...imports.operations.read( resourceNames ),
|
||||
...items.operations.read( resourceNames ),
|
||||
...notes.operations.read( resourceNames ),
|
||||
...onboarding.operations.read( resourceNames ),
|
||||
...reportItems.operations.read( resourceNames ),
|
||||
...reportStats.operations.read( resourceNames ),
|
||||
...reviews.operations.read( resourceNames ),
|
||||
|
@ -48,6 +52,7 @@ function createWcApiSpec() {
|
|||
return [
|
||||
...items.operations.update( resourceNames, data ),
|
||||
...notes.operations.update( resourceNames, data ),
|
||||
...onboarding.operations.update( resourceNames, data ),
|
||||
...settings.operations.update( resourceNames, data ),
|
||||
...user.operations.update( resourceNames, data ),
|
||||
];
|
||||
|
|
|
@ -41,15 +41,10 @@ class WC_Admin_Onboarding {
|
|||
* @return bool
|
||||
*/
|
||||
public function should_show_profiler() {
|
||||
// @todo Remove this once we have a proper way to dismiss the profiler.
|
||||
if ( ! defined( 'WOOCOMMERCE_ADMIN_DEV_SHOW_PROFILER' ) || false === WOOCOMMERCE_ADMIN_DEV_SHOW_PROFILER ) {
|
||||
return false;
|
||||
}
|
||||
$onboarding_data = get_option( 'wc_onboarding_profile', array() );
|
||||
|
||||
// @todo Update this to compare to proper bools (https://github.com/woocommerce/woocommerce-admin/issues/2299).
|
||||
$is_completed = isset( $onboarding_data['completed'] ) && 'true' === $onboarding_data['completed'];
|
||||
$is_skipped = isset( $onboarding_data['skipped'] ) && 'true' === $onboarding_data['skipped'];
|
||||
$is_completed = isset( $onboarding_data['completed'] ) && true === $onboarding_data['completed'];
|
||||
$is_skipped = isset( $onboarding_data['skipped'] ) && true === $onboarding_data['skipped'];
|
||||
|
||||
// @todo When merging to WooCommerce Core, we should set the `completed` flag to true during the upgrade progress.
|
||||
// https://github.com/woocommerce/woocommerce-admin/pull/2300#discussion_r287237498.
|
||||
|
@ -57,12 +52,12 @@ class WC_Admin_Onboarding {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add profiler status to component settings.
|
||||
* Add profiler items to component settings.
|
||||
*
|
||||
* @param array $settings Component settings.
|
||||
*/
|
||||
public function component_settings( $settings ) {
|
||||
$settings['showProfiler'] = $this->should_show_profiler();
|
||||
$settings['onboardingProfile'] = get_option( 'wc_onboarding_profile', array() );
|
||||
return $settings;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue