Skip to content

Commit

Permalink
Update shipping partner suggestions to use data from API (woocommerce…
Browse files Browse the repository at this point in the history
…#38457)

* Added shipping partner suggestions data handling in JS

* Add woocommerce services real info

* Add dynamic layout components, remove unused JS, added images to proper asset paths

* Changelog

* Update changelog and removed unused variable

* Remove console.log

* Lint fix

* Add shipping methods module in woocommerce/data

* Update data usage

* Revert "Added shipping partner suggestions data handling in JS"

This reverts commit 6a87ef2.

* Lint fix
  • Loading branch information
ilyasfoo authored May 30, 2023
1 parent ab18828 commit edf95bf
Show file tree
Hide file tree
Showing 21 changed files with 416 additions and 363 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Update shipping partner suggestions to use data from API, fix default partners data, replaced hardcoded JS components and added relevant types
7 changes: 7 additions & 0 deletions packages/js/data/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export { NAVIGATION_STORE_NAME } from './navigation';
export { OPTIONS_STORE_NAME } from './options';
export { ITEMS_STORE_NAME } from './items';
export { PAYMENT_GATEWAYS_STORE_NAME } from './payment-gateways';
export { SHIPPING_METHODS_STORE_NAME } from './shipping-methods';
export { PRODUCTS_STORE_NAME } from './products';
export { ORDERS_STORE_NAME } from './orders';
export { EXPERIMENTAL_PRODUCT_ATTRIBUTES_STORE_NAME } from './product-attributes';
Expand All @@ -28,6 +29,7 @@ export { EXPERIMENTAL_PRODUCT_VARIATIONS_STORE_NAME } from './product-variations
export { EXPERIMENTAL_PRODUCT_FORM_STORE_NAME } from './product-form';
export { EXPERIMENTAL_TAX_CLASSES_STORE_NAME } from './tax-classes';
export { PaymentGateway } from './payment-gateways/types';
export { ShippingMethod } from './shipping-methods/types';

// Export hooks
export { withSettingsHydration } from './settings/with-settings-hydration';
Expand Down Expand Up @@ -121,6 +123,7 @@ import type { REPORTS_STORE_NAME } from './reports';
import type { ITEMS_STORE_NAME } from './items';
import type { COUNTRIES_STORE_NAME } from './countries';
import type { PAYMENT_GATEWAYS_STORE_NAME } from './payment-gateways';
import type { SHIPPING_METHODS_STORE_NAME } from './shipping-methods';
import type { PRODUCTS_STORE_NAME } from './products';
import type { ORDERS_STORE_NAME } from './orders';
import type { EXPERIMENTAL_PRODUCT_ATTRIBUTES_STORE_NAME } from './product-attributes';
Expand All @@ -146,6 +149,7 @@ export type WCDataStoreName =
| typeof ITEMS_STORE_NAME
| typeof COUNTRIES_STORE_NAME
| typeof PAYMENT_GATEWAYS_STORE_NAME
| typeof SHIPPING_METHODS_STORE_NAME
| typeof PRODUCTS_STORE_NAME
| typeof ORDERS_STORE_NAME
| typeof EXPERIMENTAL_PRODUCT_ATTRIBUTES_STORE_NAME
Expand All @@ -163,6 +167,7 @@ export type WCDataStoreName =
*/
import { WPDataSelectors } from './types';
import { PaymentSelectors } from './payment-gateways/selectors';
import { ShippingMethodsSelectors } from './shipping-methods/selectors';
import { PluginSelectors } from './plugins/selectors';
import { OnboardingSelectors } from './onboarding/selectors';
import { OptionsSelectors } from './options/types';
Expand Down Expand Up @@ -190,6 +195,8 @@ export type WCSelectorType< T > = T extends typeof REVIEWS_STORE_NAME
? OnboardingSelectors
: T extends typeof PAYMENT_GATEWAYS_STORE_NAME
? PaymentSelectors
: T extends typeof SHIPPING_METHODS_STORE_NAME
? ShippingMethodsSelectors
: T extends typeof USER_STORE_NAME
? WPDataSelectors
: T extends typeof OPTIONS_STORE_NAME
Expand Down
5 changes: 5 additions & 0 deletions packages/js/data/src/shipping-methods/action-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum ACTION_TYPES {
GET_SHIPPING_METHODS_REQUEST = 'GET_SHIPPING_METHODS_REQUEST',
GET_SHIPPING_METHODS_SUCCESS = 'GET_SHIPPING_METHODS_SUCCESS',
GET_SHIPPING_METHODS_ERROR = 'GET_SHIPPING_METHODS_ERROR',
}
30 changes: 30 additions & 0 deletions packages/js/data/src/shipping-methods/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Internal dependencies
*/
import { ACTION_TYPES } from './action-types';
import { ShippingMethod } from './types';

export function getShippingMethodsRequest() {
return {
type: ACTION_TYPES.GET_SHIPPING_METHODS_REQUEST as const,
};
}

export function getShippingMethodsSuccess( shippingMethods: ShippingMethod[] ) {
return {
type: ACTION_TYPES.GET_SHIPPING_METHODS_SUCCESS as const,
shippingMethods,
};
}

export function getShippingMethodsError( error: unknown ) {
return {
type: ACTION_TYPES.GET_SHIPPING_METHODS_ERROR as const,
error,
};
}

export type Actions =
| ReturnType< typeof getShippingMethodsRequest >
| ReturnType< typeof getShippingMethodsSuccess >
| ReturnType< typeof getShippingMethodsError >;
1 change: 1 addition & 0 deletions packages/js/data/src/shipping-methods/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const STORE_KEY = 'wc/shipping-methods';
25 changes: 25 additions & 0 deletions packages/js/data/src/shipping-methods/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* External dependencies
*/
import { createReduxStore, register } from '@wordpress/data';
import { controls } from '@wordpress/data-controls';

/**
* Internal dependencies
*/
import * as actions from './actions';
import * as resolvers from './resolvers';
import * as selectors from './selectors';
import reducer from './reducer';
import { STORE_KEY } from './constants';
export const SHIPPING_METHODS_STORE_NAME = STORE_KEY;

export const store = createReduxStore( SHIPPING_METHODS_STORE_NAME, {
reducer,
selectors,
resolvers,
controls,
actions,
} );

register( store );
54 changes: 54 additions & 0 deletions packages/js/data/src/shipping-methods/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* External dependencies
*/
import { Reducer } from 'redux';

/**
* Internal dependencies
*/
import { ACTION_TYPES } from './action-types';
import { ShippingMethod } from './types';
import { Actions } from './actions';

export type ShippingMethodsState = {
shippingMethods: ShippingMethod[];
isUpdating: boolean;
errors: Record< string, unknown >;
};

const reducer: Reducer< ShippingMethodsState, Actions > = (
state = {
shippingMethods: [],
isUpdating: false,
errors: {},
},
payload
) => {
if ( payload && 'type' in payload ) {
switch ( payload.type ) {
case ACTION_TYPES.GET_SHIPPING_METHODS_REQUEST:
return {
...state,
isUpdating: true,
};
case ACTION_TYPES.GET_SHIPPING_METHODS_SUCCESS:
return {
...state,
shippingMethods: payload.shippingMethods,
isUpdating: false,
};
case ACTION_TYPES.GET_SHIPPING_METHODS_ERROR:
return {
...state,
isUpdating: false,
errors: {
...state.errors,
getShippingMethods: payload.error,
},
};
}
}
return state;
};

export default reducer;
33 changes: 33 additions & 0 deletions packages/js/data/src/shipping-methods/resolvers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* External dependencies
*/
import { apiFetch } from '@wordpress/data-controls';

/**
* Internal dependencies
*/
import {
getShippingMethodsSuccess,
getShippingMethodsRequest,
getShippingMethodsError,
} from './actions';
import { ShippingMethod } from './types';
import { WC_ADMIN_NAMESPACE } from '../constants';

export function* getShippingMethods( forceDefaultSuggestions = false ) {
let path = WC_ADMIN_NAMESPACE + '/shipping-partner-suggestions';
if ( forceDefaultSuggestions ) {
path += '?force_default_suggestions=true';
}
yield getShippingMethodsRequest();
try {
const results: ShippingMethod[] = yield apiFetch( {
path,
method: 'GET',
} );

yield getShippingMethodsSuccess( results );
} catch ( error ) {
yield getShippingMethodsError( error );
}
}
21 changes: 21 additions & 0 deletions packages/js/data/src/shipping-methods/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Internal dependencies
*/
import { ShippingMethodsState } from './reducer';
import { ShippingMethod } from './types';
import { WPDataSelector, WPDataSelectors } from '../types';

export const getShippingMethods = (
state: ShippingMethodsState
): ShippingMethod[] => {
return state.shippingMethods || [];
};

export function isShippingMethodsUpdating(
state: ShippingMethodsState
): boolean {
return state.isUpdating || false;
}
export type ShippingMethodsSelectors = {
getShippingMethods: WPDataSelector< typeof getShippingMethods >;
} & WPDataSelectors;
49 changes: 49 additions & 0 deletions packages/js/data/src/shipping-methods/test-helpers/stub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Internal dependencies
*/
import { ShippingMethod } from '../types';

export const shippingMethodsStub: ShippingMethod[] = [
{
name: 'Dummy shipping method',
slug: 'dummy-shipping-method',
description: 'Dummy shipping method description',
learn_more_link: 'https://example.com',
is_visible: true,
available_layouts: [ 'row' ],
layout_row: {
image: 'https://example.com/image.png',
features: [
{
icon: 'https://example.com/icon.png',
title: 'Feature title',
description: 'Feature description',
},
{
icon: 'https://example.com/icon.png',
title: 'Feature title 2',
description: 'Feature description 2',
},
],
},
},
{
name: 'Dummy shipping method 2',
slug: 'dummy-shipping-method-2',
description: 'Dummy shipping method description',
learn_more_link: 'https://example.com',
is_visible: true,
available_layouts: [ 'column' ],
layout_column: {
image: 'https://example.com/image.png',
features: [
{
icon: 'https://example.com/icon.png',
title: 'Feature title',
description: 'Feature description',
},
],
},
dependencies: [ 'jetpack' ],
},
];
57 changes: 57 additions & 0 deletions packages/js/data/src/shipping-methods/test/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @jest-environment node
*/

/**
* Internal dependencies
*/
import reducer, { ShippingMethodsState } from '../reducer';
import { ACTION_TYPES } from '../action-types';
import { shippingMethodsStub } from '../test-helpers/stub';
import { Actions } from '../actions';

const defaultState: ShippingMethodsState = {
shippingMethods: [],
isUpdating: false,
errors: {},
};

const restApiError = {
code: 'error code',
message: 'error message',
};

describe( 'Shipping methods reducer', () => {
it( 'should return a default state', () => {
const state = reducer( undefined, {} as Actions );
expect( state ).toEqual( defaultState );
expect( state ).not.toBe( defaultState );
} );

it( 'should handle GET_SHIPPING_METHODS_REQUEST', () => {
const state = reducer( defaultState, {
type: ACTION_TYPES.GET_SHIPPING_METHODS_REQUEST,
} );

expect( state.isUpdating ).toBe( true );
} );

it( 'should handle GET_SHIPPING_METHODS_ERROR', () => {
const state = reducer( defaultState, {
type: ACTION_TYPES.GET_SHIPPING_METHODS_ERROR,
error: restApiError,
} );

expect( state.errors.getShippingMethods ).toBe( restApiError );
} );

it( 'should handle GET_SHIPPING_METHODS_SUCCESS', () => {
const state = reducer( defaultState, {
type: ACTION_TYPES.GET_SHIPPING_METHODS_SUCCESS,
shippingMethods: shippingMethodsStub,
} );

expect( state.shippingMethods ).toHaveLength( 2 );
expect( state.shippingMethods ).toBe( shippingMethodsStub );
} );
} );
25 changes: 25 additions & 0 deletions packages/js/data/src/shipping-methods/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Types to describe shipping method object.
type Feature = {
icon: string;
title?: string;
description: string;
};

type Layout = {
image: string;
features: Feature[];
};

type LayoutType = 'row' | 'column';

export type ShippingMethod = {
name: string;
slug: string;
description: string;
learn_more_link: string;
is_visible: boolean;
available_layouts: LayoutType[];
layout_column?: Layout;
layout_row?: Layout;
dependencies?: string[];
};
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

.plugins-install__plugin-banner-image {
display: flex;
width: 150px;

img {
width: 100%;
Expand Down
Loading

0 comments on commit edf95bf

Please sign in to comment.