Skip to content

Commit

Permalink
Improve the Reusable Blocks UI by relying on multi entity save flow. (#…
Browse files Browse the repository at this point in the history
…27887)

Co-authored-by: Matías Ventura <mv@matiasventura.com>
  • Loading branch information
youknowriad and mtias committed Dec 30, 2020
1 parent 1f3d409 commit 633da16
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 492 deletions.
60 changes: 0 additions & 60 deletions packages/block-library/src/block/edit-panel/editor.scss

This file was deleted.

129 changes: 0 additions & 129 deletions packages/block-library/src/block/edit-panel/index.js

This file was deleted.

145 changes: 42 additions & 103 deletions packages/block-library/src/block/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,101 +2,76 @@
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { useEntityBlockEditor } from '@wordpress/core-data';
import { useCallback } from '@wordpress/element';
import {
useEntityBlockEditor,
useEntityProp,
store as coreStore,
} from '@wordpress/core-data';
import {
Placeholder,
Spinner,
Disabled,
ToolbarGroup,
ToolbarButton,
TextControl,
PanelBody,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import {
BlockEditorProvider,
WritingFlow,
BlockList,
__experimentalUseInnerBlocksProps as useInnerBlocksProps,
InnerBlocks,
BlockControls,
InspectorControls,
useBlockProps,
} from '@wordpress/block-editor';
import { store as noticesStore } from '@wordpress/notices';
import { store as reusableBlocksStore } from '@wordpress/reusable-blocks';

/**
* Internal dependencies
*/
import ReusableBlockEditPanel from './edit-panel';

export default function ReusableBlockEdit( {
attributes: { ref },
clientId,
isSelected,
} ) {
export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) {
const recordArgs = [ 'postType', 'wp_block', ref ];

const {
reusableBlock,
hasResolved,
isEditing,
isSaving,
canUserUpdate,
settings,
} = useSelect(
const { reusableBlock, hasResolved } = useSelect(
( select ) => ( {
reusableBlock: select( 'core' ).getEditedEntityRecord(
reusableBlock: select( coreStore ).getEditedEntityRecord(
...recordArgs
),
hasResolved: select( 'core' ).hasFinishedResolution(
hasResolved: select( coreStore ).hasFinishedResolution(
'getEditedEntityRecord',
recordArgs
),
isSaving: select( 'core' ).isSavingEntityRecord( ...recordArgs ),
canUserUpdate: select( 'core' ).canUser( 'update', 'blocks', ref ),
isEditing: select(
reusableBlocksStore
).__experimentalIsEditingReusableBlock( clientId ),
settings: select( 'core/block-editor' ).getSettings(),
} ),
[ ref, clientId ]
);

const { clearSelectedBlock } = useDispatch( 'core/block-editor' );
const { editEntityRecord, saveEditedEntityRecord } = useDispatch( 'core' );
const { __experimentalSetEditingReusableBlock } = useDispatch(
reusableBlocksStore
);
const setIsEditing = useCallback(
( value ) => {
__experimentalSetEditingReusableBlock( clientId, value );
},
[ clientId ]
);

const {
__experimentalConvertBlockToStatic: convertBlockToStatic,
} = useDispatch( reusableBlocksStore );

const { createSuccessNotice, createErrorNotice } = useDispatch(
noticesStore
);
const save = useCallback( async function () {
try {
await saveEditedEntityRecord( ...recordArgs );
createSuccessNotice( __( 'Block updated.' ), {
type: 'snackbar',
} );
} catch ( error ) {
createErrorNotice( error.message, {
type: 'snackbar',
} );
}
}, recordArgs );

const [ blocks, onInput, onChange ] = useEntityBlockEditor(
'postType',
'wp_block',
{ id: ref }
);
const [ title, setTitle ] = useEntityProp(
'postType',
'wp_block',
'title',
ref
);

const innerBlocksProps = useInnerBlocksProps(
{},
{
value: blocks,
onInput,
onChange,
renderAppender: blocks?.length
? undefined
: InnerBlocks.ButtonBlockAppender,
}
);

const blockProps = useBlockProps();

Expand All @@ -120,34 +95,6 @@ export default function ReusableBlockEdit( {
);
}

/**
* Clear the selected block when focus moves to the reusable block list.
* These blocks are in different stores and only one block should be
* selected at a time.
*/
function onFocus() {
clearSelectedBlock();
}

let element = (
<BlockEditorProvider
value={ blocks }
onInput={ onInput }
onChange={ onChange }
settings={ settings }
>
<div className="block-editor-block-list__block" onFocus={ onFocus }>
<WritingFlow>
<BlockList />
</WritingFlow>
</div>
</BlockEditorProvider>
);

if ( ! isEditing ) {
element = <Disabled>{ element }</Disabled>;
}

return (
<div { ...blockProps }>
<BlockControls>
Expand All @@ -159,25 +106,17 @@ export default function ReusableBlockEdit( {
</ToolbarButton>
</ToolbarGroup>
</BlockControls>

<div className="block-library-block__reusable-block-container">
{ ( isSelected || isEditing ) && (
<ReusableBlockEditPanel
isEditing={ isEditing }
title={ reusableBlock.title }
isSaving={ isSaving }
isEditDisabled={ ! canUserUpdate }
onEdit={ () => setIsEditing( true ) }
onChangeTitle={ ( title ) =>
editEntityRecord( ...recordArgs, { title } )
}
onSave={ () => {
save();
setIsEditing( false );
} }
<InspectorControls>
<PanelBody>
<TextControl
label={ __( 'Name' ) }
value={ title }
onChange={ setTitle }
/>
) }
{ element }
</PanelBody>
</InspectorControls>
<div className="block-library-block__reusable-block-container">
{ <div { ...innerBlocksProps } /> }
</div>
</div>
);
Expand Down
Loading

0 comments on commit 633da16

Please sign in to comment.