diff --git a/package-lock.json b/package-lock.json
index de73f17229c637..81b3bbec540f92 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9859,6 +9859,7 @@
"@wordpress/compose": "file:packages/compose",
"@wordpress/data": "file:packages/data",
"@wordpress/data-controls": "file:packages/data-controls",
+ "@wordpress/edit-post": "file:packages/edit-post",
"@wordpress/element": "file:packages/element",
"@wordpress/i18n": "file:packages/i18n",
"@wordpress/icons": "file:packages/icons",
diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json
index d36ed1b6de3e40..0bb35a3cda8e51 100644
--- a/packages/block-directory/package.json
+++ b/packages/block-directory/package.json
@@ -32,6 +32,7 @@
"@wordpress/compose": "file:../compose",
"@wordpress/data": "file:../data",
"@wordpress/data-controls": "file:../data-controls",
+ "@wordpress/edit-post": "file:../edit-post",
"@wordpress/element": "file:../element",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
diff --git a/packages/block-directory/src/components/compact-list/index.js b/packages/block-directory/src/components/compact-list/index.js
new file mode 100644
index 00000000000000..e3ef3b2ba797d1
--- /dev/null
+++ b/packages/block-directory/src/components/compact-list/index.js
@@ -0,0 +1,38 @@
+/**
+ * WordPress dependencies
+ */
+import { __, sprintf } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies
+ */
+import DownloadableBlockIcon from '../downloadable-block-icon';
+
+export default function CompactList( { items } ) {
+ if ( ! items.length ) {
+ return null;
+ }
+
+ return (
+
+ { items.map( ( { icon, id, title, author } ) => (
+ -
+
+
+
+
+ { title }
+
+
+ { sprintf(
+ /* translators: %s: Name of the block author. */
+ __( 'By %s' ),
+ author
+ ) }
+
+
+
+ ) ) }
+
+ );
+}
diff --git a/packages/block-directory/src/components/compact-list/style.scss b/packages/block-directory/src/components/compact-list/style.scss
new file mode 100644
index 00000000000000..4d017604af009a
--- /dev/null
+++ b/packages/block-directory/src/components/compact-list/style.scss
@@ -0,0 +1,28 @@
+.block-directory-compact-list {
+ margin: 0;
+ list-style: none;
+}
+
+.block-directory-compact-list__item {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin-bottom: $grid-unit-20;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.block-directory-compact-list__item-details {
+ margin-left: $grid-unit-10;
+}
+
+.block-directory-compact-list__item-title {
+ font-weight: 500;
+}
+
+.block-directory-compact-list__item-author {
+ color: $dark-gray-500;
+ font-size: 11px;
+}
diff --git a/packages/block-directory/src/components/downloadable-block-header/index.js b/packages/block-directory/src/components/downloadable-block-header/index.js
index a99220f729bf94..b392eda099f190 100644
--- a/packages/block-directory/src/components/downloadable-block-header/index.js
+++ b/packages/block-directory/src/components/downloadable-block-header/index.js
@@ -1,15 +1,15 @@
/**
* WordPress dependencies
*/
-import { __, sprintf } from '@wordpress/i18n';
+import { __ } from '@wordpress/i18n';
import { Button } from '@wordpress/components';
import { withSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
-import { BlockIcon } from '@wordpress/block-editor';
import BlockRatings from '../block-ratings';
+import DownloadableBlockIcon from '../downloadable-block-icon';
export function DownloadableBlockHeader( {
icon,
@@ -21,20 +21,7 @@ export function DownloadableBlockHeader( {
} ) {
return (
- { icon.match( /\.(jpeg|jpg|gif|png)(?:\?.*)?$/ ) !== null ? (
-
- ) : (
-
-
-
- ) }
+
diff --git a/packages/block-directory/src/components/downloadable-block-header/style.scss b/packages/block-directory/src/components/downloadable-block-header/style.scss
index e073ef1c5472a2..37fe76f2183195 100644
--- a/packages/block-directory/src/components/downloadable-block-header/style.scss
+++ b/packages/block-directory/src/components/downloadable-block-header/style.scss
@@ -2,18 +2,6 @@
display: flex;
flex-grow: 1;
- .block-editor-block-icon {
- width: $button-size;
- height: $button-size;
- font-size: $button-size;
- background-color: $light-gray-300;
- }
-
- img {
- width: $button-size;
- height: $button-size;
- }
-
.block-directory-downloadable-block-header__column {
display: flex;
flex-direction: column;
diff --git a/packages/block-directory/src/components/downloadable-block-header/test/fixtures/index.js b/packages/block-directory/src/components/downloadable-block-header/test/fixtures/index.js
index db09e7df68d30a..5c3f6cc9f234ab 100644
--- a/packages/block-directory/src/components/downloadable-block-header/test/fixtures/index.js
+++ b/packages/block-directory/src/components/downloadable-block-header/test/fixtures/index.js
@@ -18,7 +18,3 @@ const pluginBase = {
};
export const pluginWithIcon = { ...pluginBase, icon: 'block-default' };
-export const pluginWithImg = {
- ...pluginBase,
- icon: 'https://ps.w.org/listicles/assets/icon-128x128.png',
-};
diff --git a/packages/block-directory/src/components/downloadable-block-header/test/index.js b/packages/block-directory/src/components/downloadable-block-header/test/index.js
index 3bc26f312e9bc5..e23db4dfe84169 100644
--- a/packages/block-directory/src/components/downloadable-block-header/test/index.js
+++ b/packages/block-directory/src/components/downloadable-block-header/test/index.js
@@ -6,14 +6,13 @@ import { shallow } from 'enzyme';
/**
* WordPress dependencies
*/
-import { BlockIcon } from '@wordpress/block-editor';
import { Button } from '@wordpress/components';
/**
* Internal dependencies
*/
import { DownloadableBlockHeader } from '../index';
-import { pluginWithImg, pluginWithIcon } from './fixtures';
+import { pluginWithIcon } from './fixtures';
const getContainer = (
{ icon, title, rating, ratingCount },
@@ -33,30 +32,6 @@ const getContainer = (
};
describe( 'DownloadableBlockHeader', () => {
- describe( 'icon rendering', () => {
- test( 'should render an tag', () => {
- const wrapper = getContainer( pluginWithImg );
- expect( wrapper.find( 'img' ).prop( 'src' ) ).toEqual(
- pluginWithImg.icon
- );
- } );
-
- test( 'should render an tag if icon URL has query string', () => {
- const iconURLwithQueryString =
- pluginWithImg.icon + '?rev=2011672&test=234234';
- const plugin = { ...pluginWithImg, icon: iconURLwithQueryString };
- const wrapper = getContainer( plugin );
- expect( wrapper.find( 'img' ).prop( 'src' ) ).toEqual(
- plugin.icon
- );
- } );
-
- test( 'should render a component', () => {
- const wrapper = getContainer( pluginWithIcon );
- expect( wrapper.find( BlockIcon ) ).toHaveLength( 1 );
- } );
- } );
-
describe( 'user interaction', () => {
test( 'should trigger the onClick function', () => {
const onClickMock = jest.fn();
diff --git a/packages/block-directory/src/components/downloadable-block-icon/index.js b/packages/block-directory/src/components/downloadable-block-icon/index.js
new file mode 100644
index 00000000000000..e2ca57c735977d
--- /dev/null
+++ b/packages/block-directory/src/components/downloadable-block-icon/index.js
@@ -0,0 +1,26 @@
+/**
+ * WordPress dependencies
+ */
+import { __, sprintf } from '@wordpress/i18n';
+import { BlockIcon } from '@wordpress/block-editor';
+
+function DownloadableBlockIcon( { icon, title } ) {
+ return (
+
+ { icon.match( /\.(jpeg|jpg|gif|png)(?:\?.*)?$/ ) !== null ? (
+
+ ) : (
+
+ ) }
+
+ );
+}
+
+export default DownloadableBlockIcon;
diff --git a/packages/block-directory/src/components/downloadable-block-icon/style.scss b/packages/block-directory/src/components/downloadable-block-icon/style.scss
new file mode 100644
index 00000000000000..12dad759e8603b
--- /dev/null
+++ b/packages/block-directory/src/components/downloadable-block-icon/style.scss
@@ -0,0 +1,11 @@
+.block-directory-downloadable-block-icon {
+ width: $button-size;
+ height: $button-size;
+
+ .block-editor-block-icon {
+ width: $button-size;
+ height: $button-size;
+ font-size: $button-size;
+ background-color: $light-gray-300;
+ }
+}
diff --git a/packages/block-directory/src/components/downloadable-block-icon/test/__snapshots__/index.js.snap b/packages/block-directory/src/components/downloadable-block-icon/test/__snapshots__/index.js.snap
new file mode 100644
index 00000000000000..00929ab18290d1
--- /dev/null
+++ b/packages/block-directory/src/components/downloadable-block-icon/test/__snapshots__/index.js.snap
@@ -0,0 +1,34 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Downloadable Block Icon icon rendering should render a component 1`] = `
+
+
+
+`;
+
+exports[`Downloadable Block Icon icon rendering should render an tag 1`] = `
+
+
+
+`;
+
+exports[`Downloadable Block Icon icon rendering should render an tag if icon URL has query string 1`] = `
+
+
+
+`;
diff --git a/packages/block-directory/src/components/downloadable-block-icon/test/index.js b/packages/block-directory/src/components/downloadable-block-icon/test/index.js
new file mode 100644
index 00000000000000..063f4a49fddab9
--- /dev/null
+++ b/packages/block-directory/src/components/downloadable-block-icon/test/index.js
@@ -0,0 +1,41 @@
+/**
+ * External dependencies
+ */
+import { shallow } from 'enzyme';
+
+/**
+ * Internal dependencies
+ */
+import DownloadableBlockIcon from '../index';
+
+const IMAGE_URL = 'https://ps.w.org/listicles/assets/icon-128x128.png';
+
+describe( 'Downloadable Block Icon', () => {
+ describe( 'icon rendering', () => {
+ test( 'should render an tag', () => {
+ const wrapper = shallow(
+
+ );
+ expect( wrapper ).toMatchSnapshot();
+ } );
+
+ test( 'should render an tag if icon URL has query string', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect( wrapper ).toMatchSnapshot();
+ } );
+
+ test( 'should render a component', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect( wrapper ).toMatchSnapshot();
+ } );
+ } );
+} );
diff --git a/packages/block-directory/src/plugins/index.js b/packages/block-directory/src/plugins/index.js
index 917b8567c2d87f..f1e013a8d0ddee 100644
--- a/packages/block-directory/src/plugins/index.js
+++ b/packages/block-directory/src/plugins/index.js
@@ -7,9 +7,15 @@ import { registerPlugin } from '@wordpress/plugins';
* Internal dependencies
*/
import InserterMenuDownloadableBlocksPanel from './inserter-menu-downloadable-blocks-panel';
+import InstalledBlocksPrePublishPanel from './installed-blocks-pre-publish-panel';
registerPlugin( 'block-directory', {
render() {
- return ;
+ return (
+ <>
+
+
+ >
+ );
},
} );
diff --git a/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/index.js b/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/index.js
new file mode 100644
index 00000000000000..0b32c1ee29bc62
--- /dev/null
+++ b/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/index.js
@@ -0,0 +1,46 @@
+/**
+ * WordPress dependencies
+ */
+import { _n, sprintf } from '@wordpress/i18n';
+import { PluginPrePublishPanel } from '@wordpress/edit-post';
+import { useSelect } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import CompactList from '../../components/compact-list';
+
+export default function InstalledBlocksPrePublishPanel() {
+ const newBlockTypes = useSelect( ( select ) =>
+ select( 'core/block-directory' ).getInstalledBlockTypes()
+ );
+
+ if ( ! newBlockTypes.length ) {
+ return null;
+ }
+
+ return (
+
+
+ { _n(
+ 'The following block has been added to your site.',
+ 'The following blocks have been added to your site.',
+ newBlockTypes.length
+ ) }
+
+
+
+ );
+}
diff --git a/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/style.scss b/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/style.scss
new file mode 100644
index 00000000000000..3b3e701f9ce53e
--- /dev/null
+++ b/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/style.scss
@@ -0,0 +1,3 @@
+.installed-blocks-pre-publish-panel__copy {
+ margin-top: 0;
+}
diff --git a/packages/block-directory/src/store/actions.js b/packages/block-directory/src/store/actions.js
index d5c0f7c2b9dfa2..8145ef29562798 100644
--- a/packages/block-directory/src/store/actions.js
+++ b/packages/block-directory/src/store/actions.js
@@ -53,11 +53,12 @@ export function setInstallBlocksPermission( hasPermission ) {
/**
* Action triggered to install a block plugin.
*
- * @param {Object} item The block item returned by search.
+ * @param {Object} block The block item returned by search.
*
* @return {boolean} Whether the block was successfully installed & loaded.
*/
-export function* installBlockType( { id, name, assets } ) {
+export function* installBlockType( block ) {
+ const { id, assets } = block;
let success = false;
yield clearErrorNotice( id );
try {
@@ -68,14 +69,14 @@ export function* installBlockType( { id, name, assets } ) {
const response = yield apiFetch( {
path: '__experimental/block-directory/install',
data: {
- slug: id,
+ slug: block.id,
},
method: 'POST',
} );
if ( response.success !== true ) {
throw new Error( __( 'Unable to install this block.' ) );
}
- yield addInstalledBlockType( { id, name } );
+ yield addInstalledBlockType( block );
yield loadAssets( assets );
const registeredBlocks = yield select( 'core/blocks', 'getBlockTypes' );
diff --git a/packages/block-directory/src/store/test/actions.js b/packages/block-directory/src/store/test/actions.js
index ce5f5c1eae2811..dc2789d955f6f7 100644
--- a/packages/block-directory/src/store/test/actions.js
+++ b/packages/block-directory/src/store/test/actions.js
@@ -31,10 +31,7 @@ describe( 'actions', () => {
expect( generator.next( { success: true } ).value ).toEqual( {
type: 'ADD_INSTALLED_BLOCK_TYPE',
- item: {
- id: item.id,
- name: item.name,
- },
+ item,
} );
expect( generator.next().value ).toEqual( {
diff --git a/packages/block-directory/src/style.scss b/packages/block-directory/src/style.scss
index e0286f8fc42ae0..82cc67442872a4 100644
--- a/packages/block-directory/src/style.scss
+++ b/packages/block-directory/src/style.scss
@@ -1,8 +1,11 @@
+@import "./components/block-ratings/style.scss";
+@import "./components/compact-list/style.scss";
+@import "./components/downloadable-block-author-info/style.scss";
@import "./components/downloadable-block-header/style.scss";
+@import "./components/downloadable-block-icon/style.scss";
@import "./components/downloadable-block-info/style.scss";
-@import "./components/downloadable-block-author-info/style.scss";
@import "./components/downloadable-block-list-item/style.scss";
+@import "./components/downloadable-block-notice/style.scss";
@import "./components/downloadable-blocks-list/style.scss";
@import "./components/downloadable-blocks-panel/style.scss";
-@import "./components/block-ratings/style.scss";
-@import "./components/downloadable-block-notice/style.scss";
+@import "./plugins/installed-blocks-pre-publish-panel/style.scss";