Skip to content

Commit

Permalink
Patterns: Avoid mapping template parts objects to patterns (#62927)
Browse files Browse the repository at this point in the history
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org>
Co-authored-by: oandregal <oandregal@git.wordpress.org>
  • Loading branch information
5 people committed 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

1 comment on commit 9a331f1

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 9a331f1.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/9716428975
📝 Reported issues:

Please sign in to comment.