Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Add logic of Upgrade Notice after upgrading Products to Product Colle…
Browse files Browse the repository at this point in the history
…ction (#10267)

* WIP of Upgrade Notice state

* Extend the state options with seeing option

* Move the logic to the dedicated folder

* Subscribe only if not reverted

* Refactor the way UpgradeNotice is rendered

* Simplify the logic of keeping the Upgrade Notice state in local storage

* Improve types organisation

* Lift the functions interacting with local storage to the Inspector Controls of Product Colelction

* Simplify logic of showing Upgrade Notice

* Disable auto migration

* Refactoring

* Use useLocalStorageState hook

* Fix incorrect merge

* Final improvements

* Allow to display Upgrade Notice after revert and manual upgrade

* Fix incorrect merge

* Improve the unsubscribe process

* Trigger auto-update from Product Collection only

* Remove weird console.log

* Abstract manual update from Product Query

* Fix the taxQuery migration from Product Collection to Products

* Product Collection - logic to hide upgrade notice (#10494)

* Add timestamp to each upgrade notice status change

* Revert back only Product Collections converted from Products block

* Make the time threshold configurable

* Add logic that hides the Upgrade Notice after some amount of displays

* Fix the taxQuery migration from Product Collection to Products

* Change the way to count Product Collection entries

* Fix the problem of multiple display counter increments with Product Collection

* Update Upgrade Notice visibility conditions

* Add contiions to unmark Product Collection as converted from Products

* Change variable name

* Change variable t to time name for better readibility. Improve types

* Replace useState with useRef

* Remove unecessary props passed to UpgradeNotice
  • Loading branch information
kmanijak authored Aug 18, 2023
1 parent d4b3ee9 commit de5c3e0
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 129 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Internal dependencies
*/
import type { UpgradeNoticeStatus, UpgradeNoticeStatuses } from './types';

export const AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION = false;
export const MANUAL_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION = false;
export const HOURS_TO_DISPLAY_UPGRADE_NOTICE = 72;
export const UPGRADE_NOTICE_DISPLAY_COUNT_THRESHOLD = 4;
export const MIGRATION_STATUS_LS_KEY =
'wc-blocks_upgraded-products-to-product-collection';
// Initial status used in the localStorage
export const INITIAL_STATUS_LS_VALUE: UpgradeNoticeStatuses = 'notseen';

export const getInitialStatusLSValue: () => UpgradeNoticeStatus = () => ( {
status: INITIAL_STATUS_LS_VALUE,
time: Date.now(),
displayCount: 0,
} );
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export * from './migration-from-products-to-product-collection';
export * from './migration-from-product-collection-to-products';
export * from './migration-utils';
export * from './constants';
export * from './types';
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@ import { select, dispatch } from '@wordpress/data';
/**
* Internal dependencies
*/
import { disableAutoUpdate } from './migration-from-products-to-product-collection';
import {
getProductCollectionBlockClientIds,
checkIfBlockCanBeInserted,
postTemplateHasSupportForGridView,
type TransformBlock,
type IsBlockType,
type ProductGridLayout,
type ProductGridLayoutTypes,
type PostTemplateLayout,
type PostTemplateLayoutTypes,
setUpgradeStatus,
} from './migration-utils';
import type {
TransformBlock,
IsBlockType,
ProductGridLayout,
ProductGridLayoutTypes,
PostTemplateLayout,
PostTemplateLayoutTypes,
} from './types';

const VARIATION_NAME = 'woocommerce/product-query';

Expand Down Expand Up @@ -45,6 +49,10 @@ const mapAttributes = ( attributes ) => {
mappedQuery.__woocommerceOnSale = woocommerceOnSale;
}

if ( taxQuery ) {
mappedQuery.taxQuery = taxQuery;
}

return {
...restAttributes,
namespace: VARIATION_NAME,
Expand Down Expand Up @@ -207,3 +215,12 @@ export const replaceProductCollectionWithProducts = () => {

productCollectionBlockClientIds.map( replaceProductCollectionBlock );
};

export const revertMigration = () => {
disableAutoUpdate();
setUpgradeStatus( {
status: 'reverted',
time: Date.now(),
} );
replaceProductCollectionWithProducts();
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,31 @@
* External dependencies
*/
import { createBlock, BlockInstance } from '@wordpress/blocks';
import { select, dispatch } from '@wordpress/data';
import { select, dispatch, subscribe } from '@wordpress/data';
import { isWpVersion } from '@woocommerce/settings';

/**
* Internal dependencies
*/
import {
AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION,
getInitialStatusLSValue,
} from './constants';
import {
getProductsBlockClientIds,
checkIfBlockCanBeInserted,
postTemplateHasSupportForGridView,
type TransformBlock,
type IsBlockType,
type ProductGridLayout,
type ProductGridLayoutTypes,
type PostTemplateLayout,
type PostTemplateLayoutTypes,
getUpgradeStatus,
setUpgradeStatus,
} from './migration-utils';
import type {
TransformBlock,
IsBlockType,
ProductGridLayout,
ProductGridLayoutTypes,
PostTemplateLayout,
PostTemplateLayoutTypes,
} from './types';

const mapAttributes = ( attributes: Record< string, unknown > ) => {
const { query, namespace, ...restAttributes } = attributes;
Expand All @@ -41,7 +50,7 @@ const mapAttributes = ( attributes: Record< string, unknown > ) => {
isProductCollectionBlock: true,
...restQuery,
},
displayUpgradeNotice: true,
convertedFromProducts: true,
};
};

Expand Down Expand Up @@ -194,9 +203,7 @@ const replaceProductsBlocks = ( productsBlockClientIds: string[] ) => {
return !! results.length && results.every( ( result ) => !! result );
};

export const replaceProductsWithProductCollection = (
unsubscribe?: () => void
) => {
export const replaceProductsWithProductCollection = () => {
const queryBlocksCount =
select( 'core/block-editor' ).getGlobalBlockCount( 'core/query' );
if ( queryBlocksCount === 0 ) {
Expand All @@ -211,10 +218,32 @@ export const replaceProductsWithProductCollection = (
return;
}

const replaced = replaceProductsBlocks( productsBlockClientIds );
replaceProductsBlocks( productsBlockClientIds );
};

export const manualUpdate = () => {
setUpgradeStatus( getInitialStatusLSValue() );
replaceProductsWithProductCollection();
};

if ( unsubscribe && replaced ) {
// @todo: unsubscribe on user reverting migration
let unsubscribe: ( () => void ) | undefined;
export const disableAutoUpdate = () => {
if ( unsubscribe ) {
unsubscribe();
}
};
export const enableAutoUpdate = () => {
if ( isWpVersion( '6.1', '>=' ) ) {
const { status } = getUpgradeStatus();

if (
AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION &&
status !== 'reverted' &&
! unsubscribe
) {
unsubscribe = subscribe( () => {
replaceProductsWithProductCollection();
}, 'core/block-editor' );
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,25 @@
import { getSettingWithCoercion } from '@woocommerce/settings';
import { type BlockInstance } from '@wordpress/blocks';
import { select } from '@wordpress/data';
import { isBoolean } from '@woocommerce/types';
import { isBoolean, isNumber } from '@woocommerce/types';

type GetBlocksClientIds = ( blocks: BlockInstance[] ) => string[];
export type IsBlockType = ( block: BlockInstance ) => boolean;
export type TransformBlock = (
block: BlockInstance,
innerBlock: BlockInstance[]
) => BlockInstance;
export type ProductGridLayoutTypes = 'flex' | 'list';
export type PostTemplateLayoutTypes = 'grid' | 'default';

export type ProductGridLayout = {
type: ProductGridLayoutTypes;
columns: number;
};

export type PostTemplateLayout = {
type: PostTemplateLayoutTypes;
columnCount: number;
};
/**
* Internal dependencies
*/
import { MIGRATION_STATUS_LS_KEY, getInitialStatusLSValue } from './constants';
import type {
IsBlockType,
GetBlocksClientIds,
UpgradeNoticeStatus,
} from './types';

const isProductsBlock: IsBlockType = ( block ) =>
block.name === 'core/query' &&
block.attributes.namespace === 'woocommerce/product-query';

const isProductCollectionBlock: IsBlockType = ( block ) =>
block.name === 'woocommerce/product-collection';
const isConvertedProductCollectionBlock: IsBlockType = ( block ) =>
block.name === 'woocommerce/product-collection' &&
block.attributes.convertedFromProducts;

const getBlockClientIdsByPredicate = (
blocks: BlockInstance[],
Expand All @@ -53,7 +45,7 @@ const getProductsBlockClientIds: GetBlocksClientIds = ( blocks ) =>
getBlockClientIdsByPredicate( blocks, isProductsBlock );

const getProductCollectionBlockClientIds: GetBlocksClientIds = ( blocks ) =>
getBlockClientIdsByPredicate( blocks, isProductCollectionBlock );
getBlockClientIdsByPredicate( blocks, isConvertedProductCollectionBlock );

const checkIfBlockCanBeInserted = (
clientId: string,
Expand All @@ -78,9 +70,35 @@ const postTemplateHasSupportForGridView = getSettingWithCoercion(
isBoolean
);

const getUpgradeStatus = (): UpgradeNoticeStatus => {
const status = window.localStorage.getItem( MIGRATION_STATUS_LS_KEY );
return status ? JSON.parse( status ) : getInitialStatusLSValue();
};

const setUpgradeStatus = ( newStatus: UpgradeNoticeStatus ) => {
window.localStorage.setItem(
MIGRATION_STATUS_LS_KEY,
JSON.stringify( newStatus )
);
};

const incrementUpgradeStatusDisplayCount = () => {
const status = getUpgradeStatus();
const displayCount = isNumber( status.displayCount )
? status.displayCount + 1
: 0;
setUpgradeStatus( {
...status,
displayCount,
} );
};

export {
getProductsBlockClientIds,
getProductCollectionBlockClientIds,
checkIfBlockCanBeInserted,
postTemplateHasSupportForGridView,
getUpgradeStatus,
setUpgradeStatus,
incrementUpgradeStatusDisplayCount,
};
29 changes: 29 additions & 0 deletions assets/js/blocks/migration-products-to-product-collection/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* External dependencies
*/
import { type BlockInstance } from '@wordpress/blocks';

export type GetBlocksClientIds = ( blocks: BlockInstance[] ) => string[];
export type IsBlockType = ( block: BlockInstance ) => boolean;
export type TransformBlock = (
block: BlockInstance,
innerBlock: BlockInstance[]
) => BlockInstance;
export type ProductGridLayoutTypes = 'flex' | 'list';
export type PostTemplateLayoutTypes = 'grid' | 'default';

export type ProductGridLayout = {
type: ProductGridLayoutTypes;
columns: number;
};

export type PostTemplateLayout = {
type: PostTemplateLayoutTypes;
columnCount: number;
};
export type UpgradeNoticeStatuses = 'notseen' | 'seen' | 'reverted';
export type UpgradeNoticeStatus = {
status: UpgradeNoticeStatuses;
time: number;
displayCount?: number;
};
2 changes: 1 addition & 1 deletion assets/js/blocks/product-collection/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"displayLayout": {
"type": "object"
},
"displayUpgradeNotice": {
"convertedFromProducts": {
"type": "boolean",
"default": false
}
Expand Down
Loading

0 comments on commit de5c3e0

Please sign in to comment.