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

CYS: Override header and footer template parts #45196

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -6,8 +6,8 @@
// @ts-ignore No types for this exist yet.
import { store as blockEditorStore } from '@wordpress/block-editor';
// @ts-ignore No types for this exist yet.
import { useEntityRecords } from '@wordpress/core-data';
import { select } from '@wordpress/data';
import { useEntityRecords, store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
// @ts-ignore No types for this exist yet.
import { privateApis as routerPrivateApis } from '@wordpress/router';
// @ts-ignore No types for this exist yet.
Expand Down Expand Up @@ -67,7 +67,19 @@ const MAX_PAGE_COUNT = 100;
export const BlockEditor = ( {} ) => {
const history = useHistory();
const settings = useSiteEditorSettings();
const [ blocks, , onChange ] = useEditorBlocks();

const currentTemplate = useSelect(
( select ) =>
// @ts-expect-error No types for this exist yet.
select( coreStore ).__experimentalGetTemplateForLink( '/' ),
[]
);

const [ blocks, , onChange ] = useEditorBlocks(
'wp_template',
currentTemplate.id
);

const urlParams = useQuery();
const { currentState } = useContext( CustomizeStoreContext );

Expand Down Expand Up @@ -120,8 +132,8 @@ export const BlockEditor = ( {} ) => {
[ history, urlParams, pages ]
);

const { highlightedBlockIndex } = useContext( HighlightedBlockContext );
const isHighlighting = highlightedBlockIndex !== -1;
const { highlightedBlockClientId } = useContext( HighlightedBlockContext );
const isHighlighting = highlightedBlockClientId !== null;
const additionalStyles = isHighlighting
? `
.wp-block.preview-opacity {
Expand All @@ -130,23 +142,37 @@ export const BlockEditor = ( {} ) => {
`
: '';

const opacityClass = 'preview-opacity';

const renderedBlocks = useMemo(
() =>
blocks.map( ( block, i ) => {
if ( ! isHighlighting || i === highlightedBlockIndex ) {
return block;
blocks.map( ( block ) => {
if (
! isHighlighting ||
block.clientId === highlightedBlockClientId
) {
return {
...block,
attributes: {
...block.attributes,
className: block.attributes.className?.replace(
opacityClass,
''
),
},
};
}

return {
...block,
attributes: {
...block.attributes,
className:
block.attributes.className + ' preview-opacity',
block.attributes.className + ` ${ opacityClass }`,
},
};
} ),
[ blocks, highlightedBlockIndex, isHighlighting ]
[ blocks, highlightedBlockClientId, isHighlighting ]
);

return (
Expand Down
Expand Up @@ -4,13 +4,17 @@
import React, { createContext, useState } from '@wordpress/element';
import type { ReactNode } from 'react';

export const HighlightedBlockContext = createContext( {
highlightedBlockIndex: -1,
export const HighlightedBlockContext = createContext< {
highlightedBlockClientId: string | null;
setHighlightedBlockClientId: ( clientId: string | null ) => void;
resetHighlightedBlockClientId: () => void;
} >( {
highlightedBlockClientId: null,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setHighlightedBlockIndex: ( index: number ) => {
setHighlightedBlockClientId: ( clientId: string | null ) => {
// No op by default.
},
resetHighlightedBlockIndex: () => {
resetHighlightedBlockClientId: () => {
// No op by default.
},
} );
Expand All @@ -23,18 +27,20 @@ export const HighlightedBlockContextProvider = ( {
children: ReactNode;
} ) => {
// Create some state
const [ highlightedBlockIndex, setHighlightedBlockIndex ] = useState( -1 );
const [ highlightedBlockClientId, setHighlightedBlockClientId ] = useState<
string | null
>( null );

const resetHighlightedBlockIndex = () => {
setHighlightedBlockIndex( -1 );
const resetHighlightedBlockClientId = () => {
setHighlightedBlockClientId( null );
};

return (
<HighlightedBlockContext.Provider
value={ {
highlightedBlockIndex,
setHighlightedBlockIndex,
resetHighlightedBlockIndex,
highlightedBlockClientId,
setHighlightedBlockClientId,
resetHighlightedBlockClientId,
} }
>
{ children }
Expand Down
Expand Up @@ -13,19 +13,17 @@ import { usePatterns } from '../use-patterns';
jest.mock( '../use-patterns' );
jest.mock( '~/customize-store/data/homepageTemplates', () => ( {
HOMEPAGE_TEMPLATES: {
template1: { blocks: [ 'header', 'content1', 'content2', 'footer' ] },
template2: { blocks: [ 'header', 'content3', 'footer' ] },
template1: { blocks: [ 'content1', 'content2' ] },
template2: { blocks: [ 'content3' ] },
},
} ) );

const mockUsePatterns = usePatterns;

const mockPatternsByName = {
header: { name: 'header', content: '<div>Header</div>' },
content1: { name: 'content1', content: '<div>Content1</div>' },
content2: { name: 'content2', content: '<div>Content2</div>' },
content3: { name: 'content3', content: '<div>Content3</div>' },
footer: { name: 'footer', content: '<div>Footer</div>' },
};

describe( 'useHomeTemplates', () => {
Expand Down
Expand Up @@ -5,11 +5,6 @@
*/
// @ts-ignore No types for this exist yet.
import { useEntityBlockEditor } from '@wordpress/core-data';
// @ts-ignore No types for this exist yet.
import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
// @ts-ignore No types for this exist yet.
import { store as editSiteStore } from '@wordpress/edit-site/build-module/store';
import { useSelect } from '@wordpress/data';
import { BlockInstance } from '@wordpress/blocks';

export type ChangeHandler = (
Expand All @@ -19,25 +14,18 @@ export type ChangeHandler = (

// Note, must be used within BlockEditorProvider. This allows shared access of blocks currently
// being edited in the BlockEditor.
export const useEditorBlocks = (): [
BlockInstance[],
ChangeHandler,
ChangeHandler
] => {
const { templateType } = useSelect( ( select ) => {
const { getEditedPostType } = unlock( select( editSiteStore ) );

return {
templateType: getEditedPostType(),
};
}, [] );

export const useEditorBlocks = (
templateType: 'wp_template' | 'wp_template_part',
templateId: string
): [ BlockInstance[], ChangeHandler, ChangeHandler ] => {
// @ts-ignore Types are not up to date.
const [ blocks, onInput, onChange ]: [
BlockInstance[] | undefined,
ChangeHandler,
ChangeHandler
] = useEntityBlockEditor( 'postType', templateType );
] = useEntityBlockEditor( 'postType', templateType, {
id: templateId,
} );

return [ blocks ?? [], onInput, onChange ];
};
Expand Up @@ -61,7 +61,7 @@ export const useHomeTemplates = () => {
) => {
if ( templateName in recommendedTemplates ) {
acc[ templateName ] = getTemplatePatterns(
template.blocks.slice( 1, -1 ),
template.blocks,
patternsByName
);
}
Expand Down
Expand Up @@ -52,7 +52,7 @@ export const SaveHub = () => {
const { sendEvent } = useContext( CustomizeStoreContext );
const [ isResolving, setIsResolving ] = useState< boolean >( false );
const navigator = useNavigator();
const { resetHighlightedBlockIndex } = useContext(
const { resetHighlightedBlockClientId } = useContext(
HighlightedBlockContext
);
const isEditorLoading = useIsSiteEditorLoading();
Expand Down Expand Up @@ -164,7 +164,7 @@ export const SaveHub = () => {

try {
await save();
resetHighlightedBlockIndex();
resetHighlightedBlockClientId();
navigator.goToParent();
} catch ( error ) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand Down
Expand Up @@ -14,6 +14,8 @@ import {
import { Link } from '@woocommerce/components';
import { recordEvent } from '@woocommerce/tracks';
import { Spinner } from '@wordpress/components';
// @ts-expect-error No types for this exist yet.
import { store as coreStore } from '@wordpress/core-data';

/**
* Internal dependencies
Expand All @@ -29,6 +31,8 @@ import { findPatternByBlock } from './utils';
import BlockPatternList from '../block-pattern-list';
import { CustomizeStoreContext } from '~/customize-store/assembler-hub';
import { FlowType } from '~/customize-store/types';
import { footerTemplateId } from '~/customize-store/data/homepageTemplates';
import { useSelect } from '@wordpress/data';

const SUPPORTED_FOOTER_PATTERNS = [
'woocommerce-blocks/footer-simple-menu',
Expand All @@ -43,18 +47,41 @@ export const SidebarNavigationScreenFooter = () => {
} );

const { isLoading, patterns } = usePatternsByCategory( 'woo-commerce' );
const [ blocks, , onChange ] = useEditorBlocks();
const { setHighlightedBlockIndex, resetHighlightedBlockIndex } = useContext(
HighlightedBlockContext

const currentTemplate = useSelect(
( select ) =>
// @ts-expect-error No types for this exist yet.
select( coreStore ).__experimentalGetTemplateForLink( '/' ),
[]
);

const [ mainTemplateBlocks ] = useEditorBlocks(
'wp_template',
currentTemplate.id
);

const [ blocks, , onChange ] = useEditorBlocks(
'wp_template_part',
footerTemplateId
);

const footerTemplatePartBlockClientId = mainTemplateBlocks.find(
( block ) => block.attributes.slug === 'footer'
);

const { setHighlightedBlockClientId, resetHighlightedBlockClientId } =
useContext( HighlightedBlockContext );
// eslint-disable-next-line react-hooks/exhaustive-deps
const { selectedPattern, setSelectedPattern } = useSelectedPattern();

useEffect( () => {
if ( blocks && blocks.length ) {
setHighlightedBlockIndex( blocks.length - 1 );
}
}, [ setHighlightedBlockIndex, blocks ] );
setHighlightedBlockClientId(
footerTemplatePartBlockClientId?.clientId ?? null
);
}, [
footerTemplatePartBlockClientId?.clientId,
setHighlightedBlockClientId,
] );

const footerPatterns = useMemo(
() =>
Expand Down Expand Up @@ -115,7 +142,7 @@ export const SidebarNavigationScreenFooter = () => {
return (
<SidebarNavigationScreen
title={ title }
onNavigateBackClick={ resetHighlightedBlockIndex }
onNavigateBackClick={ resetHighlightedBlockClientId }
description={ createInterpolateElement( description, {
EditorLink: (
<Link
Expand Down
Expand Up @@ -14,6 +14,9 @@ import {
import { Link } from '@woocommerce/components';
import { recordEvent } from '@woocommerce/tracks';
import { Spinner } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
// @ts-expect-error No types for this exist yet.
import { store as coreStore } from '@wordpress/core-data';

/**
* Internal dependencies
Expand All @@ -29,6 +32,7 @@ import { findPatternByBlock } from './utils';
import BlockPatternList from '../block-pattern-list';
import { CustomizeStoreContext } from '~/customize-store/assembler-hub';
import { FlowType } from '~/customize-store/types';
import { headerTemplateId } from '~/customize-store/data/homepageTemplates';

const SUPPORTED_HEADER_PATTERNS = [
'woocommerce-blocks/header-essential',
Expand All @@ -44,17 +48,38 @@ export const SidebarNavigationScreenHeader = () => {
} );

const { isLoading, patterns } = usePatternsByCategory( 'woo-commerce' );
const [ blocks, , onChange ] = useEditorBlocks();
const { setHighlightedBlockIndex, resetHighlightedBlockIndex } = useContext(
HighlightedBlockContext

const currentTemplate = useSelect(
( select ) =>
// @ts-expect-error No types for this exist yet.
select( coreStore ).__experimentalGetTemplateForLink( '/' ),
[]
);

const [ mainTemplateBlocks ] = useEditorBlocks(
'wp_template',
currentTemplate.id
);

const [ blocks, , onChange ] = useEditorBlocks(
'wp_template_part',
headerTemplateId
);

const headerTemplatePartBlock = mainTemplateBlocks.find(
( block ) => block.attributes.slug === 'header'
);

const { setHighlightedBlockClientId, resetHighlightedBlockClientId } =
useContext( HighlightedBlockContext );
// eslint-disable-next-line react-hooks/exhaustive-deps
const { selectedPattern, setSelectedPattern } = useSelectedPattern();

useEffect( () => {
setHighlightedBlockIndex( 0 );
}, [ setHighlightedBlockIndex ] );

setHighlightedBlockClientId(
headerTemplatePartBlock?.clientId ?? null
);
}, [ headerTemplatePartBlock?.clientId, setHighlightedBlockClientId ] );
const headerPatterns = useMemo(
() =>
patterns
Expand Down Expand Up @@ -103,7 +128,7 @@ export const SidebarNavigationScreenHeader = () => {
return (
<SidebarNavigationScreen
title={ title }
onNavigateBackClick={ resetHighlightedBlockIndex }
onNavigateBackClick={ resetHighlightedBlockClientId }
description={ createInterpolateElement(
__(
"Select a new header from the options below. Your header includes your site's navigation and will be added to every page. You can continue customizing this via the <EditorLink>Editor</EditorLink>.",
Expand Down