Skip to content

Commit

Permalink
Thunkify reusable-blocks store (#35217)
Browse files Browse the repository at this point in the history
* Migrate reusable-blocks store to thunks

* Remove unnecessary request handler mocks

* Remove jest.useRealTimers() and add a comment to explain the addEntities() call

* Update test snapshots
  • Loading branch information
adamziel committed Oct 8, 2021
1 parent 23f943b commit 17e3641
Show file tree
Hide file tree
Showing 6 changed files with 400 additions and 378 deletions.
102 changes: 88 additions & 14 deletions packages/reusable-blocks/src/store/actions.js
@@ -1,39 +1,113 @@
/**
* Internal dependencies
* External dependencies
*/
import { isFunction } from 'lodash';

/**
* WordPress dependencies
*/
import { store as blockEditorStore } from '@wordpress/block-editor';
import {
convertBlockToStatic,
convertBlocksToReusable,
deleteReusableBlock,
} from './controls';
createBlock,
isReusableBlock,
parse,
serialize,
} from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';

/**
* Returns a generator converting a reusable block into a static block.
*
* @param {string} clientId The client ID of the block to attach.
*/
export function* __experimentalConvertBlockToStatic( clientId ) {
yield convertBlockToStatic( clientId );
}
export const __experimentalConvertBlockToStatic = ( clientId ) => ( {
registry,
} ) => {
const oldBlock = registry.select( blockEditorStore ).getBlock( clientId );
const reusableBlock = registry
.select( 'core' )
.getEditedEntityRecord(
'postType',
'wp_block',
oldBlock.attributes.ref
);

const newBlocks = parse(
isFunction( reusableBlock.content )
? reusableBlock.content( reusableBlock )
: reusableBlock.content
);
registry
.dispatch( blockEditorStore )
.replaceBlocks( oldBlock.clientId, newBlocks );
};

/**
* Returns a generator converting one or more static blocks into a reusable block.
*
* @param {string[]} clientIds The client IDs of the block to detach.
* @param {string} title Reusable block title.
*/
export function* __experimentalConvertBlocksToReusable( clientIds, title ) {
yield convertBlocksToReusable( clientIds, title );
}
export const __experimentalConvertBlocksToReusable = (
clientIds,
title
) => async ( { registry, dispatch } ) => {
const reusableBlock = {
title: title || __( 'Untitled Reusable block' ),
content: serialize(
registry.select( blockEditorStore ).getBlocksByClientId( clientIds )
),
status: 'publish',
};

const updatedRecord = await registry
.dispatch( 'core' )
.saveEntityRecord( 'postType', 'wp_block', reusableBlock );

const newBlock = createBlock( 'core/block', {
ref: updatedRecord.id,
} );
registry.dispatch( blockEditorStore ).replaceBlocks( clientIds, newBlock );
dispatch.__experimentalSetEditingReusableBlock( newBlock.clientId, true );
};

/**
* Returns a generator deleting a reusable block.
*
* @param {string} id The ID of the reusable block to delete.
*/
export function* __experimentalDeleteReusableBlock( id ) {
yield deleteReusableBlock( id );
}
export const __experimentalDeleteReusableBlock = ( id ) => async ( {
registry,
} ) => {
const reusableBlock = registry
.select( 'core' )
.getEditedEntityRecord( 'postType', 'wp_block', id );

// Don't allow a reusable block with a temporary ID to be deleted
if ( ! reusableBlock ) {
return;
}

// Remove any other blocks that reference this reusable block
const allBlocks = registry.select( blockEditorStore ).getBlocks();
const associatedBlocks = allBlocks.filter(
( block ) => isReusableBlock( block ) && block.attributes.ref === id
);
const associatedBlockClientIds = associatedBlocks.map(
( block ) => block.clientId
);

// Remove the parsed block.
if ( associatedBlockClientIds.length ) {
registry
.dispatch( blockEditorStore )
.removeBlocks( associatedBlockClientIds );
}

await registry
.dispatch( 'core' )
.deleteEntityRecord( 'postType', 'wp_block', id );
};

/**
* Returns an action descriptor for SET_EDITING_REUSABLE_BLOCK action.
Expand Down
160 changes: 0 additions & 160 deletions packages/reusable-blocks/src/store/controls.js

This file was deleted.

3 changes: 1 addition & 2 deletions packages/reusable-blocks/src/store/index.js
Expand Up @@ -7,7 +7,6 @@ import { createReduxStore, register } from '@wordpress/data';
* Internal dependencies
*/
import * as actions from './actions';
import controls from './controls';
import reducer from './reducer';
import * as selectors from './selectors';

Expand All @@ -22,9 +21,9 @@ const STORE_NAME = 'core/reusable-blocks';
*/
export const store = createReduxStore( STORE_NAME, {
actions,
controls,
reducer,
selectors,
__experimentalUseThunks: true,
} );

register( store );
@@ -0,0 +1,50 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Actions __experimentalConvertBlockToStatic should convert a static reusable into a static block 1`] = `
Array [
Object {
"attributes": Object {
"name": "Big Bird",
},
"innerBlocks": Array [
Object {
"attributes": Object {
"name": "Oscar the Grouch",
},
"innerBlocks": Array [],
"isValid": true,
"name": "core/test-block",
"originalContent": "",
"validationIssues": Array [],
},
Object {
"attributes": Object {
"name": "Cookie Monster",
},
"innerBlocks": Array [],
"isValid": true,
"name": "core/test-block",
"originalContent": "",
"validationIssues": Array [],
},
],
"isValid": true,
"name": "core/test-block",
"originalContent": "",
"validationIssues": Array [],
},
]
`;

exports[`Actions __experimentalConvertBlocksToReusable should convert a static block into a reusable block 1`] = `
Array [
Object {
"attributes": Object {
"ref": "new-id",
},
"innerBlocks": Array [],
"isValid": true,
"name": "core/block",
},
]
`;

0 comments on commit 17e3641

Please sign in to comment.