Skip to content

Commit

Permalink
[Block Library - Query Loop]: Improve pattern setup and replace flow
Browse files Browse the repository at this point in the history
  • Loading branch information
ntsekouras committed Aug 16, 2022
1 parent fc0e1fe commit 564266c
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 18 deletions.
20 changes: 11 additions & 9 deletions packages/block-library/src/query/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { store as blocksStore, cloneBlock } from '@wordpress/blocks';
import { store as blocksStore } from '@wordpress/blocks';
import { useInstanceId } from '@wordpress/compose';
import { useState, useEffect } from '@wordpress/element';
import {
Expand Down Expand Up @@ -30,7 +30,7 @@ import QueryToolbar from './query-toolbar';
import QueryInspectorControls from './inspector-controls';
import QueryPlaceholder from './query-placeholder';
import { DEFAULTS_POSTS_PER_PAGE } from '../constants';
import { getFirstQueryClientIdFromBlocks } from '../utils';
import { getTransformedBlocksFromPattern } from '../utils';

const TEMPLATE = [ [ 'core/post-template' ] ];
export function QueryContent( {
Expand Down Expand Up @@ -177,6 +177,7 @@ function QueryPatternSetup( {
<QueryPlaceholder
clientId={ clientId }
name={ name }
attributes={ attributes }
setAttributes={ setAttributes }
icon={ icon }
label={ label }
Expand Down Expand Up @@ -215,7 +216,7 @@ function QueryPatternSetup( {
}

const QueryEdit = ( props ) => {
const { clientId, name } = props;
const { clientId, name, attributes } = props;
const [ isPatternSelectionModalOpen, setIsPatternSelectionModalOpen ] =
useState( false );
const { replaceBlock, selectBlock } = useDispatch( blockEditorStore );
Expand All @@ -226,12 +227,13 @@ const QueryEdit = ( props ) => {
);
const Component = hasInnerBlocks ? QueryContent : QueryPatternSetup;
const onBlockPatternSelect = ( blocks ) => {
const clonedBlocks = blocks.map( ( block ) => cloneBlock( block ) );
const firstQueryClientId =
getFirstQueryClientIdFromBlocks( clonedBlocks );
replaceBlock( clientId, clonedBlocks );
if ( firstQueryClientId ) {
selectBlock( firstQueryClientId );
const { newBlocks, queryClientIds } = getTransformedBlocksFromPattern(
blocks,
attributes
);
replaceBlock( clientId, newBlocks );
if ( queryClientIds[ 0 ] ) {
selectBlock( queryClientIds[ 0 ] );
}
};
return (
Expand Down
19 changes: 17 additions & 2 deletions packages/block-library/src/query/edit/query-placeholder.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ import {
store as blocksStore,
} from '@wordpress/blocks';

function QueryPlaceholder( { clientId, name, setAttributes, icon, label } ) {
function QueryPlaceholder( {
clientId,
name,
attributes,
setAttributes,
icon,
label,
} ) {
const { defaultVariation, scopeVariations } = useSelect(
( select ) => {
const {
Expand All @@ -39,7 +46,15 @@ function QueryPlaceholder( { clientId, name, setAttributes, icon, label } ) {
variations={ scopeVariations }
onSelect={ ( nextVariation = defaultVariation ) => {
if ( nextVariation.attributes ) {
setAttributes( nextVariation.attributes );
setAttributes( {
...nextVariation.attributes,
query: {
...nextVariation.attributes.query,
postType:
attributes.query.postType ||
nextVariation.attributes.query.postType,
},
} );
}
if ( nextVariation.innerBlocks ) {
replaceInnerBlocks(
Expand Down
42 changes: 35 additions & 7 deletions packages/block-library/src/query/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import { useSelect } from '@wordpress/data';
import { useMemo } from '@wordpress/element';
import { store as coreStore } from '@wordpress/core-data';
import { decodeEntities } from '@wordpress/html-entities';
import { cloneBlock } from '@wordpress/blocks';

/**
* @typedef TransformedBlocksFromPattern
* @property {WPBlock[]} newBlocks The cloned/transformed blocks.
* @property {string[]} queryClientIds All the Query Loop clients from `newBlocks`.
*/

/**
* @typedef IHasNameAndId
Expand Down Expand Up @@ -127,21 +134,42 @@ export const useTaxonomies = ( postType ) => {
};

/**
* Recurses over a list of blocks and returns the first found
* Query Loop block's clientId.
* Clones a pattern's blocks and then recurses over that list of blocks,
* transforming them to retain some `query` attribute properties.
* For now we retain the `postType` and `inherit` properties as they are
* fundamental for the expected functionality of the block and don't affect
* its design and presentation.
*
* Returns the cloned/transformed blocks and array of existing Query Loop
* client ids for further manipulation, in order to avoid multiple recursions.
*
* @param {WPBlock[]} blocks The list of blocks to look through.
* @return {string=} The first found Query Loop's clientId.
* @param {WPBlock[]} blocks The list of blocks to look through and transform(mutate).
* @param {Record<string,*>} queryBlockAttributes The existing Query Loop's attributes.
* @return {TransformedBlocksFromPattern} The first found Query Loop's clientId.
*/
export const getFirstQueryClientIdFromBlocks = ( blocks ) => {
const blocksQueue = [ ...blocks ];
export const getTransformedBlocksFromPattern = (
blocks,
queryBlockAttributes
) => {
const {
query: { postType, inherit },
} = queryBlockAttributes;
const clonedBlocks = blocks.map( ( block ) => cloneBlock( block ) );
const queryClientIds = [];
const blocksQueue = [ ...clonedBlocks ];
while ( blocksQueue.length > 0 ) {
const block = blocksQueue.shift();
if ( block.name === 'core/query' ) {
return block.clientId;
block.attributes.query = {
...block.attributes.query,
postType,
inherit,
};
queryClientIds.push( block.clientId );
}
block.innerBlocks?.forEach( ( innerBlock ) => {
blocksQueue.push( innerBlock );
} );
}
return { newBlocks: clonedBlocks, queryClientIds };
};

0 comments on commit 564266c

Please sign in to comment.