Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Directory: Fix installations for 'template-locked' mode #69394

Merged
merged 4 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

Loading