woocommerce/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-h...

278 lines
8.2 KiB
TypeScript
Raw Normal View History

/* eslint-disable @woocommerce/dependency-group */
/* eslint-disable @typescript-eslint/ban-ts-comment */
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import {
createInterpolateElement,
useCallback,
useMemo,
useEffect,
useContext,
} from '@wordpress/element';
import { Link } from '@woocommerce/components';
import { Spinner } from '@wordpress/components';
// @ts-expect-error Missing type.
import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
// @ts-expect-error No types for this exist yet.
import { store as coreStore } from '@wordpress/core-data';
import {
privateApis as blockEditorPrivateApis,
__experimentalBlockPatternsList as BlockPatternList,
store as blockEditorStore,
// @ts-expect-error No types for this exist yet.
} from '@wordpress/block-editor';
// @ts-expect-error Missing type in core-data.
import { useIsSiteEditorLoading } from '@wordpress/edit-site/build-module/components/layout/hooks';
/**
* Internal dependencies
*/
import { SidebarNavigationScreen } from './sidebar-navigation-screen';
import { ADMIN_URL } from '~/utils/admin-settings';
import { useEditorBlocks } from '../hooks/use-editor-blocks';
import { useHomeTemplates } from '../hooks/use-home-templates';
import { BlockInstance } from '@wordpress/blocks';
import { useSelectedPattern } from '../hooks/use-selected-pattern';
import { useEditorScroll } from '../hooks/use-editor-scroll';
import { FlowType } from '~/customize-store/types';
import { CustomizeStoreContext } from '~/customize-store/assembler-hub';
import { select, useDispatch, useSelect } from '@wordpress/data';
import { trackEvent } from '~/customize-store/tracking';
import {
PRODUCT_HERO_PATTERN_BUTTON_STYLE,
findButtonBlockInsideCoverBlockProductHeroPatternAndUpdate,
} from '../utils/hero-pattern';
import { isEqual } from 'lodash';
import { COLOR_PALETTES } from './global-styles/color-palette-variations/constants';
const { GlobalStylesContext } = unlock( blockEditorPrivateApis );
export const SidebarNavigationScreenHomepage = () => {
const { scroll } = useEditorScroll( {
editorSelector: '.woocommerce-customize-store__block-editor iframe',
scrollDirection: 'top',
} );
const { isLoading, homeTemplates } = useHomeTemplates();
// eslint-disable-next-line react-hooks/exhaustive-deps
const { selectedPattern, setSelectedPattern } = useSelectedPattern();
const currentTemplate = useSelect(
( sel ) =>
// @ts-expect-error No types for this exist yet.
sel( coreStore ).__experimentalGetTemplateForLink( '/' ),
[]
);
const [ blocks, , onChange ] = useEditorBlocks(
'wp_template',
currentTemplate.id
);
// @ts-expect-error No types for this exist yet.
const { selectBlock } = useDispatch( blockEditorStore );
const onClickPattern = useCallback(
( pattern, selectedBlocks ) => {
if ( pattern === selectedPattern ) {
return;
}
setSelectedPattern( pattern );
selectBlock( pattern.blocks[ 0 ].clientId );
onChange(
[ blocks[ 0 ], ...selectedBlocks, blocks[ blocks.length - 1 ] ],
{ selection: {} }
);
scroll();
},
[
selectedPattern,
setSelectedPattern,
selectBlock,
onChange,
blocks,
scroll,
]
);
const isEditorLoading = useIsSiteEditorLoading();
// @ts-expect-error No types for this exist yet.
const { user } = useContext( GlobalStylesContext );
const isActiveNewNeutralVariation = useMemo(
() =>
isEqual( COLOR_PALETTES[ 0 ].settings.color, user.settings.color ),
[ user ]
);
const homePatterns = useMemo( () => {
return Object.entries( homeTemplates ).map(
( [ templateName, patterns ] ) => {
if ( templateName === 'template1' ) {
return {
name: templateName,
title: templateName,
blocks: patterns.reduce(
( acc: BlockInstance[], pattern ) => {
const parsedPattern = unlock(
select( blockEditorStore )
).__experimentalGetParsedPattern(
pattern.name
);
if ( ! parsedPattern ) {
return acc;
}
if ( ! isActiveNewNeutralVariation ) {
return [ ...acc, ...parsedPattern.blocks ];
}
const updatedBlocks =
findButtonBlockInsideCoverBlockProductHeroPatternAndUpdate(
parsedPattern.blocks,
( buttonBlock: BlockInstance ) => {
buttonBlock.attributes.style =
PRODUCT_HERO_PATTERN_BUTTON_STYLE;
}
);
return [ ...acc, ...updatedBlocks ];
},
[]
),
blockTypes: [ '' ],
categories: [ '' ],
content: '',
source: '',
};
}
return {
name: templateName,
title: templateName,
blocks: patterns.reduce(
( acc: BlockInstance[], pattern ) => {
const parsedPattern = unlock(
select( blockEditorStore )
).__experimentalGetParsedPattern( pattern.name );
if ( ! parsedPattern ) {
return acc;
}
return [ ...acc, ...parsedPattern.blocks ];
},
[]
),
blockTypes: [ '' ],
categories: [ '' ],
content: '',
source: '',
};
}
);
}, [ homeTemplates, isActiveNewNeutralVariation ] );
useEffect( () => {
CYS - E2E tests: add homepage picker E2E tests (#46127) * Update checks for sale price * Update checks for product images * Update checks for linked products * Update default theme for e2e environment to twentytwentythree * Fix basic spec * Fix locator product block editor test * Make cart.spec.js theme agnostic * Updated mini-cart.spec.js * Updated cart-checkout-block-calculate-tax.spec.js * Updated cart-block.spec.js * Fix cart-block.spec.js * Update account-email-receiving.spec.js * CYS - E2E tests: fix flaky assembler-hub test * Use a value for pr_number * Update condition for the Slack alert job * Remove pr_number argument * Add changefile(s) from automation for the following project(s): woocommerce * Update conditions for the publish reports jobs * Rename jobs * Send GITHUB_SHA to report * Check for skipped status * Include Slack notification step in the reporting job * Rename jobs * Test update to trigger api tests * Revert test change for api tests * fix flakiness * Test change to trigger all tests * Test slack alert condition * add waitUntil * Force a test failure * Revert all test changes * improve logic * fix build error * try now * Update product-inventory-block-editor.spec.js * fix unit test * fix flakiness * Update checkout-block.spec.js * Update checkout-block.spec.js * Add utils/order * Remove the check for more items than the coupon max amount as it fails with block themes * Update create-simple-product-block-editor.spec.js * Update cart-checkout-calculate-tax.spec.js * Update checkout-block.spec.js * Update create-simple-product-block-editor.spec.js * Update wordpress-post.spec.js * Update my-account-addresses.spec.js * Update my-account-create-account.spec.js * Update my-account-downloads.spec.js * Update my-account-pay-order.spec.js * Update my-account.spec.js * Update order-email-receiving.spec.js * Update product-grouped.spec.js * Update product-simple.spec.js * Update product-tags-attributes.spec.js * Update product-variable.spec.js * Update shop-search-browse-sort.spec.js * Update checkout.spec.js * Update checkout-login.spec.js * Update checkout-create-account.spec.js * Update wordpress-post.spec.js * Update cart-checkout-calculate-tax.spec.js * Update wordpress-post.spec.js * Update mini-cart.spec.js * Remove logging of order id * Remove the log-out action as it invalidates the customer state and breaks other tests * Use disableWelcomeModal * CYS - E2E tests: add homepage picker E2E tests * update snapshots * add snapshots * use screenshot tests+ * use snapshot * try now * update snapshot * remove wp-container snapshot * remove only * add comment * add snapshot * enable color picker tests * revert to twentytwentythree * restore changes related to the color picker * use default theme --------- Co-authored-by: Adrian Moldovan <adim.moldovan@gmail.com> Co-authored-by: Adrian Moldovan <3854374+adimoldovan@users.noreply.github.com> Co-authored-by: github-actions <github-actions@github.com>
2024-04-08 10:43:41 +00:00
if (
selectedPattern ||
! blocks.length ||
! homePatterns.length ||
isLoading ||
isEditorLoading
) {
return;
}
const currentSelectedPattern = homePatterns.find( ( patterns ) => {
//'blocks' contains all blocks in the template, including the
// header and footer blocks, while the 'patterns.blocks' does
// not. For that reason we are removing the first and last
// blocks from the 'blocks' to be able to compare then
const homeBlocks = blocks.slice( 1, blocks.length - 1 );
if ( patterns.blocks.length !== homeBlocks.length ) {
return false;
}
return homeBlocks.every(
( block, i ) => block.name === patterns.blocks[ i ].name
);
} );
setSelectedPattern( currentSelectedPattern );
// eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want to re-run this effect when currentSelectedPattern changes
CYS - E2E tests: add homepage picker E2E tests (#46127) * Update checks for sale price * Update checks for product images * Update checks for linked products * Update default theme for e2e environment to twentytwentythree * Fix basic spec * Fix locator product block editor test * Make cart.spec.js theme agnostic * Updated mini-cart.spec.js * Updated cart-checkout-block-calculate-tax.spec.js * Updated cart-block.spec.js * Fix cart-block.spec.js * Update account-email-receiving.spec.js * CYS - E2E tests: fix flaky assembler-hub test * Use a value for pr_number * Update condition for the Slack alert job * Remove pr_number argument * Add changefile(s) from automation for the following project(s): woocommerce * Update conditions for the publish reports jobs * Rename jobs * Send GITHUB_SHA to report * Check for skipped status * Include Slack notification step in the reporting job * Rename jobs * Test update to trigger api tests * Revert test change for api tests * fix flakiness * Test change to trigger all tests * Test slack alert condition * add waitUntil * Force a test failure * Revert all test changes * improve logic * fix build error * try now * Update product-inventory-block-editor.spec.js * fix unit test * fix flakiness * Update checkout-block.spec.js * Update checkout-block.spec.js * Add utils/order * Remove the check for more items than the coupon max amount as it fails with block themes * Update create-simple-product-block-editor.spec.js * Update cart-checkout-calculate-tax.spec.js * Update checkout-block.spec.js * Update create-simple-product-block-editor.spec.js * Update wordpress-post.spec.js * Update my-account-addresses.spec.js * Update my-account-create-account.spec.js * Update my-account-downloads.spec.js * Update my-account-pay-order.spec.js * Update my-account.spec.js * Update order-email-receiving.spec.js * Update product-grouped.spec.js * Update product-simple.spec.js * Update product-tags-attributes.spec.js * Update product-variable.spec.js * Update shop-search-browse-sort.spec.js * Update checkout.spec.js * Update checkout-login.spec.js * Update checkout-create-account.spec.js * Update wordpress-post.spec.js * Update cart-checkout-calculate-tax.spec.js * Update wordpress-post.spec.js * Update mini-cart.spec.js * Remove logging of order id * Remove the log-out action as it invalidates the customer state and breaks other tests * Use disableWelcomeModal * CYS - E2E tests: add homepage picker E2E tests * update snapshots * add snapshots * use screenshot tests+ * use snapshot * try now * update snapshot * remove wp-container snapshot * remove only * add comment * add snapshot * enable color picker tests * revert to twentytwentythree * restore changes related to the color picker * use default theme --------- Co-authored-by: Adrian Moldovan <adim.moldovan@gmail.com> Co-authored-by: Adrian Moldovan <3854374+adimoldovan@users.noreply.github.com> Co-authored-by: github-actions <github-actions@github.com>
2024-04-08 10:43:41 +00:00
}, [ blocks, homePatterns, isLoading, isEditorLoading ] );
const { context } = useContext( CustomizeStoreContext );
const aiOnline = context.flowType === FlowType.AIOnline;
const title = aiOnline
? __( 'Change your homepage', 'woocommerce' )
: __( 'Choose your homepage', 'woocommerce' );
const sidebarMessage = aiOnline
? __(
'Based on the most successful stores in your industry and location, our AI tool has recommended this template for your business. Prefer a different layout? Choose from the templates below now, or later via the <EditorLink>Editor</EditorLink>.',
'woocommerce'
)
: __(
'Create an engaging homepage by selecting one of our pre-designed layouts. You can continue customizing this page, including the content, later via the <EditorLink>Editor</EditorLink>.',
'woocommerce'
);
return (
<SidebarNavigationScreen
title={ title }
description={ createInterpolateElement( sidebarMessage, {
EditorLink: (
<Link
onClick={ () => {
trackEvent(
'customize_your_store_assembler_hub_editor_link_click',
{
source: 'homepage',
}
);
window.open(
`${ ADMIN_URL }site-editor.php`,
'_blank'
);
return false;
} }
href=""
/>
),
} ) }
content={
<div className="woocommerce-customize-store__sidebar-homepage-content">
<div className="edit-site-sidebar-navigation-screen-patterns__group-homepage">
{ /* This is necessary to fix this issue: https://github.com/woocommerce/woocommerce/issues/45711
If the user switch the homepage while the editor is loading, header and footer could disappear.
For more details check: https://github.com/woocommerce/woocommerce/pull/45735
*/ }
{ isLoading || isEditorLoading ? (
<span className="components-placeholder__preview">
<Spinner />
</span>
) : (
<BlockPatternList
shownPatterns={ homePatterns }
blockPatterns={ homePatterns }
onClickPattern={ onClickPattern }
label={ 'Homepage' }
orientation="vertical"
category={ 'homepage' }
isDraggable={ false }
showTitlesAsTooltip={ false }
/>
) }
</div>
</div>
}
/>
);
};