Skip to content

Commit

Permalink
Patterns: avoid fetching on load (#57999)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix authored Jan 24, 2024
1 parent ed46eac commit 8db42b1
Show file tree
Hide file tree
Showing 11 changed files with 721 additions and 606 deletions.
2 changes: 2 additions & 0 deletions packages/block-editor/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import reducer from './reducer';
import * as selectors from './selectors';
import * as privateActions from './private-actions';
import * as privateSelectors from './private-selectors';
import * as resolvers from './resolvers';
import * as actions from './actions';
import { STORE_NAME } from './constants';
import { unlock } from '../lock-unlock';
Expand All @@ -22,6 +23,7 @@ import { unlock } from '../lock-unlock';
export const storeConfig = {
reducer,
selectors,
resolvers,
actions,
};

Expand Down
105 changes: 80 additions & 25 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
*/
import createSelector from 'rememo';

/**
* WordPress dependencies
*/
import { createRegistrySelector } from '@wordpress/data';

/**
* Internal dependencies
*/
Expand All @@ -11,11 +16,12 @@ import {
getBlockParents,
getBlockEditingMode,
getSettings,
__experimentalGetParsedPattern,
canInsertBlockType,
__experimentalGetAllowedPatterns,
} from './selectors';
import { getAllPatterns, checkAllowListRecursive } from './utils';
import { checkAllowListRecursive, getAllPatternsDependants } from './utils';
import { INSERTER_PATTERN_TYPES } from '../components/inserter/block-patterns-tab/utils';
import { store } from './';
import { unlock } from '../lock-unlock';

/**
* Returns true if the block interface is hidden, or false otherwise.
Expand Down Expand Up @@ -242,6 +248,10 @@ export const getInserterMediaCategories = createSelector(
]
);

export function getFetchedPatterns( state ) {
return state.blockPatterns;
}

/**
* Returns whether there is at least one allowed pattern for inner blocks children.
* This is useful for deferring the parsing of all patterns until needed.
Expand All @@ -251,29 +261,74 @@ export const getInserterMediaCategories = createSelector(
*
* @return {boolean} If there is at least one allowed pattern.
*/
export const hasAllowedPatterns = createSelector(
( state, rootClientId = null ) => {
const patterns = getAllPatterns( state );
const { allowedBlockTypes } = getSettings( state );
return patterns.some( ( { name, inserter = true } ) => {
if ( ! inserter ) {
return false;
}
const { blocks } = __experimentalGetParsedPattern( state, name );
return (
checkAllowListRecursive( blocks, allowedBlockTypes ) &&
blocks.every( ( { name: blockName } ) =>
canInsertBlockType( state, blockName, rootClientId )
)
export const hasAllowedPatterns = createRegistrySelector( ( select ) =>
createSelector(
( state, rootClientId = null ) => {
const { getAllPatterns, __experimentalGetParsedPattern } = unlock(
select( store )
);
} );
},
( state, rootClientId ) => [
...__experimentalGetAllowedPatterns.getDependants(
state,
rootClientId
),
]
const patterns = getAllPatterns();
const { allowedBlockTypes } = getSettings( state );
return patterns.some( ( { name, inserter = true } ) => {
if ( ! inserter ) {
return false;
}
const { blocks } = __experimentalGetParsedPattern( name );
return (
checkAllowListRecursive( blocks, allowedBlockTypes ) &&
blocks.every( ( { name: blockName } ) =>
canInsertBlockType( state, blockName, rootClientId )
)
);
} );
},
( state, rootClientId ) => [
getAllPatternsDependants( state ),
state.settings.allowedBlockTypes,
state.settings.templateLock,
state.blockListSettings[ rootClientId ],
state.blocks.byClientId.get( rootClientId ),
]
)
);

export const getAllPatterns = createRegistrySelector( ( select ) =>
createSelector( ( state ) => {
// This setting is left for back compat.
const {
__experimentalBlockPatterns = [],
__experimentalUserPatternCategories = [],
__experimentalReusableBlocks = [],
} = state.settings;
const userPatterns = ( __experimentalReusableBlocks ?? [] ).map(
( userPattern ) => {
return {
name: `core/block/${ userPattern.id }`,
id: userPattern.id,
type: INSERTER_PATTERN_TYPES.user,
title: userPattern.title.raw,
categories: userPattern.wp_pattern_category.map(
( catId ) => {
const category = (
__experimentalUserPatternCategories ?? []
).find( ( { id } ) => id === catId );
return category ? category.slug : catId;
}
),
content: userPattern.content.raw,
syncStatus: userPattern.wp_pattern_sync_status,
};
}
);
return [
...userPatterns,
...__experimentalBlockPatterns,
...unlock( select( store ) ).getFetchedPatterns(),
].filter(
( x, index, arr ) =>
index === arr.findIndex( ( y ) => x.name === y.name )
);
}, getAllPatternsDependants )
);

/**
Expand Down
10 changes: 10 additions & 0 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2023,6 +2023,15 @@ export function lastFocus( state = false, action ) {
return state;
}

function blockPatterns( state = [], action ) {
switch ( action.type ) {
case 'RECEIVE_BLOCK_PATTERNS':
return action.patterns;
}

return state;
}

const combinedReducers = combineReducers( {
blocks,
isTyping,
Expand Down Expand Up @@ -2053,6 +2062,7 @@ const combinedReducers = combineReducers( {
blockRemovalRules,
openedBlockSettingsMenu,
registeredInserterMediaCategories,
blockPatterns,
} );

function withAutomaticChangeReset( reducer ) {
Expand Down
17 changes: 17 additions & 0 deletions packages/block-editor/src/store/resolvers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const getFetchedPatterns =
() =>
async ( { dispatch, select } ) => {
const { __experimentalFetchBlockPatterns } = select.getSettings();
if ( ! __experimentalFetchBlockPatterns ) {
return [];
}
const patterns = await __experimentalFetchBlockPatterns();
dispatch( { type: 'RECEIVE_BLOCK_PATTERNS', patterns } );
};

getFetchedPatterns.shouldInvalidate = ( action ) => {
return (
action.type === 'UPDATE_SETTINGS' &&
!! action.settings.__experimentalFetchBlockPatterns
);
};
Loading

1 comment on commit 8db42b1

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 8db42b1.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/7639648823
📝 Reported issues:

Please sign in to comment.