Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GTIN] Migration notice #2656

Open
wants to merge 17 commits into
base: add/gtin-migration-api-controller
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions js/src/components/gtin-migration-banner/gtin-migration-banner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Notice } from '@wordpress/components';
import { createInterpolateElement, useState } from '@wordpress/element';

/**
* Internal dependencies
*/
import TrackableLink from '.~/components/trackable-link';
import AppButton from '.~/components/app-button';
import AppModal from '.~/components/app-modal';
import { recordGlaEvent } from '.~/utils/tracks';
import useDispatchCoreNotices from '.~/hooks/useDispatchCoreNotices';
import useGTINMigrationStatus from '.~/hooks/useGTINMigrationStatus';
import './index.scss';

const GTIN_MIGRATION_BANNER_CONTEXT = 'gtin_migration_banner';
const GTIN_MIGRATION_READY = 'ready';
const GTIN_MIGRATION_STARTED = 'started';

const LinkGTINMigrationJobStatusPage = ( props ) => (
<TrackableLink

Check warning on line 24 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L24

Added line #L24 was not covered by tests
eventName="gla_gtin_migration_banner_status_link_click"
eventProps={ {
context: GTIN_MIGRATION_BANNER_CONTEXT,
} }
href={
'admin.php?page=wc-status&tab=action-scheduler&s=migrate_gtin&orderby=schedule&order=desc'
}
type="external"
target="_blank"
{ ...props }
/>
);

const GtinMigrationBanner = () => {
const { createNotice } = useDispatchCoreNotices();
const [ showModal, setShowModal ] = useState( false );
const [ status, loading, startMigration ] = useGTINMigrationStatus();

if (
status !== GTIN_MIGRATION_READY &&
status !== GTIN_MIGRATION_STARTED
) {
return null;
}

const closeModal = () => {
recordGlaEvent( 'gla_modal_closed', {

Check warning on line 51 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L50-L51

Added lines #L50 - L51 were not covered by tests
context: GTIN_MIGRATION_BANNER_CONTEXT,
} );
setShowModal( false );

Check warning on line 54 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L54

Added line #L54 was not covered by tests
};

const openModal = () => {
recordGlaEvent( 'gla_modal_open', {

Check warning on line 58 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L57-L58

Added lines #L57 - L58 were not covered by tests
context: GTIN_MIGRATION_BANNER_CONTEXT,
} );
setShowModal( true );

Check warning on line 61 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L61

Added line #L61 was not covered by tests
};

const handleStartMigrationClick = async () => {
recordGlaEvent( 'gla_gtin_migration_banner_migration_start', {

Check warning on line 65 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L64-L65

Added lines #L64 - L65 were not covered by tests
context: GTIN_MIGRATION_BANNER_CONTEXT,
} );
try {
await startMigration();
recordGlaEvent( 'gla_gtin_migration_banner_migration_scheduled', {

Check warning on line 70 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L68-L70

Added lines #L68 - L70 were not covered by tests
context: GTIN_MIGRATION_BANNER_CONTEXT,
} );
setShowModal( false );
createNotice(

Check warning on line 74 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L73-L74

Added lines #L73 - L74 were not covered by tests
'info',
__(
'GTIN Migration was successfully scheduled.',
'google-listings-and-ads'
)
);
} catch ( e ) {
recordGlaEvent( 'gla_gtin_migration_banner_migration_failed', {

Check warning on line 82 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L82

Added line #L82 was not covered by tests
context: GTIN_MIGRATION_BANNER_CONTEXT,
error: e.message,
} );
createNotice(

Check warning on line 86 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L86

Added line #L86 was not covered by tests
'error',
__(
'Unable to start GTIN Migration.',
'google-listings-and-ads'
)
);
}
};

return (

Check warning on line 96 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L96

Added line #L96 was not covered by tests
<>
{ showModal && (
<AppModal

Check warning on line 99 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L98-L99

Added lines #L98 - L99 were not covered by tests
className="gla-gtin-migration-banner-modal"
title={ __(
'Before you start the migration…',
'google-listings-and-ads'
) }
buttons={ [
<AppButton key="1" isSecondary onClick={ closeModal }>
{ __( 'Never mind', 'google-listings-and-ads' ) }
</AppButton>,
<AppButton
key="2"
disabled={ loading }
isPrimary
onClick={ handleStartMigrationClick }
>
{ __(
'Start migration',
'google-listings-and-ads'
) }
</AppButton>,
] }
onRequestClose={ closeModal }
>
<p>
{ createInterpolateElement(
__(
"This migration will copy all GTIN numbers set in the Google for WooCommerce Product tab into the new GTIN field under the Product Inventory tab. If you have already set GTIN numbers in some of your products' Inventory tab, they will not be overridden. The GTIN numbers in the Google for WooCommerce tab will not be removed. The migration will run in the background and is not reversible. You can check the migration process on the <link>WooCommerce Scheduled Actions page</link>.",
'google-listings-and-ads'
),
{
link: <LinkGTINMigrationJobStatusPage />,
}
) }
</p>
</AppModal>
) }
{ status === GTIN_MIGRATION_READY && (
<Notice isDismissible={ false }>

Check warning on line 137 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L136-L137

Added lines #L136 - L137 were not covered by tests
{ createInterpolateElement(
__(
"The GTIN field managed by WooCommerce in the Product's inventory section, will now be used by Google for WooCommerce. It will continue to support the previous field and any mapping rules you have setup for the GTIN field. If you would like to migrate the data <link>click here</link>.",
'google-listings-and-ads'
),
{
link: (
<TrackableLink
className="gla-gtin-migration__link"
eventName="gla_gtin_migration_banner_click"
eventProps={ {
context: GTIN_MIGRATION_BANNER_CONTEXT,
} }
onClick={ openModal }
/>
),
}
) }
</Notice>
) }
{ status === GTIN_MIGRATION_STARTED && (
<Notice isDismissible={ false }>

Check warning on line 159 in js/src/components/gtin-migration-banner/gtin-migration-banner.js

View check run for this annotation

Codecov / codecov/patch

js/src/components/gtin-migration-banner/gtin-migration-banner.js#L158-L159

Added lines #L158 - L159 were not covered by tests
{ createInterpolateElement(
__(
'Your GTIN Migration is now running in the background. You can check the migration process on the <link>WooCommerce Scheduled Actions page</link>',
'google-listings-and-ads'
),
{
link: <LinkGTINMigrationJobStatusPage />,
}
) }
</Notice>
) }
</>
);
};
export default GtinMigrationBanner;
1 change: 1 addition & 0 deletions js/src/components/gtin-migration-banner/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './gtin-migration-banner';
6 changes: 6 additions & 0 deletions js/src/components/gtin-migration-banner/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.gla-gtin-migration {
&__link {
cursor: pointer;
text-decoration: underline;
}
}
9 changes: 7 additions & 2 deletions js/src/components/main-tab-nav/main-tab-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getNewPath, getPath } from '@woocommerce/navigation';
import { glaData } from '.~/constants';
import AppTabNav from '.~/components/app-tab-nav';
import useMenuEffect from '.~/hooks/useMenuEffect';
import GtinMigrationBanner from '.~/components/gtin-migration-banner';

