diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index f3ee1bda69719f..dcec39ddc7bedb 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -44,6 +44,7 @@ import CanvasLoader from '../canvas-loader'; import { unlock } from '../../lock-unlock'; import useEditedEntityRecord from '../use-edited-entity-record'; import { SidebarFixedBottomSlot } from '../sidebar-edit-mode/sidebar-fixed-bottom'; +import PatternModal from '../pattern-modal'; import { POST_TYPE_LABELS, TEMPLATE_POST_TYPE } from '../../utils/constants'; const { BlockRemovalWarningModal } = unlock( blockEditorPrivateApis ); @@ -220,6 +221,7 @@ export default function Editor( { listViewToggleElement, isLoading } ) { + ) } { editorMode === 'text' && diff --git a/packages/edit-site/src/components/page-patterns/rename-menu-item.js b/packages/edit-site/src/components/page-patterns/rename-menu-item.js index 5792454a44aa8a..8b1d6771c2e90e 100644 --- a/packages/edit-site/src/components/page-patterns/rename-menu-item.js +++ b/packages/edit-site/src/components/page-patterns/rename-menu-item.js @@ -61,9 +61,9 @@ export default function RenameMenuItem( { item, onClose } ) { const fallbackErrorMessage = item.type === TEMPLATE_PART_POST_TYPE ? __( - 'An error occurred while reverting the template part.' + 'An error occurred while renaming the template part.' ) - : __( 'An error occurred while reverting the pattern.' ); + : __( 'An error occurred while renaming the pattern.' ); const errorMessage = error.message && error.code !== 'unknown_error' ? error.message diff --git a/packages/edit-site/src/components/pattern-modal/index.js b/packages/edit-site/src/components/pattern-modal/index.js new file mode 100644 index 00000000000000..acf96a64877255 --- /dev/null +++ b/packages/edit-site/src/components/pattern-modal/index.js @@ -0,0 +1,14 @@ +/** + * Internal dependencies + */ +import PatternRenameModal from './rename'; + +export const PATTERN_MODALS = { + rename: 'edit-site/pattern-rename', +}; + +export default function PatternModal() { + // Further modals are likely + // e.g. duplicating and switching up sync status etc. + return ; +} diff --git a/packages/edit-site/src/components/pattern-modal/rename.js b/packages/edit-site/src/components/pattern-modal/rename.js new file mode 100644 index 00000000000000..3175451bd16460 --- /dev/null +++ b/packages/edit-site/src/components/pattern-modal/rename.js @@ -0,0 +1,29 @@ +/** + * WordPress dependencies + */ +import { useDispatch, useSelect } from '@wordpress/data'; +import { store as interfaceStore } from '@wordpress/interface'; +import { privateApis as patternsPrivateApis } from '@wordpress/patterns'; + +/** + * Internal dependencies + */ +import { PATTERN_MODALS } from './'; +import { unlock } from '../../lock-unlock'; +import useEditedEntityRecord from '../use-edited-entity-record'; + +const { RenamePatternModal } = unlock( patternsPrivateApis ); + +export default function PatternRenameModal() { + const { record: pattern } = useEditedEntityRecord(); + const { closeModal } = useDispatch( interfaceStore ); + const isActive = useSelect( ( select ) => + select( interfaceStore ).isModalActive( PATTERN_MODALS.rename ) + ); + + if ( ! isActive ) { + return null; + } + + 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 a10d518d53644b..107efce384eb72 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 @@ -15,6 +15,7 @@ import { code, keyboard, listView, + symbol, } from '@wordpress/icons'; import { useCommandLoader } from '@wordpress/commands'; import { decodeEntities } from '@wordpress/html-entities'; @@ -32,6 +33,7 @@ import isTemplateRemovable from '../../utils/is-template-removable'; import isTemplateRevertable from '../../utils/is-template-revertable'; import { KEYBOARD_SHORTCUT_HELP_MODAL_NAME } from '../../components/keyboard-shortcut-help-modal'; import { PREFERENCES_MODAL_NAME } from '../../components/preferences-modal'; +import { PATTERN_MODALS } from '../../components/pattern-modal'; import { unlock } from '../../lock-unlock'; import { TEMPLATE_POST_TYPE } from '../../utils/constants'; @@ -359,6 +361,31 @@ function useEditUICommands() { }; } +function usePatternCommands() { + const { isLoaded, record: pattern } = useEditedEntityRecord(); + const { openModal } = useDispatch( interfaceStore ); + + if ( ! isLoaded ) { + return { isLoading: true, commands: [] }; + } + + const commands = []; + + if ( pattern?.type === 'wp_block' ) { + commands.push( { + name: 'core/rename-pattern', + label: __( 'Rename pattern' ), + icon: symbol, + callback: ( { close } ) => { + openModal( PATTERN_MODALS.rename ); + close(); + }, + } ); + } + + return { isLoading: false, commands }; +} + export function useEditModeCommands() { useCommandLoader( { name: 'core/exit-code-editor', @@ -377,6 +404,11 @@ export function useEditModeCommands() { hook: useManipulateDocumentCommands, } ); + useCommandLoader( { + name: 'core/edit-site/patterns', + hook: usePatternCommands, + } ); + useCommandLoader( { name: 'core/edit-site/edit-ui', hook: useEditUICommands, diff --git a/packages/patterns/src/components/rename-pattern-modal.js b/packages/patterns/src/components/rename-pattern-modal.js new file mode 100644 index 00000000000000..9b905c04b1e20e --- /dev/null +++ b/packages/patterns/src/components/rename-pattern-modal.js @@ -0,0 +1,115 @@ +/** + * WordPress dependencies + */ +import { + Button, + Modal, + TextControl, + __experimentalHStack as HStack, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import { store as coreStore } from '@wordpress/core-data'; +import { useDispatch } from '@wordpress/data'; +import { useState } from '@wordpress/element'; +import { decodeEntities } from '@wordpress/html-entities'; +import { __ } from '@wordpress/i18n'; +import { store as noticesStore } from '@wordpress/notices'; + +export default function RenamePatternModal( { + onClose, + onError, + onSuccess, + pattern, + ...props +} ) { + const originalName = decodeEntities( pattern.title ); + const [ name, setName ] = useState( originalName ); + const [ isSaving, setIsSaving ] = useState( false ); + + const { + editEntityRecord, + __experimentalSaveSpecifiedEntityEdits: saveSpecifiedEntityEdits, + } = useDispatch( coreStore ); + + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + + const onRename = async ( event ) => { + event.preventDefault(); + + if ( ! name || name === pattern.title || isSaving ) { + return; + } + + try { + await editEntityRecord( 'postType', pattern.type, pattern.id, { + title: name, + } ); + + setIsSaving( true ); + setName( '' ); + onClose?.(); + + const savedRecord = await saveSpecifiedEntityEdits( + 'postType', + pattern.type, + pattern.id, + [ 'title' ], + { throwOnError: true } + ); + + onSuccess?.( savedRecord ); + + createSuccessNotice( __( 'Pattern renamed' ), { + type: 'snackbar', + id: 'pattern-update', + } ); + } catch ( error ) { + onError?.(); + + const errorMessage = + error.message && error.code !== 'unknown_error' + ? error.message + : __( 'An error occurred while renaming the pattern.' ); + + createErrorNotice( errorMessage, { + type: 'snackbar', + id: 'pattern-update', + } ); + } finally { + setIsSaving( false ); + setName( '' ); + } + }; + + const onRequestClose = () => { + onClose?.(); + setName( '' ); + }; + + return ( + +
+ + + + + + + + + +
+
+ ); +} diff --git a/packages/patterns/src/private-apis.js b/packages/patterns/src/private-apis.js index cdbf1a6ba29408..3a68cea8794a54 100644 --- a/packages/patterns/src/private-apis.js +++ b/packages/patterns/src/private-apis.js @@ -3,6 +3,7 @@ */ import { lock } from './lock-unlock'; import CreatePatternModal from './components/create-pattern-modal'; +import RenamePatternModal from './components/rename-pattern-modal'; import PatternsMenuItems from './components'; import { PATTERN_TYPES, @@ -15,6 +16,7 @@ import { export const privateApis = {}; lock( privateApis, { CreatePatternModal, + RenamePatternModal, PatternsMenuItems, PATTERN_TYPES, PATTERN_DEFAULT_CATEGORY,