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

Commit de5c3e0

Browse files
authored
Add logic of Upgrade Notice after upgrading Products to Product Collection (#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
1 parent d4b3ee9 commit de5c3e0

File tree

12 files changed

+316
-129
lines changed

12 files changed

+316
-129
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import type { UpgradeNoticeStatus, UpgradeNoticeStatuses } from './types';
5+
6+
export const AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION = false;
7+
export const MANUAL_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION = false;
8+
export const HOURS_TO_DISPLAY_UPGRADE_NOTICE = 72;
9+
export const UPGRADE_NOTICE_DISPLAY_COUNT_THRESHOLD = 4;
10+
export const MIGRATION_STATUS_LS_KEY =
11+
'wc-blocks_upgraded-products-to-product-collection';
12+
// Initial status used in the localStorage
13+
export const INITIAL_STATUS_LS_VALUE: UpgradeNoticeStatuses = 'notseen';
14+
15+
export const getInitialStatusLSValue: () => UpgradeNoticeStatus = () => ( {
16+
status: INITIAL_STATUS_LS_VALUE,
17+
time: Date.now(),
18+
displayCount: 0,
19+
} );
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
export * from './migration-from-products-to-product-collection';
22
export * from './migration-from-product-collection-to-products';
3+
export * from './migration-utils';
4+
export * from './constants';
5+
export * from './types';

assets/js/blocks/shared/scripts/migration-from-product-collection-to-products.tsx renamed to assets/js/blocks/migration-products-to-product-collection/migration-from-product-collection-to-products.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@ import { select, dispatch } from '@wordpress/data';
77
/**
88
* Internal dependencies
99
*/
10+
import { disableAutoUpdate } from './migration-from-products-to-product-collection';
1011
import {
1112
getProductCollectionBlockClientIds,
1213
checkIfBlockCanBeInserted,
1314
postTemplateHasSupportForGridView,
14-
type TransformBlock,
15-
type IsBlockType,
16-
type ProductGridLayout,
17-
type ProductGridLayoutTypes,
18-
type PostTemplateLayout,
19-
type PostTemplateLayoutTypes,
15+
setUpgradeStatus,
2016
} from './migration-utils';
17+
import type {
18+
TransformBlock,
19+
IsBlockType,
20+
ProductGridLayout,
21+
ProductGridLayoutTypes,
22+
PostTemplateLayout,
23+
PostTemplateLayoutTypes,
24+
} from './types';
2125

2226
const VARIATION_NAME = 'woocommerce/product-query';
2327

@@ -45,6 +49,10 @@ const mapAttributes = ( attributes ) => {
4549
mappedQuery.__woocommerceOnSale = woocommerceOnSale;
4650
}
4751

52+
if ( taxQuery ) {
53+
mappedQuery.taxQuery = taxQuery;
54+
}
55+
4856
return {
4957
...restAttributes,
5058
namespace: VARIATION_NAME,
@@ -207,3 +215,12 @@ export const replaceProductCollectionWithProducts = () => {
207215

208216
productCollectionBlockClientIds.map( replaceProductCollectionBlock );
209217
};
218+
219+
export const revertMigration = () => {
220+
disableAutoUpdate();
221+
setUpgradeStatus( {
222+
status: 'reverted',
223+
time: Date.now(),
224+
} );
225+
replaceProductCollectionWithProducts();
226+
};

assets/js/blocks/shared/scripts/migration-from-products-to-product-collection.tsx renamed to assets/js/blocks/migration-products-to-product-collection/migration-from-products-to-product-collection.ts

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,31 @@
22
* External dependencies
33
*/
44
import { createBlock, BlockInstance } from '@wordpress/blocks';
5-
import { select, dispatch } from '@wordpress/data';
5+
import { select, dispatch, subscribe } from '@wordpress/data';
6+
import { isWpVersion } from '@woocommerce/settings';
67

78
/**
89
* Internal dependencies
910
*/
11+
import {
12+
AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION,
13+
getInitialStatusLSValue,
14+
} from './constants';
1015
import {
1116
getProductsBlockClientIds,
1217
checkIfBlockCanBeInserted,
1318
postTemplateHasSupportForGridView,
14-
type TransformBlock,
15-
type IsBlockType,
16-
type ProductGridLayout,
17-
type ProductGridLayoutTypes,
18-
type PostTemplateLayout,
19-
type PostTemplateLayoutTypes,
19+
getUpgradeStatus,
20+
setUpgradeStatus,
2021
} from './migration-utils';
22+
import type {
23+
TransformBlock,
24+
IsBlockType,
25+
ProductGridLayout,
26+
ProductGridLayoutTypes,
27+
PostTemplateLayout,
28+
PostTemplateLayoutTypes,
29+
} from './types';
2130

2231
const mapAttributes = ( attributes: Record< string, unknown > ) => {
2332
const { query, namespace, ...restAttributes } = attributes;
@@ -41,7 +50,7 @@ const mapAttributes = ( attributes: Record< string, unknown > ) => {
4150
isProductCollectionBlock: true,
4251
...restQuery,
4352
},
44-
displayUpgradeNotice: true,
53+
convertedFromProducts: true,
4554
};
4655
};
4756

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

197-
export const replaceProductsWithProductCollection = (
198-
unsubscribe?: () => void
199-
) => {
206+
export const replaceProductsWithProductCollection = () => {
200207
const queryBlocksCount =
201208
select( 'core/block-editor' ).getGlobalBlockCount( 'core/query' );
202209
if ( queryBlocksCount === 0 ) {
@@ -211,10 +218,32 @@ export const replaceProductsWithProductCollection = (
211218
return;
212219
}
213220

214-
const replaced = replaceProductsBlocks( productsBlockClientIds );
221+
replaceProductsBlocks( productsBlockClientIds );
222+
};
223+
224+
export const manualUpdate = () => {
225+
setUpgradeStatus( getInitialStatusLSValue() );
226+
replaceProductsWithProductCollection();
227+
};
215228

216-
if ( unsubscribe && replaced ) {
217-
// @todo: unsubscribe on user reverting migration
229+
let unsubscribe: ( () => void ) | undefined;
230+
export const disableAutoUpdate = () => {
231+
if ( unsubscribe ) {
218232
unsubscribe();
219233
}
220234
};
235+
export const enableAutoUpdate = () => {
236+
if ( isWpVersion( '6.1', '>=' ) ) {
237+
const { status } = getUpgradeStatus();
238+
239+
if (
240+
AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION &&
241+
status !== 'reverted' &&
242+
! unsubscribe
243+
) {
244+
unsubscribe = subscribe( () => {
245+
replaceProductsWithProductCollection();
246+
}, 'core/block-editor' );
247+
}
248+
}
249+
};

assets/js/blocks/shared/scripts/migration-utils.tsx renamed to assets/js/blocks/migration-products-to-product-collection/migration-utils.ts

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,25 @@
44
import { getSettingWithCoercion } from '@woocommerce/settings';
55
import { type BlockInstance } from '@wordpress/blocks';
66
import { select } from '@wordpress/data';
7-
import { isBoolean } from '@woocommerce/types';
7+
import { isBoolean, isNumber } from '@woocommerce/types';
88

9-
type GetBlocksClientIds = ( blocks: BlockInstance[] ) => string[];
10-
export type IsBlockType = ( block: BlockInstance ) => boolean;
11-
export type TransformBlock = (
12-
block: BlockInstance,
13-
innerBlock: BlockInstance[]
14-
) => BlockInstance;
15-
export type ProductGridLayoutTypes = 'flex' | 'list';
16-
export type PostTemplateLayoutTypes = 'grid' | 'default';
17-
18-
export type ProductGridLayout = {
19-
type: ProductGridLayoutTypes;
20-
columns: number;
21-
};
22-
23-
export type PostTemplateLayout = {
24-
type: PostTemplateLayoutTypes;
25-
columnCount: number;
26-
};
9+
/**
10+
* Internal dependencies
11+
*/
12+
import { MIGRATION_STATUS_LS_KEY, getInitialStatusLSValue } from './constants';
13+
import type {
14+
IsBlockType,
15+
GetBlocksClientIds,
16+
UpgradeNoticeStatus,
17+
} from './types';
2718

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

32-
const isProductCollectionBlock: IsBlockType = ( block ) =>
33-
block.name === 'woocommerce/product-collection';
23+
const isConvertedProductCollectionBlock: IsBlockType = ( block ) =>
24+
block.name === 'woocommerce/product-collection' &&
25+
block.attributes.convertedFromProducts;
3426

3527
const getBlockClientIdsByPredicate = (
3628
blocks: BlockInstance[],
@@ -53,7 +45,7 @@ const getProductsBlockClientIds: GetBlocksClientIds = ( blocks ) =>
5345
getBlockClientIdsByPredicate( blocks, isProductsBlock );
5446

5547
const getProductCollectionBlockClientIds: GetBlocksClientIds = ( blocks ) =>
56-
getBlockClientIdsByPredicate( blocks, isProductCollectionBlock );
48+
getBlockClientIdsByPredicate( blocks, isConvertedProductCollectionBlock );
5749

5850
const checkIfBlockCanBeInserted = (
5951
clientId: string,
@@ -78,9 +70,35 @@ const postTemplateHasSupportForGridView = getSettingWithCoercion(
7870
isBoolean
7971
);
8072

73+
const getUpgradeStatus = (): UpgradeNoticeStatus => {
74+
const status = window.localStorage.getItem( MIGRATION_STATUS_LS_KEY );
75+
return status ? JSON.parse( status ) : getInitialStatusLSValue();
76+
};
77+
78+
const setUpgradeStatus = ( newStatus: UpgradeNoticeStatus ) => {
79+
window.localStorage.setItem(
80+
MIGRATION_STATUS_LS_KEY,
81+
JSON.stringify( newStatus )
82+
);
83+
};
84+
85+
const incrementUpgradeStatusDisplayCount = () => {
86+
const status = getUpgradeStatus();
87+
const displayCount = isNumber( status.displayCount )
88+
? status.displayCount + 1
89+
: 0;
90+
setUpgradeStatus( {
91+
...status,
92+
displayCount,
93+
} );
94+
};
95+
8196
export {
8297
getProductsBlockClientIds,
8398
getProductCollectionBlockClientIds,
8499
checkIfBlockCanBeInserted,
85100
postTemplateHasSupportForGridView,
101+
getUpgradeStatus,
102+
setUpgradeStatus,
103+
incrementUpgradeStatusDisplayCount,
86104
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { type BlockInstance } from '@wordpress/blocks';
5+
6+
export type GetBlocksClientIds = ( blocks: BlockInstance[] ) => string[];
7+
export type IsBlockType = ( block: BlockInstance ) => boolean;
8+
export type TransformBlock = (
9+
block: BlockInstance,
10+
innerBlock: BlockInstance[]
11+
) => BlockInstance;
12+
export type ProductGridLayoutTypes = 'flex' | 'list';
13+
export type PostTemplateLayoutTypes = 'grid' | 'default';
14+
15+
export type ProductGridLayout = {
16+
type: ProductGridLayoutTypes;
17+
columns: number;
18+
};
19+
20+
export type PostTemplateLayout = {
21+
type: PostTemplateLayoutTypes;
22+
columnCount: number;
23+
};
24+
export type UpgradeNoticeStatuses = 'notseen' | 'seen' | 'reverted';
25+
export type UpgradeNoticeStatus = {
26+
status: UpgradeNoticeStatuses;
27+
time: number;
28+
displayCount?: number;
29+
};

assets/js/blocks/product-collection/block.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"displayLayout": {
2222
"type": "object"
2323
},
24-
"displayUpgradeNotice": {
24+
"convertedFromProducts": {
2525
"type": "boolean",
2626
"default": false
2727
}

0 commit comments

Comments
 (0)