diff --git a/packages/edit-site/src/components/create-template-part-modal/index.js b/packages/edit-site/src/components/create-template-part-modal/index.js index b44446da0c068..1de94832878cd 100644 --- a/packages/edit-site/src/components/create-template-part-modal/index.js +++ b/packages/edit-site/src/components/create-template-part-modal/index.js @@ -57,6 +57,7 @@ export function CreateTemplatePartModalContents( { defaultArea = TEMPLATE_PART_AREA_DEFAULT_CATEGORY, blocks = [], confirmLabel = __( 'Create' ), + content, closeModal, onCreate, onError, @@ -95,7 +96,7 @@ export function CreateTemplatePartModalContents( { { slug: cleanSlug, title: uniqueTitle, - content: serialize( blocks ), + content: content || serialize( blocks ), area, }, { throwOnError: true } diff --git a/packages/edit-site/src/components/template-part-modal/duplicate.js b/packages/edit-site/src/components/template-part-modal/duplicate.js new file mode 100644 index 0000000000000..329334ce67d5d --- /dev/null +++ b/packages/edit-site/src/components/template-part-modal/duplicate.js @@ -0,0 +1,93 @@ +/** + * WordPress dependencies + */ +import { useDispatch, useSelect } from '@wordpress/data'; +import { __, sprintf } from '@wordpress/i18n'; +import { store as interfaceStore } from '@wordpress/interface'; +import { store as noticesStore } from '@wordpress/notices'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { getQueryArgs } from '@wordpress/url'; + +/** + * Internal dependencies + */ +import CreateTemplatePartModal from '../create-template-part-modal'; +import useEditedEntityRecord from '../use-edited-entity-record'; +import { TEMPLATE_PART_MODALS } from './'; +import { unlock } from '../../lock-unlock'; +import { TEMPLATE_PART_POST_TYPE } from '../../utils/constants'; + +const { useHistory } = unlock( routerPrivateApis ); + +function DuplicateModal( { 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 ( + + ); +} + +export default function TemplatePartDuplicateModal() { + 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 ( + + ); +} diff --git a/packages/edit-site/src/components/template-part-modal/index.js b/packages/edit-site/src/components/template-part-modal/index.js index 632470483186a..aea7e909a29cc 100644 --- a/packages/edit-site/src/components/template-part-modal/index.js +++ b/packages/edit-site/src/components/template-part-modal/index.js @@ -1,6 +1,7 @@ /** * Internal dependencies */ +import TemplatePartDuplicateModal from './duplicate'; import TemplatePartRenameModal from './rename'; export const TEMPLATE_PART_MODALS = { @@ -9,11 +10,10 @@ export const TEMPLATE_PART_MODALS = { }; export default function TemplatePartModal() { - // Duplication command and modal is in separate follow-up. return ( <> - { /* */ } + ); } diff --git a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js index e5a756aed101f..6e6f6a87dad12 100644 --- a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js +++ b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js @@ -290,7 +290,7 @@ 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(); @@ -298,7 +298,15 @@ function usePatternCommands() { } ); } - // 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 };