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

[Site Editor]: Add create pattern button in patterns page #60302

Merged
merged 7 commits into from
May 21, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 29 additions & 22 deletions packages/edit-site/src/components/add-new-pattern/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { DropdownMenu } from '@wordpress/components';
import { useState, useRef } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { plus, symbol, symbolFilled, upload } from '@wordpress/icons';
import { symbol, symbolFilled, upload } from '@wordpress/icons';
import { useSelect, useDispatch } from '@wordpress/data';
import { privateApis as routerPrivateApis } from '@wordpress/router';
import {
Expand All @@ -18,7 +18,6 @@ import { store as coreStore } from '@wordpress/core-data';
* Internal dependencies
*/
import CreateTemplatePartModal from '../create-template-part-modal';
import SidebarButton from '../sidebar-button';
import { unlock } from '../../lock-unlock';
import {
PATTERN_TYPES,
Expand All @@ -41,10 +40,17 @@ export default function AddNewPattern() {
const { createSuccessNotice, createErrorNotice } =
useDispatch( noticesStore );
const patternUploadInputRef = useRef();
const isBlockBasedTheme = useSelect(
( select ) => select( coreStore ).getCurrentTheme()?.is_block_theme,
[]
);
const { isBlockBasedTheme, addNewPatternLabel, addNewTemplatePartLabel } =
useSelect( ( select ) => {
const { getCurrentTheme, getPostType } = select( coreStore );
return {
isBlockBasedTheme: getCurrentTheme()?.is_block_theme,
addNewPatternLabel: getPostType( PATTERN_TYPES.user )?.labels
?.add_new_item,
addNewTemplatePartLabel: getPostType( TEMPLATE_PART_POST_TYPE )
?.labels?.add_new_item,
};
}, [] );

function handleCreatePattern( { pattern, categoryId } ) {
setShowPatternModal( false );
Expand Down Expand Up @@ -74,19 +80,19 @@ export default function AddNewPattern() {
setShowTemplatePartModal( false );
}

const controls = [];

controls.push( {
icon: symbol,
onClick: () => setShowPatternModal( true ),
title: __( 'Create pattern' ),
} );
const controls = [
{
icon: symbol,
onClick: () => setShowPatternModal( true ),
title: addNewPatternLabel,
},
];

if ( isBlockBasedTheme ) {
controls.push( {
icon: symbolFilled,
onClick: () => setShowTemplatePartModal( true ),
title: __( 'Create template part' ),
title: addNewTemplatePartLabel,
} );
}

Expand All @@ -101,14 +107,15 @@ export default function AddNewPattern() {
const { categoryMap, findOrCreateTerm } = useAddPatternCategory();
return (
<>
<DropdownMenu
controls={ controls }
toggleProps={ {
as: SidebarButton,
} }
icon={ plus }
label={ __( 'Create pattern' ) }
/>
{ addNewPatternLabel && (
<DropdownMenu
controls={ controls }
icon={ null }
toggleProps={ { variant: 'primary', showTooltip: false } }
text={ addNewPatternLabel }
label={ addNewPatternLabel }
/>
) }
{ showPatternModal && (
<CreatePatternModal
onClose={ () => setShowPatternModal( false ) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ import {
} from '../../utils/template-part-create';

export default function CreateTemplatePartModal( {
modalTitle = __( 'Create template part' ),
modalTitle,
...restProps
} ) {
const defaultModalTitle = useSelect(
( select ) =>
select( coreStore ).getPostType( TEMPLATE_PART_POST_TYPE )?.labels
?.add_new_item,
[]
);
return (
<Modal
title={ modalTitle }
title={ modalTitle || defaultModalTitle }
onRequestClose={ restProps.closeModal }
overlayClassName="edit-site-create-template-part-modal"
>
Expand All @@ -56,7 +62,7 @@ export default function CreateTemplatePartModal( {
export function CreateTemplatePartModalContents( {
defaultArea = TEMPLATE_PART_AREA_DEFAULT_CATEGORY,
blocks = [],
confirmLabel = __( 'Create' ),
confirmLabel = __( 'Add' ),
closeModal,
onCreate,
onError,
Expand Down
31 changes: 16 additions & 15 deletions packages/edit-site/src/components/page-pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,13 @@ export default function PagePages() {
[ totalItems, totalPages ]
);

const { frontPageId, postsPageId } = useSelect( ( select ) => {
const { getEntityRecord } = select( coreStore );
const { frontPageId, postsPageId, addNewLabel } = useSelect( ( select ) => {
const { getEntityRecord, getPostType } = select( coreStore );
const siteSettings = getEntityRecord( 'root', 'site' );

return {
frontPageId: siteSettings?.page_on_front,
postsPageId: siteSettings?.page_for_posts,
addNewLabel: getPostType( 'page' )?.labels?.add_new_item,
};
} );

Expand Down Expand Up @@ -488,22 +488,23 @@ export default function PagePages() {
closeModal();
};

// TODO: we need to handle properly `data={ data || EMPTY_ARRAY }` for when `isLoading`.
return (
<Page
title={ __( 'Pages' ) }
actions={
<>
<Button variant="primary" onClick={ openModal }>
{ __( 'Add new page' ) }
</Button>
{ showAddPageModal && (
<AddNewPageModal
onSave={ handleNewPage }
onClose={ closeModal }
/>
) }
</>
addNewLabel && (
<>
<Button variant="primary" onClick={ openModal }>
{ addNewLabel }
</Button>
{ showAddPageModal && (
<AddNewPageModal
onSave={ handleNewPage }
onClose={ closeModal }
/>
) }
</>
)
}
>
<DataViews
Expand Down
62 changes: 33 additions & 29 deletions packages/edit-site/src/components/page-patterns/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { moreVertical } from '@wordpress/icons';
/**
* Internal dependencies
*/
import AddNewPattern from '../add-new-pattern';
import RenameCategoryMenuItem from './rename-category-menu-item';
import DeleteCategoryMenuItem from './delete-category-menu-item';
import usePatternCategories from '../sidebar-navigation-screen-patterns/use-pattern-categories';
Expand Down Expand Up @@ -57,39 +58,42 @@ export default function PatternsHeader( {
}

return (
<VStack className="edit-site-patterns__section-header">
<VStack className="edit-site-patterns__section-header" gap={ 3 }>
<HStack justify="space-between">
<Heading as="h2" level={ 4 } id={ titleId }>
{ title }
</Heading>
{ !! patternCategory?.id && (
<DropdownMenu
icon={ moreVertical }
label={ __( 'Actions' ) }
toggleProps={ {
className: 'edit-site-patterns__button',
describedBy: sprintf(
/* translators: %s: pattern category name */
__( 'Action menu for %s pattern category' ),
title
),
size: 'compact',
} }
>
{ ( { onClose } ) => (
<MenuGroup>
<RenameCategoryMenuItem
category={ patternCategory }
onClose={ onClose }
/>
<DeleteCategoryMenuItem
category={ patternCategory }
onClose={ onClose }
/>
</MenuGroup>
) }
</DropdownMenu>
) }
<HStack expanded={ false }>
<AddNewPattern />
{ !! patternCategory?.id && (
Copy link
Contributor

@youknowriad youknowriad May 21, 2024

Choose a reason for hiding this comment

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

I think this menu should move close to the "title" (left of the header) rather than staying on the right no? Anyway, not a blocker.

<DropdownMenu
icon={ moreVertical }
label={ __( 'Actions' ) }
toggleProps={ {
className: 'edit-site-patterns__button',
describedBy: sprintf(
/* translators: %s: pattern category name */
__( 'Action menu for %s pattern category' ),
title
),
size: 'compact',
} }
>
{ ( { onClose } ) => (
<MenuGroup>
<RenameCategoryMenuItem
category={ patternCategory }
onClose={ onClose }
/>
<DeleteCategoryMenuItem
category={ patternCategory }
onClose={ onClose }
/>
</MenuGroup>
) }
</DropdownMenu>
) }
</HStack>
</HStack>
{ description ? (
<Text variant="muted" as="p" id={ descriptionId }>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
/**
* Internal dependencies
*/
import AddNewPattern from '../add-new-pattern';
import SidebarNavigationScreen from '../sidebar-navigation-screen';
import CategoryItem from './category-item';
import {
Expand Down Expand Up @@ -133,7 +132,6 @@ export default function SidebarNavigationScreenPatterns( { backPath } ) {
'Manage what patterns are available when editing the site.'
) }
backPath={ backPath }
actions={ <AddNewPattern /> }
content={
<>
{ isLoading && __( 'Loading items…' ) }
Expand Down
21 changes: 16 additions & 5 deletions packages/patterns/src/components/create-pattern-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,37 @@ import {
} from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { useDispatch, useSelect } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import { store as coreStore } from '@wordpress/core-data';

/**
* Internal dependencies
*/
import { PATTERN_DEFAULT_CATEGORY, PATTERN_SYNC_TYPES } from '../constants';
import {
PATTERN_DEFAULT_CATEGORY,
PATTERN_SYNC_TYPES,
PATTERN_TYPES,
} from '../constants';
import { store as patternsStore } from '../store';
import CategorySelector from './category-selector';
import { useAddPatternCategory } from '../private-hooks';
import { unlock } from '../lock-unlock';

export default function CreatePatternModal( {
className = 'patterns-menu-items__convert-modal',
modalTitle = __( 'Create pattern' ),
modalTitle,
...restProps
} ) {
const defaultModalTitle = useSelect(
( select ) =>
select( coreStore ).getPostType( PATTERN_TYPES.user )?.labels
?.add_new_item,
[]
);
return (
<Modal
title={ modalTitle }
title={ modalTitle || defaultModalTitle }
onRequestClose={ restProps.onClose }
overlayClassName={ className }
>
Expand All @@ -40,7 +51,7 @@ export default function CreatePatternModal( {
}

export function CreatePatternModalContents( {
confirmLabel = __( 'Create' ),
confirmLabel = __( 'Add' ),
defaultCategories = [],
content,
onClose,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ test.describe( 'Block editor keyboard shortcuts', () => {
.getByRole( 'menuitem', { name: 'Create pattern' } )
.click();
await page
.getByRole( 'dialog', { name: 'Create pattern' } )
.getByRole( 'dialog', { name: 'add new pattern' } )
.getByRole( 'textbox', { name: 'Name' } )
.fill( 'hi' );

Expand Down
4 changes: 2 additions & 2 deletions test/e2e/specs/editor/various/inserting-blocks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => {
.click();
await page.getByRole( 'menuitem', { name: 'Create pattern' } ).click();
const createPatternDialog = page.getByRole( 'dialog', {
name: 'Create pattern',
name: 'add new pattern',
} );
await createPatternDialog
.getByRole( 'textbox', { name: 'Name' } )
Expand All @@ -274,7 +274,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => {
.getByRole( 'checkbox', { name: 'Synced' } )
.setChecked( true );
await createPatternDialog
.getByRole( 'button', { name: 'Create' } )
.getByRole( 'button', { name: 'Add' } )
.click();
const patternBlock = page.getByRole( 'document', {
name: 'Block: Pattern',
Expand Down
12 changes: 6 additions & 6 deletions test/e2e/specs/editor/various/pattern-overrides.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ test.describe( 'Pattern Overrides', () => {
await admin.visitSiteEditor( { path: '/patterns' } );

await page
.getByRole( 'region', { name: 'Navigation' } )
.getByRole( 'button', { name: 'Create pattern' } )
.getByRole( 'region', { name: 'Patterns content' } )
.getByRole( 'button', { name: 'add new pattern' } )
.click();

await page
.getByRole( 'menu', { name: 'Create pattern' } )
.getByRole( 'menuitem', { name: 'Create pattern' } )
.getByRole( 'menu', { name: 'add new pattern' } )
.getByRole( 'menuitem', { name: 'add new pattern' } )
.click();

const createPatternDialog = page.getByRole( 'dialog', {
name: 'Create pattern',
name: 'add new pattern',
} );
await createPatternDialog
.getByRole( 'textbox', { name: 'Name' } )
Expand All @@ -57,7 +57,7 @@ test.describe( 'Pattern Overrides', () => {
.getByRole( 'checkbox', { name: 'Synced' } )
.setChecked( true );
await createPatternDialog
.getByRole( 'button', { name: 'Create' } )
.getByRole( 'button', { name: 'Add' } )
.click();

await editor.canvas
Expand Down
Loading
Loading