Skip to content

Commit

Permalink
Block Directory: Fix installations for 'template-locked' mode (#69394)
Browse files Browse the repository at this point in the history
* Use stable reference fallback for getDownloadableBlocks
* Do nothing when there are no installed block types
* Update block directory selectors
* Remove unused utility method and tests

Co-authored-by: Mamaduka <[email protected]>
Co-authored-by: t-hamano <[email protected]>
Co-authored-by: karthikeya-io <[email protected]>
  • Loading branch information
4 people authored and gutenbergplugin committed Mar 5, 2025
1 parent f4039e8 commit 68b1105
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 84 deletions.
57 changes: 44 additions & 13 deletions packages/block-directory/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
import { createSelector, createRegistrySelector } from '@wordpress/data';
import { store as blockEditorStore } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import hasBlockType from './utils/has-block-type';
const EMPTY_ARRAY = [];

/**
* Returns true if application is requesting for downloadable blocks.
Expand All @@ -30,7 +27,7 @@ export function isRequestingDownloadableBlocks( state, filterValue ) {
* @return {Array} Downloadable blocks.
*/
export function getDownloadableBlocks( state, filterValue ) {
return state.downloadableBlocks[ filterValue ]?.results ?? [];
return state.downloadableBlocks[ filterValue ]?.results ?? EMPTY_ARRAY;
}

/**
Expand All @@ -56,16 +53,33 @@ export function getInstalledBlockTypes( state ) {
export const getNewBlockTypes = createRegistrySelector( ( select ) =>
createSelector(
( state ) => {
const usedBlockTree = select( blockEditorStore ).getBlocks();
const installedBlockTypes = getInstalledBlockTypes( state );
if ( ! installedBlockTypes.length ) {
return EMPTY_ARRAY;
}

return installedBlockTypes.filter( ( blockType ) =>
hasBlockType( blockType, usedBlockTree )
const { getBlockName, getClientIdsWithDescendants } =
select( blockEditorStore );
const installedBlockNames = installedBlockTypes.map(
( blockType ) => blockType.name
);
const foundBlockNames = getClientIdsWithDescendants().flatMap(
( clientId ) => {
const blockName = getBlockName( clientId );
return installedBlockNames.includes( blockName )
? blockName
: [];
}
);
const newBlockTypes = installedBlockTypes.filter( ( blockType ) =>
foundBlockNames.includes( blockType.name )
);

return newBlockTypes.length > 0 ? newBlockTypes : EMPTY_ARRAY;
},
( state ) => [
getInstalledBlockTypes( state ),
select( blockEditorStore ).getBlocks(),
select( blockEditorStore ).getClientIdsWithDescendants(),
]
)
);
Expand All @@ -81,16 +95,33 @@ export const getNewBlockTypes = createRegistrySelector( ( select ) =>
export const getUnusedBlockTypes = createRegistrySelector( ( select ) =>
createSelector(
( state ) => {
const usedBlockTree = select( blockEditorStore ).getBlocks();
const installedBlockTypes = getInstalledBlockTypes( state );
if ( ! installedBlockTypes.length ) {
return EMPTY_ARRAY;
}

return installedBlockTypes.filter(
( blockType ) => ! hasBlockType( blockType, usedBlockTree )
const { getBlockName, getClientIdsWithDescendants } =
select( blockEditorStore );
const installedBlockNames = installedBlockTypes.map(
( blockType ) => blockType.name
);
const foundBlockNames = getClientIdsWithDescendants().flatMap(
( clientId ) => {
const blockName = getBlockName( clientId );
return installedBlockNames.includes( blockName )
? blockName
: [];
}
);
const unusedBlockTypes = installedBlockTypes.filter(
( blockType ) => ! foundBlockNames.includes( blockType.name )
);

return unusedBlockTypes.length > 0 ? unusedBlockTypes : EMPTY_ARRAY;
},
( state ) => [
getInstalledBlockTypes( state ),
select( blockEditorStore ).getBlocks(),
select( blockEditorStore ).getClientIdsWithDescendants(),
]
)
);
Expand Down
6 changes: 6 additions & 0 deletions packages/block-directory/src/store/test/fixtures/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,9 @@ export const blockList = [
innerBlocks: [],
},
];

export const blockListIds = blockList.map( ( block ) => block.clientId );
export const blockListNameMap = blockList.reduce( ( acc, block ) => {
acc[ block.clientId ] = block.name;
return acc;
}, {} );
23 changes: 18 additions & 5 deletions packages/block-directory/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* Internal dependencies
*/
import {
blockList,
blockListIds,
blockListNameMap,
blockTypeInstalled,
blockTypeUnused,
downloadableBlock,
Expand Down Expand Up @@ -90,7 +91,10 @@ describe( 'selectors', () => {
describe( 'getNewBlockTypes', () => {
it( 'should retrieve the block types that are installed and in the post content', () => {
getNewBlockTypes.registry = {
select: jest.fn( () => ( { getBlocks: () => blockList } ) ),
select: jest.fn( () => ( {
getBlockName: ( clientId ) => blockListNameMap[ clientId ],
getClientIdsWithDescendants: () => blockListIds,
} ) ),
};
const state = {
blockManagement: {
Expand All @@ -107,7 +111,10 @@ describe( 'selectors', () => {

it( 'should return an empty array if no blocks are used', () => {
getNewBlockTypes.registry = {
select: jest.fn( () => ( { getBlocks: () => [] } ) ),
select: jest.fn( () => ( {
getBlockName: ( clientId ) => blockListNameMap[ clientId ],
getClientIdsWithDescendants: () => [],
} ) ),
};
const state = {
blockManagement: {
Expand All @@ -125,7 +132,10 @@ describe( 'selectors', () => {
describe( 'getUnusedBlockTypes', () => {
it( 'should retrieve the block types that are installed but not used', () => {
getUnusedBlockTypes.registry = {
select: jest.fn( () => ( { getBlocks: () => blockList } ) ),
select: jest.fn( () => ( {
getBlockName: ( clientId ) => blockListNameMap[ clientId ],
getClientIdsWithDescendants: () => blockListIds,
} ) ),
};
const state = {
blockManagement: {
Expand All @@ -142,7 +152,10 @@ describe( 'selectors', () => {

it( 'should return all block types if no blocks are used', () => {
getUnusedBlockTypes.registry = {
select: jest.fn( () => ( { getBlocks: () => [] } ) ),
select: jest.fn( () => ( {
getBlockName: ( clientId ) => blockListNameMap[ clientId ],
getClientIdsWithDescendants: () => [],
} ) ),
};
const state = {
blockManagement: {
Expand Down
24 changes: 0 additions & 24 deletions packages/block-directory/src/store/utils/has-block-type.js

This file was deleted.

42 changes: 0 additions & 42 deletions packages/block-directory/src/store/utils/test/has-block-type.js

This file was deleted.

0 comments on commit 68b1105

Please sign in to comment.