diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index ff5cd7ddbb5452..0df73d1996deb5 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -9,7 +9,6 @@ import { store as coreStore } from '@wordpress/core-data'; import { __, sprintf, _x } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; import { useMemo, useState, useEffect } from '@wordpress/element'; -import { parse } from '@wordpress/blocks'; import { DataForm } from '@wordpress/dataviews'; import { Button, @@ -27,7 +26,6 @@ import { } from '../../store/constants'; import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; -import { CreateTemplatePartModalContents } from '../create-template-part-modal'; import { getItemTitle } from '../../dataviews/actions/utils'; // TODO: this should be shared with other components (see post-fields in edit-site). @@ -268,75 +266,14 @@ const useDuplicatePostAction = ( postType ) => { ); }; -export const duplicateTemplatePartAction = { - id: 'duplicate-template-part', - label: _x( 'Duplicate', 'action label' ), - isEligible: ( item ) => item.type === TEMPLATE_PART_POST_TYPE, - modalHeader: _x( 'Duplicate template part', 'action label' ), - RenderModal: ( { items, closeModal } ) => { - const [ item ] = items; - const blocks = useMemo( () => { - return ( - item.blocks ?? - parse( - typeof item.content === 'string' - ? item.content - : item.content.raw, - { - __unstableSkipMigrationLogs: true, - } - ) - ); - }, [ item.content, 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.' ), - getItemTitle( item ) - ), - { type: 'snackbar', id: 'edit-site-patterns-success' } - ); - closeModal(); - } - return ( - - ); - }, -}; - export function usePostActions( { postType, onActionPerformed, context } ) { - const { - defaultActions, - postTypeObject, - userCanCreatePostType, - isBlockBasedTheme, - } = useSelect( + const { defaultActions, postTypeObject } = useSelect( ( select ) => { - const { getPostType, canUser, getCurrentTheme } = - select( coreStore ); + const { getPostType } = select( coreStore ); const { getEntityActions } = unlock( select( editorStore ) ); return { postTypeObject: getPostType( postType ), defaultActions: getEntityActions( 'postType', postType ), - userCanCreatePostType: canUser( 'create', { - kind: 'postType', - name: postType, - } ), - isBlockBasedTheme: getCurrentTheme()?.is_block_theme, }; }, [ postType ] @@ -368,10 +305,6 @@ export function usePostActions( { postType, onActionPerformed, context } ) { ! isPattern && duplicatePostAction : false, - isTemplateOrTemplatePart && - userCanCreatePostType && - isBlockBasedTheme && - duplicateTemplatePartAction, ...defaultActions, ].filter( Boolean ); // Filter actions based on provided context. If not provided @@ -437,7 +370,6 @@ export function usePostActions( { postType, onActionPerformed, context } ) { return actions; }, [ defaultActions, - userCanCreatePostType, isTemplateOrTemplatePart, isPattern, postTypeObject?.viewable, diff --git a/packages/editor/src/dataviews/actions/duplicate-template-part.tsx b/packages/editor/src/dataviews/actions/duplicate-template-part.tsx new file mode 100644 index 00000000000000..fa3cf39ba76268 --- /dev/null +++ b/packages/editor/src/dataviews/actions/duplicate-template-part.tsx @@ -0,0 +1,70 @@ +/** + * WordPress dependencies + */ +import { useDispatch } from '@wordpress/data'; +import { __, sprintf, _x } from '@wordpress/i18n'; +import { store as noticesStore } from '@wordpress/notices'; +import { useMemo } from '@wordpress/element'; +// @ts-ignore +import { parse } from '@wordpress/blocks'; +import type { Action } from '@wordpress/dataviews'; + +/** + * Internal dependencies + */ +import { TEMPLATE_PART_POST_TYPE } from '../../store/constants'; +import { CreateTemplatePartModalContents } from '../../components/create-template-part-modal'; +import { getItemTitle } from './utils'; +import type { TemplatePart } from '../types'; + +const duplicateTemplatePart: Action< TemplatePart > = { + id: 'duplicate-template-part', + label: _x( 'Duplicate', 'action label' ), + isEligible: ( item ) => item.type === TEMPLATE_PART_POST_TYPE, + modalHeader: _x( 'Duplicate template part', 'action label' ), + RenderModal: ( { items, closeModal } ) => { + const [ item ] = items; + const blocks = useMemo( () => { + return ( + item.blocks ?? + parse( + typeof item.content === 'string' + ? item.content + : item.content.raw, + { + __unstableSkipMigrationLogs: true, + } + ) + ); + }, [ item.content, 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.' ), + getItemTitle( item ) + ), + { type: 'snackbar', id: 'edit-site-patterns-success' } + ); + closeModal?.(); + } + return ( + + ); + }, +}; + +export default duplicateTemplatePart; diff --git a/packages/editor/src/dataviews/store/private-actions.ts b/packages/editor/src/dataviews/store/private-actions.ts index 6854c29bb0c4e4..80449d1b7a0798 100644 --- a/packages/editor/src/dataviews/store/private-actions.ts +++ b/packages/editor/src/dataviews/store/private-actions.ts @@ -10,6 +10,7 @@ import { doAction } from '@wordpress/hooks'; */ import deletePost from '../actions/delete-post'; import duplicatePattern from '../actions/duplicate-pattern'; +import duplicateTemplatePart from '../actions/duplicate-template-part'; import exportPattern from '../actions/export-pattern'; import resetPost from '../actions/reset-post'; import trashPost from '../actions/trash-post'; @@ -81,8 +82,15 @@ export const registerPostTypeActions = kind: 'postType', name: postType, } ); + const currentTheme = await registry + .resolveSelect( coreStore ) + .getCurrentTheme(); const actions = [ + postTypeConfig.slug === 'wp_template_part' && + canCreate && + currentTheme?.is_block_theme && + duplicateTemplatePart, canCreate && postTypeConfig.slug === 'wp_block' ? duplicatePattern : undefined, diff --git a/packages/editor/src/dataviews/types.ts b/packages/editor/src/dataviews/types.ts index 80b6f3c5ceb852..5750ab96eeae81 100644 --- a/packages/editor/src/dataviews/types.ts +++ b/packages/editor/src/dataviews/types.ts @@ -10,8 +10,10 @@ type PostStatus = export interface BasePost { status?: PostStatus; title: string | { rendered: string } | { raw: string }; + content: string | { raw: string; rendered: string }; type: string; id: string | number; + blocks?: Object[]; } export interface Template extends BasePost { @@ -27,12 +29,12 @@ export interface TemplatePart extends BasePost { source: string; has_theme_file: boolean; id: string; + area: string; } export interface Pattern extends BasePost { slug: string; title: { raw: string }; - content: { raw: string } | string; wp_pattern_sync_status: string; }