Skip to content

Commit

Permalink
Patterns: Avoid mapping template parts objects to patterns (WordPress…
Browse files Browse the repository at this point in the history
…#62927)

Co-authored-by: youknowriad <[email protected]>
Co-authored-by: ellatrix <[email protected]>
Co-authored-by: ntsekouras <[email protected]>
Co-authored-by: oandregal <[email protected]>
  • Loading branch information
5 people authored Jun 28, 2024
1 parent 15da2aa commit 9a331f1
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 72 deletions.
30 changes: 21 additions & 9 deletions packages/edit-site/src/components/page-patterns/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { usePrevious } from '@wordpress/compose';
import { useEntityRecords } from '@wordpress/core-data';
import { privateApis as editorPrivateApis } from '@wordpress/editor';
import { privateApis as routerPrivateApis } from '@wordpress/router';
import { parse } from '@wordpress/blocks';
import { decodeEntities } from '@wordpress/html-entities';

/**
* Internal dependencies
Expand All @@ -53,6 +55,7 @@ import PatternsHeader from './header';
import { useLink } from '../routes/link';
import { useAddedBy } from '../page-templates/hooks';
import { useEditPostAction } from '../dataviews-actions';
import { defaultGetTitle } from './search-items';

const { ExperimentalBlockEditorProvider, useGlobalStyle } = unlock(
blockEditorPrivateApis
Expand Down Expand Up @@ -116,14 +119,21 @@ function Preview( { item, viewType } ) {
const descriptionId = useId();
const isUserPattern = item.type === PATTERN_TYPES.user;
const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE;
const isEmpty = ! item.blocks?.length;

const [ backgroundColor ] = useGlobalStyle( 'color.background' );
const { onClick } = useLink( {
postType: item.type,
postId: isUserPattern ? item.id : item.name,
postId: isUserPattern || isTemplatePart ? item.id : item.name,
canvas: 'edit',
} );
const blocks = useMemo( () => {
return (
item.blocks ??
parse( item.content.raw, {
__unstableSkipMigrationLogs: true,
} )
);
}, [ item?.content?.raw, item.blocks ] );
const isEmpty = ! blocks?.length;

return (
<div
Expand All @@ -140,7 +150,7 @@ function Preview( { item, viewType } ) {
{ ! isEmpty && (
<Async>
<BlockPreview
blocks={ item.blocks }
blocks={ blocks }
viewportWidth={ item.viewportWidth }
/>
</Async>
Expand Down Expand Up @@ -187,11 +197,13 @@ function Author( { item, viewType } ) {

function Title( { item } ) {
const isUserPattern = item.type === PATTERN_TYPES.user;
const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE;
const { onClick } = useLink( {
postType: item.type,
postId: isUserPattern ? item.id : item.name,
postId: isUserPattern || isTemplatePart ? item.id : item.name,
canvas: 'edit',
} );
const title = decodeEntities( defaultGetTitle( item ) );
return (
<HStack alignment="center" justify="flex-start" spacing={ 2 }>
<Flex
Expand All @@ -201,7 +213,7 @@ function Title( { item } ) {
className="edit-site-patterns__pattern-title"
>
{ item.type === PATTERN_TYPES.theme ? (
item.title
title
) : (
<Button
variant="link"
Expand All @@ -210,7 +222,7 @@ function Title( { item } ) {
// See https://github.com/WordPress/gutenberg/pull/51898#discussion_r1243399243.
tabIndex="-1"
>
{ item.title || item.name }
{ title || item.name }
</Button>
) }
</Flex>
Expand Down Expand Up @@ -321,7 +333,7 @@ export default function DataviewsPatterns() {
_fields.push( {
header: __( 'Author' ),
id: 'author',
getValue: ( { item } ) => item.templatePart.author_text,
getValue: ( { item } ) => item.author_text,
render: ( { item } ) => {
return <Author viewType={ view.type } item={ item } />;
},
Expand Down Expand Up @@ -406,7 +418,7 @@ export default function DataviewsPatterns() {
fields={ fields }
actions={ actions }
data={ data || EMPTY_ARRAY }
getItemId={ ( item ) => item.name }
getItemId={ ( item ) => item.name ?? item.id }
isLoading={ isResolving }
view={ view }
onChangeView={ onChangeView }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ import {
PATTERN_DEFAULT_CATEGORY,
PATTERN_USER_CATEGORY,
PATTERN_TYPES,
TEMPLATE_PART_POST_TYPE,
} from '../../utils/constants';

// Default search helpers.
const defaultGetName = ( item ) => item.name || '';
const defaultGetTitle = ( item ) => item.title;
const defaultGetName = ( item ) =>
item.type !== TEMPLATE_PART_POST_TYPE ? item.name || '' : '';
export const defaultGetTitle = ( item ) =>
typeof item.title === 'string' ? item.title : item.title.rendered;
const defaultGetDescription = ( item ) => item.description || '';
const defaultGetKeywords = ( item ) => item.keywords || [];
const defaultHasCategory = () => false;
Expand Down
40 changes: 6 additions & 34 deletions packages/edit-site/src/components/page-patterns/use-patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { parse } from '@wordpress/blocks';
import { useSelect, createSelector } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { store as editorStore } from '@wordpress/editor';
import { decodeEntities } from '@wordpress/html-entities';

/**
* Internal dependencies
Expand All @@ -16,7 +15,6 @@ import {
PATTERN_TYPES,
PATTERN_SYNC_TYPES,
TEMPLATE_PART_POST_TYPE,
TEMPLATE_ORIGINS,
TEMPLATE_PART_AREA_DEFAULT_CATEGORY,
} from '../../utils/constants';
import { unlock } from '../../lock-unlock';
Expand All @@ -25,38 +23,16 @@ import { store as editSiteStore } from '../../store';

const EMPTY_PATTERN_LIST = [];

const createTemplatePartId = ( theme, slug ) =>
theme && slug ? theme + '//' + slug : null;

const templatePartToPattern = ( templatePart ) => ( {
blocks: parse( templatePart.content.raw, {
__unstableSkipMigrationLogs: true,
} ),
categories: [ templatePart.area ],
description: templatePart.description || '',
isCustom: templatePart.source === TEMPLATE_ORIGINS.custom,
keywords: templatePart.keywords || [],
id: createTemplatePartId( templatePart.theme, templatePart.slug ),
name: createTemplatePartId( templatePart.theme, templatePart.slug ),
title: decodeEntities( templatePart.title.rendered ),
type: templatePart.type,
_links: templatePart._links,
templatePart,
} );

const selectTemplatePartsAsPatterns = createSelector(
const selectTemplateParts = createSelector(
( select, categoryId, search = '' ) => {
const { getEntityRecords, isResolving: isResolvingSelector } =
select( coreStore );
const { __experimentalGetDefaultTemplatePartAreas } =
select( editorStore );
const query = { per_page: -1 };
const rawTemplateParts =
const templateParts =
getEntityRecords( 'postType', TEMPLATE_PART_POST_TYPE, query ) ??
EMPTY_PATTERN_LIST;
const templateParts = rawTemplateParts.map( ( templatePart ) =>
templatePartToPattern( templatePart )
);

// In the case where a custom template part area has been removed we need
// the current list of areas to cross check against so orphaned template
Expand All @@ -66,12 +42,12 @@ const selectTemplatePartsAsPatterns = createSelector(

const templatePartHasCategory = ( item, category ) => {
if ( category !== TEMPLATE_PART_AREA_DEFAULT_CATEGORY ) {
return item.templatePart.area === category;
return item.area === category;
}

return (
item.templatePart.area === category ||
! templatePartAreas.includes( item.templatePart.area )
item.area === category ||
! templatePartAreas.includes( item.area )
);
};

Expand Down Expand Up @@ -298,11 +274,7 @@ export const usePatterns = (
return useSelect(
( select ) => {
if ( postType === TEMPLATE_PART_POST_TYPE ) {
return selectTemplatePartsAsPatterns(
select,
categoryId,
search
);
return selectTemplateParts( select, categoryId, search );
} else if ( postType === PATTERN_TYPES.user && !! categoryId ) {
const appliedCategory =
categoryId === 'uncategorized' ? '' : categoryId;
Expand Down
43 changes: 23 additions & 20 deletions packages/editor/src/components/post-actions/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { __, _n, sprintf, _x } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { useMemo, useState } from '@wordpress/element';
import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
import { parse } from '@wordpress/blocks';

import {
Button,
Expand Down Expand Up @@ -52,17 +53,17 @@ function isTemplateRemovable( template ) {
// than the one returned from the endpoint. This is why we need to check for
// two props whether is custom or has a theme file.
return (
[ template.source, template.templatePart?.source ].includes(
TEMPLATE_ORIGINS.custom
) &&
! template.has_theme_file &&
! template.templatePart?.has_theme_file
template?.source === TEMPLATE_ORIGINS.custom &&
! template?.has_theme_file
);
}
const canDeleteOrReset = ( item ) => {
const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE;
const isUserPattern = item.type === PATTERN_TYPES.user;
return isUserPattern || ( isTemplatePart && item.isCustom );
return (
isUserPattern ||
( isTemplatePart && item.source === TEMPLATE_ORIGINS.custom )
);
};

function getItemTitle( item ) {
Expand Down Expand Up @@ -630,19 +631,13 @@ const renamePostAction = {
// two props whether is custom or has a theme file.
const isCustomPattern =
isUserPattern ||
( isTemplatePart &&
( post.isCustom || post.source === TEMPLATE_ORIGINS.custom ) );
const hasThemeFile =
isTemplatePart &&
( post.templatePart?.has_theme_file || post.has_theme_file );
( isTemplatePart && post.source === TEMPLATE_ORIGINS.custom );
const hasThemeFile = post?.has_theme_file;
return isCustomPattern && ! hasThemeFile;
},
RenderModal: ( { items, closeModal, onActionPerformed } ) => {
const [ item ] = items;
const originalTitle = decodeEntities(
typeof item.title === 'string' ? item.title : item.title.rendered
);
const [ title, setTitle ] = useState( () => originalTitle );
const [ title, setTitle ] = useState( () => getItemTitle( item ) );
const { editEntityRecord, saveEditedEntityRecord } =
useDispatch( coreStore );
const { createSuccessNotice, createErrorNotice } =
Expand Down Expand Up @@ -879,7 +874,7 @@ const isTemplatePartRevertable = ( item ) => {
if ( ! item ) {
return false;
}
const hasThemeFile = item.templatePart?.has_theme_file;
const hasThemeFile = item?.has_theme_file;
return canDeleteOrReset( item ) && hasThemeFile;
};

Expand Down Expand Up @@ -1031,26 +1026,34 @@ export const duplicateTemplatePartAction = {
modalHeader: _x( 'Duplicate template part', 'action label' ),
RenderModal: ( { items, closeModal } ) => {
const [ item ] = items;
const blocks = useMemo( () => {
return (
item.blocks ??
parse( item.content.raw, {
__unstableSkipMigrationLogs: true,
} )
);
}, [ item?.content?.raw, item.blocks ] );
const { createSuccessNotice } = useDispatch( noticesStore );
function onTemplatePartSuccess() {
createSuccessNotice(
sprintf(
// translators: %s: The new template part's title e.g. 'Call to action (copy)'.
__( '"%s" duplicated.' ),
item.title
getItemTitle( item )
),
{ type: 'snackbar', id: 'edit-site-patterns-success' }
);
closeModal();
}
return (
<CreateTemplatePartModalContents
blocks={ item.blocks }
defaultArea={ item.templatePart?.area || item.area }
blocks={ blocks }
defaultArea={ item.area }
defaultTitle={ sprintf(
/* translators: %s: Existing template part title */
__( '%s (Copy)' ),
item.title
getItemTitle( item )
) }
onCreate={ onTemplatePartSuccess }
onError={ closeModal }
Expand Down
7 changes: 1 addition & 6 deletions packages/editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,12 +370,7 @@ export const revertTemplate =
export const removeTemplates =
( items ) =>
async ( { registry } ) => {
const isResetting = items.every(
( item ) =>
!! item &&
( item.has_theme_file ||
( item.templatePart && item.templatePart.has_theme_file ) )
);
const isResetting = items.every( ( item ) => item?.has_theme_file );

const promiseResult = await Promise.allSettled(
items.map( ( item ) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ test.describe( 'Site editor url navigation', () => {
.getByRole( 'region', {
name: 'Patterns content',
} )
.getByLabel( 'header', { exact: true } )
.getByText( 'header', { exact: true } )
.click();
await expect(
page.getByRole( 'region', { name: 'Editor content' } )
Expand Down

0 comments on commit 9a331f1

Please sign in to comment.