let tabs = [
{
Expand Down Expand Up @@ -55,7 +56,11 @@ const MainTabNav = () => {

const selectedKey = getSelectedTabKey();

return <AppTabNav tabs={ tabs } selectedKey={ selectedKey } />;
return (
<>
<GtinMigrationBanner />
<AppTabNav tabs={ tabs } selectedKey={ selectedKey } />
</>
);
};

export default MainTabNav;
7 changes: 7 additions & 0 deletions js/src/dashboard/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ import isWCTracksEnabled from '.~/utils/isWCTracksEnabled';
import RebrandingTour from '.~/components/tours/rebranding-tour';
import { GUIDE_NAMES } from '.~/constants';

jest.mock( '.~/hooks/useGTINMigrationStatus', () =>
jest
.fn()
.mockReturnValue( [ 'completed', false, jest.fn() ] )
.mockName( 'useGTINMigrationStatus' )
);

jest.mock( '.~/components/different-currency-notice', () =>
jest.fn().mockName( 'DifferentCurrencyNotice' )
);
Expand Down
1 change: 1 addition & 0 deletions js/src/data/action-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const TYPES = {
UPSERT_TOUR: 'UPSERT_TOUR',
HYDRATE_PREFETCHED_DATA: 'HYDRATE_PREFETCHED_DATA',
RECEIVE_GOOGLE_ADS_ACCOUNT_STATUS: 'RECEIVE_GOOGLE_ADS_ACCOUNT_STATUS',
RECEIVE_GTIN_MIGRATION_STATUS: 'RECEIVE_GTIN_MIGRATION_STATUS',
};

export default TYPES;
12 changes: 12 additions & 0 deletions js/src/data/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,18 @@
}
}

