Skip to content

Commit

Permalink
Template Parts: Add duplicate template part command
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Oct 13, 2023
1 parent fb1c039 commit 8ade2be
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default function CreateTemplatePartModal( {
defaultArea = TEMPLATE_PART_AREA_DEFAULT_CATEGORY,
blocks = [],
confirmLabel = __( 'Create' ),
content,
closeModal,
modalTitle = __( 'Create template part' ),
onCreate,
Expand Down Expand Up @@ -82,7 +83,7 @@ export default function CreateTemplatePartModal( {
{
slug: cleanSlug,
title: uniqueTitle,
content: serialize( blocks ),
content: content || serialize( blocks ),
area,
},
{ throwOnError: true }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* WordPress dependencies
*/
import { useDispatch } from '@wordpress/data';
import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';

/**
* Internal dependencies
*/
import CreateTemplatePartModal from '../create-template-part-modal';

export default function DuplicateTemplatePartModal( {
templatePart,
onClose,
onSuccess,
} ) {
const { createSuccessNotice } = useDispatch( noticesStore );

function handleOnSuccess( newTemplatePart ) {
createSuccessNotice(
sprintf(
// translators: %s: The new template part's title e.g. 'Call to action (copy)'.
__( '"%s" duplicated.' ),
templatePart.title
),
{
type: 'snackbar',
id: 'template-parts-create',
}
);

onSuccess?.( newTemplatePart );
}

return (
<CreateTemplatePartModal
content={ templatePart.content }
closeModal={ onClose }
confirmLabel={ __( 'Duplicate' ) }
defaultArea={ templatePart.area }
defaultTitle={ sprintf(
/* translators: %s: Existing template part title */
__( '%s (Copy)' ),
typeof templatePart.title === 'string'
? templatePart.title
: templatePart.title.raw
) }
modalTitle={ __( 'Duplicate template part' ) }
onCreate={ handleOnSuccess }
onError={ onClose }
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
* WordPress dependencies
*/
import { MenuItem } from '@wordpress/components';
import { useDispatch } from '@wordpress/data';
import { useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { __ } from '@wordpress/i18n';
import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
import { privateApis as routerPrivateApis } from '@wordpress/router';

Expand All @@ -14,7 +12,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
*/
import { TEMPLATE_PART_POST_TYPE, PATTERN_TYPES } from '../../utils/constants';
import { unlock } from '../../lock-unlock';
import CreateTemplatePartModal from '../create-template-part-modal';
import DuplicateTemplatePartModal from '../duplicate-template-part-modal';

const { DuplicatePatternModal } = unlock( patternsPrivateApis );
const { useHistory } = unlock( routerPrivateApis );
Expand All @@ -25,7 +23,6 @@ export default function DuplicateMenuItem( {
label = __( 'Duplicate' ),
onClose,
} ) {
const { createSuccessNotice } = useDispatch( noticesStore );
const [ isModalOpen, setIsModalOpen ] = useState( false );
const history = useHistory();

Expand All @@ -35,18 +32,6 @@ export default function DuplicateMenuItem( {
const isThemePattern = item.type === PATTERN_TYPES.theme;

async function onTemplatePartSuccess( templatePart ) {
createSuccessNotice(
sprintf(
// translators: %s: The new template part's title e.g. 'Call to action (copy)'.
__( '"%s" duplicated.' ),
item.title
),
{
type: 'snackbar',
id: 'edit-site-patterns-success',
}
);

history.push( {
postType: TEMPLATE_PART_POST_TYPE,
postId: templatePart?.id,
Expand Down Expand Up @@ -85,19 +70,10 @@ export default function DuplicateMenuItem( {
/>
) }
{ isModalOpen && isTemplatePart && (
<CreateTemplatePartModal
blocks={ item.blocks }
closeModal={ closeModal }
confirmLabel={ __( 'Duplicate' ) }
defaultArea={ item.templatePart.area }
defaultTitle={ sprintf(
/* translators: %s: Existing template part title */
__( '%s (Copy)' ),
item.title
) }
modalTitle={ __( 'Duplicate template part' ) }
onCreate={ onTemplatePartSuccess }
onError={ closeModal }
<DuplicateTemplatePartModal
onClose={ closeModal }
onSuccess={ onTemplatePartSuccess }
templatePart={ item.templatePart }
/>
) }
</>
Expand Down
52 changes: 52 additions & 0 deletions packages/edit-site/src/components/template-part-modal/duplicate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* WordPress dependencies
*/
import { useDispatch, useSelect } from '@wordpress/data';
import { store as interfaceStore } from '@wordpress/interface';
import { privateApis as routerPrivateApis } from '@wordpress/router';
import { getQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
*/
import useEditedEntityRecord from '../use-edited-entity-record';
import DuplicateTemplatePartModal from '../duplicate-template-part-modal';
import { TEMPLATE_PART_MODALS } from './';
import { unlock } from '../../lock-unlock';
import { TEMPLATE_PART_POST_TYPE } from '../../utils/constants';

const { useHistory } = unlock( routerPrivateApis );

export default function PatternDuplicateModal() {
const { record } = useEditedEntityRecord();
const { categoryType, categoryId } = getQueryArgs( window.location.href );
const { closeModal } = useDispatch( interfaceStore );
const history = useHistory();

const isActive = useSelect( ( select ) =>
select( interfaceStore ).isModalActive( TEMPLATE_PART_MODALS.duplicate )
);

if ( ! isActive ) {
return null;
}

function onSuccess( newTemplatePart ) {
history.push( {
postType: TEMPLATE_PART_POST_TYPE,
postId: newTemplatePart.id,
categoryType,
categoryId,
} );

closeModal();
}

return (
<DuplicateTemplatePartModal
onClose={ closeModal }
onSuccess={ onSuccess }
templatePart={ record }
/>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* Internal dependencies
*/
import TemplatePartDuplicateModal from './duplicate';
import TemplatePartRenameModal from './rename';

export const TEMPLATE_PART_MODALS = {
Expand All @@ -9,11 +10,10 @@ export const TEMPLATE_PART_MODALS = {
};

export default function TemplatePartModal() {
// Duplication command and modal is in separate follow-up.
return (
<>
<TemplatePartRenameModal />
{ /* <PatternDuplicateModal /> */ }
<TemplatePartDuplicateModal />
</>
);
}
13 changes: 11 additions & 2 deletions packages/edit-site/src/hooks/commands/use-edit-mode-commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { useSelect, useDispatch } from '@wordpress/data';
import { __, sprintf, isRTL } from '@wordpress/i18n';
import {
edit,
trash,
rotateLeft,
rotateRight,
Expand Down Expand Up @@ -398,15 +399,23 @@ function usePatternCommands() {
commands.push( {
name: 'core/rename-template-part',
label: __( 'Rename template part' ),
icon: symbol,
icon: edit,
callback: ( { close } ) => {
openModal( TEMPLATE_PART_MODALS.rename );
close();
},
} );
}

// All template parts will be eligible for duplication in a follow-up.
commands.push( {
name: 'core/duplicate-template-part',
label: __( 'Duplicate template part' ),
icon: symbol,
callback: ( { close } ) => {
openModal( TEMPLATE_PART_MODALS.duplicate );
close();
},
} );
}

return { isLoading: false, commands };
Expand Down

0 comments on commit 8ade2be

Please sign in to comment.