Skip to content

Commit

Permalink
Patterns: Add rename command (#55188)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Oct 12, 2023
1 parent 7f538ed commit 7a187fb
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 2 deletions.
2 changes: 2 additions & 0 deletions packages/edit-site/src/components/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -220,6 +221,7 @@ export default function Editor( { listViewToggleElement, isLoading } ) {
<BlockRemovalWarningModal
rules={ blockRemovalRules }
/>
<PatternModal />
</>
) }
{ editorMode === 'text' &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions packages/edit-site/src/components/pattern-modal/index.js
Original file line number Diff line number Diff line change
@@ -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 <PatternRenameModal />;
}
29 changes: 29 additions & 0 deletions packages/edit-site/src/components/pattern-modal/rename.js
Original file line number Diff line number Diff line change
@@ -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 <RenamePatternModal onClose={ closeModal } pattern={ pattern } />;
}
32 changes: 32 additions & 0 deletions packages/edit-site/src/hooks/commands/use-edit-mode-commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
code,
keyboard,
listView,
symbol,
} from '@wordpress/icons';
import { useCommandLoader } from '@wordpress/commands';
import { decodeEntities } from '@wordpress/html-entities';
Expand All @@ -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';

Expand Down Expand Up @@ -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',
Expand All @@ -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,
Expand Down
115 changes: 115 additions & 0 deletions packages/patterns/src/components/rename-pattern-modal.js
Original file line number Diff line number Diff line change
@@ -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 (
<Modal title={ __( 'Rename' ) } { ...props } onRequestClose={ onClose }>
<form onSubmit={ onRename }>
<VStack spacing="5">
<TextControl
__nextHasNoMarginBottom
label={ __( 'Name' ) }
value={ name }
onChange={ setName }
required
/>

<HStack justify="right">
<Button variant="tertiary" onClick={ onRequestClose }>
{ __( 'Cancel' ) }
</Button>

<Button variant="primary" type="submit">
{ __( 'Save' ) }
</Button>
</HStack>
</VStack>
</form>
</Modal>
);
}
2 changes: 2 additions & 0 deletions packages/patterns/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -15,6 +16,7 @@ import {
export const privateApis = {};
lock( privateApis, {
CreatePatternModal,
RenamePatternModal,
PatternsMenuItems,
PATTERN_TYPES,
PATTERN_DEFAULT_CATEGORY,
Expand Down

0 comments on commit 7a187fb

Please sign in to comment.