/**
* Action to receive the GTIN Migration status.
*
* @param {string} status GTIN Migration status
*/
export function* receiveGtinMigrationStatus( status ) {
return {

Check warning on line 1275 in js/src/data/actions.js

View check run for this annotation

Codecov / codecov/patch

js/src/data/actions.js#L1274-L1275

Added lines #L1274 - L1275 were not covered by tests
type: TYPES.RECEIVE_GTIN_MIGRATION_STATUS,
data: status,
};
}

export function* fetchGoogleAdsAccountStatus() {
try {
const data = yield apiFetch( {
Expand Down
6 changes: 6 additions & 0 deletions js/src/data/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
step: null,
},
},
gtinMigrationStatus: null,
};

/**
Expand Down Expand Up @@ -510,6 +511,11 @@
.end();
}

case TYPES.RECEIVE_GTIN_MIGRATION_STATUS: {
const { data } = action;
return setIn( state, 'gtinMigrationStatus', data?.status );

Check warning on line 516 in js/src/data/reducer.js

View check run for this annotation

Codecov / codecov/patch

js/src/data/reducer.js#L514-L516

Added lines #L514 - L516 were not covered by tests
}

// Page will be reloaded after all accounts have been disconnected, so no need to mutate state.
case TYPES.DISCONNECT_ACCOUNTS_ALL:
default:
Expand Down
22 changes: 22 additions & 0 deletions js/src/data/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
receiveMappingRules,
receiveStoreCategories,
receiveTour,
receiveGtinMigrationStatus,
} from './actions';

export function* getShippingRates() {
Expand Down Expand Up @@ -534,3 +535,24 @@
getGoogleAdsAccountStatus.shouldInvalidate = ( action ) => {
return action.type === TYPES.DISCONNECT_ACCOUNTS_GOOGLE_ADS;
};

/**
* Resolver for getting the GTIN Migration status.
*/
export function* getGtinMigrationStatus() {
try {
const response = yield apiFetch( {

Check warning on line 544 in js/src/data/resolvers.js

View check run for this annotation

Codecov / codecov/patch

js/src/data/resolvers.js#L542-L544

Added lines #L542 - L544 were not covered by tests
path: `${ API_NAMESPACE }/gtin-migration`,
} );

yield receiveGtinMigrationStatus( response );

Check warning on line 548 in js/src/data/resolvers.js

View check run for this annotation

Codecov / codecov/patch

js/src/data/resolvers.js#L548

Added line #L548 was not covered by tests
} catch ( error ) {
handleApiError(

Check warning on line 550 in js/src/data/resolvers.js

View check run for this annotation

Codecov / codecov/patch

js/src/data/resolvers.js#L550

Added line #L550 was not covered by tests
error,
__(
'There was an error getting the GTIN Migration Status.',
'google-listings-and-ads'
)
);
}
}
10 changes: 10 additions & 0 deletions js/src/data/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,13 @@ export const getTour = ( state, tourId ) => {
export const getGoogleAdsAccountStatus = ( state ) => {
return state.ads.accountStatus;
};

/**
* Return the GTIN Migration status.
*
* @param {Object} state The state
* @return {Object} The GTIN Migration status.
*/
export const getGtinMigrationStatus = ( state ) => {
return state.gtinMigrationStatus;
};
1 change: 1 addition & 0 deletions js/src/data/test/reducer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ describe( 'reducer', () => {
step: null,
},
},
gtinMigrationStatus: null,
} );

prepareState = prepareImmutableStateWithRefCheck.bind(
Expand Down
33 changes: 33 additions & 0 deletions js/src/hooks/useGTINMigrationStatus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* External dependencies
*/
import { useCallback } from '@wordpress/element';

/**
* Internal dependencies
*/
import useAppSelectDispatch from '.~/hooks/useAppSelectDispatch';
import useApiFetchCallback from '.~/hooks/useApiFetchCallback';

const selectorName = 'getGtinMigrationStatus';

const useGTINMigrationStatus = () => {
const { data, isResolving, invalidateResolution } =
useAppSelectDispatch( selectorName );

const [ startMigrationApiCall, { loading } ] = useApiFetchCallback( {
path: `/wc/gla/gtin-migration`,
method: 'POST',
} );

const isLoading = loading || isResolving;

const startMigration = useCallback( async () => {
await startMigrationApiCall();
invalidateResolution();

Check warning on line 27 in js/src/hooks/useGTINMigrationStatus.js

View check run for this annotation

Codecov / codecov/patch

js/src/hooks/useGTINMigrationStatus.js#L26-L27

Added lines #L26 - L27 were not covered by tests
}, [ startMigrationApiCall, invalidateResolution ] );

return [ data, isLoading, startMigration ];
};

export default useGTINMigrationStatus;
Loading