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

DownloadableBlocksPanel: remove withSelect in favor of useSelect #58109

Merged
merged 1 commit into from
Jan 23, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
*/
import { __ } from '@wordpress/i18n';
import { Spinner } from '@wordpress/components';
import { compose } from '@wordpress/compose';
import { store as coreStore } from '@wordpress/core-data';
import { withSelect } from '@wordpress/data';
import { useSelect } from '@wordpress/data';
import { getBlockType } from '@wordpress/blocks';

/**
Expand All @@ -18,16 +17,71 @@ import { store as blockDirectoryStore } from '../../store';

const EMPTY_ARRAY = [];

function DownloadableBlocksPanel( {
downloadableItems,
const useDownloadableBlocks = ( filterValue ) =>
useSelect(
( select ) => {
const {
getDownloadableBlocks,
isRequestingDownloadableBlocks,
getInstalledBlockTypes,
} = select( blockDirectoryStore );

const hasPermission = select( coreStore ).canUser(
'read',
'block-directory/search'
);

let downloadableBlocks = EMPTY_ARRAY;
if ( hasPermission ) {
downloadableBlocks = getDownloadableBlocks( filterValue );

// Filter out blocks that are already installed.
const installedBlockTypes = getInstalledBlockTypes();
const installableBlocks = downloadableBlocks.filter(
( { name } ) => {
// Check if the block has just been installed, in which case it
// should still show in the list to avoid suddenly disappearing.
// `installedBlockTypes` only returns blocks stored in state
// immediately after installation, not all installed blocks.
const isJustInstalled = installedBlockTypes.some(
( blockType ) => blockType.name === name
);
const isPreviouslyInstalled = getBlockType( name );
return isJustInstalled || ! isPreviouslyInstalled;
}
);

// Keep identity of the `downloadableBlocks` array if nothing was filtered out
if ( installableBlocks.length !== downloadableBlocks.length ) {
downloadableBlocks = installableBlocks;
}

// Return identical empty array when there are no blocks
if ( downloadableBlocks.length === 0 ) {
downloadableBlocks = EMPTY_ARRAY;
}
}

return {
hasPermission,
downloadableBlocks,
isLoading: isRequestingDownloadableBlocks( filterValue ),
};
},
[ filterValue ]
);

export default function DownloadableBlocksPanel( {
onSelect,
onHover,
hasLocalBlocks,
hasPermission,
isLoading,
isTyping,
filterValue,
} ) {
if ( typeof hasPermission === 'undefined' || isLoading || isTyping ) {
const { hasPermission, downloadableBlocks, isLoading } =
useDownloadableBlocks( filterValue );

if ( hasPermission === undefined || isLoading || isTyping ) {
return (
<>
{ hasPermission && ! hasLocalBlocks && (
Expand Down Expand Up @@ -55,71 +109,20 @@ function DownloadableBlocksPanel( {
return null;
}

return !! downloadableItems.length ? (
if ( downloadableBlocks.length === 0 ) {
return hasLocalBlocks ? null : <DownloadableBlocksNoResults />;
}

return (
<DownloadableBlocksInserterPanel
downloadableItems={ downloadableItems }
downloadableItems={ downloadableBlocks }
hasLocalBlocks={ hasLocalBlocks }
>
<DownloadableBlocksList
items={ downloadableItems }
items={ downloadableBlocks }
onSelect={ onSelect }
onHover={ onHover }
/>
</DownloadableBlocksInserterPanel>
) : (
! hasLocalBlocks && <DownloadableBlocksNoResults />
);
}

export default compose( [
withSelect( ( select, { filterValue } ) => {
const {
getDownloadableBlocks,
isRequestingDownloadableBlocks,
getInstalledBlockTypes,
} = select( blockDirectoryStore );

const hasPermission = select( coreStore ).canUser(
'read',
'block-directory/search'
);

function getInstallableBlocks( term ) {
const downloadableBlocks = getDownloadableBlocks( term );
const installedBlockTypes = getInstalledBlockTypes();
// Filter out blocks that are already installed.
const installableBlocks = downloadableBlocks.filter( ( block ) => {
// Check if the block has just been installed, in which case it
// should still show in the list to avoid suddenly disappearing.
// `installedBlockTypes` only returns blocks stored in state
// immediately after installation, not all installed blocks.
const isJustInstalled = !! installedBlockTypes.find(
( blockType ) => blockType.name === block.name
);
const isPreviouslyInstalled = getBlockType( block.name );
return isJustInstalled || ! isPreviouslyInstalled;
} );

if ( downloadableBlocks.length === installableBlocks.length ) {
return downloadableBlocks;
}
return installableBlocks;
}

let downloadableItems = hasPermission
? getInstallableBlocks( filterValue )
: [];

if ( downloadableItems.length === 0 ) {
downloadableItems = EMPTY_ARRAY;
}

const isLoading = isRequestingDownloadableBlocks( filterValue );

return {
downloadableItems,
hasPermission,
isLoading,
};
} ),
] )( DownloadableBlocksPanel );
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ function InserterMenuDownloadableBlocksPanel() {

return (
<__unstableInserterMenuExtension>
{ ( {
onSelect,
onHover,
filterValue,
hasItems,
rootClientId,
} ) => {
{ ( { onSelect, onHover, filterValue, hasItems } ) => {
if ( debouncedFilterValue !== filterValue ) {
debouncedSetFilterValue( filterValue );
}
Expand All @@ -35,7 +29,6 @@ function InserterMenuDownloadableBlocksPanel() {
<DownloadableBlocksPanel
onSelect={ onSelect }
onHover={ onHover }
rootClientId={ rootClientId }
Copy link
Member

Choose a reason for hiding this comment

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

Nice!

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, the prop was not used 🙂

filterValue={ debouncedFilterValue }
hasLocalBlocks={ hasItems }
isTyping={ filterValue !== debouncedFilterValue }
Expand Down
Loading