Skip to content

Commit

Permalink
block-directory: migrate store to thunks
Browse files Browse the repository at this point in the history
  • Loading branch information
jsnajdr authored and adamziel committed Sep 22, 2021
1 parent 42e3cb9 commit f2a0b6c
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 371 deletions.
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/block-directory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"@wordpress/compose": "file:../compose",
"@wordpress/core-data": "file:../core-data",
"@wordpress/data": "file:../data",
"@wordpress/data-controls": "file:../data-controls",
"@wordpress/edit-post": "file:../edit-post",
"@wordpress/editor": "file:../editor",
"@wordpress/element": "file:../element",
Expand Down
82 changes: 37 additions & 45 deletions packages/block-directory/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
*/
import { store as blocksStore } from '@wordpress/blocks';
import { __, sprintf } from '@wordpress/i18n';
import { controls } from '@wordpress/data';
import { apiFetch } from '@wordpress/data-controls';
import apiFetch from '@wordpress/api-fetch';
import { store as noticesStore } from '@wordpress/notices';

/**
* Internal dependencies
*/
import { loadAssets } from './controls';
import { loadAssets } from './load-assets';
import getPluginUrl from './utils/get-plugin-url';

/**
Expand Down Expand Up @@ -49,56 +48,49 @@ export function receiveDownloadableBlocks( downloadableBlocks, filterValue ) {
*
* @return {boolean} Whether the block was successfully installed & loaded.
*/
export function* installBlockType( block ) {
export const installBlockType = ( block ) => async ( {
registry,
dispatch,
} ) => {
const { id } = block;
let success = false;
yield clearErrorNotice( id );
dispatch.clearErrorNotice( id );
try {
yield setIsInstalling( id, true );
dispatch.setIsInstalling( id, true );

// If we have a wp:plugin link, the plugin is installed but inactive.
const url = getPluginUrl( block );
let links = {};
if ( url ) {
yield apiFetch( {
url,
data: {
status: 'active',
},
await apiFetch( {
method: 'PUT',
url,
data: { status: 'active' },
} );
} else {
const response = yield apiFetch( {
path: 'wp/v2/plugins',
data: {
slug: id,
status: 'active',
},
const response = await apiFetch( {
method: 'POST',
path: 'wp/v2/plugins',
data: { slug: id, status: 'active' },
} );
// Add the `self` link for newly-installed blocks.
links = response._links;
}

yield addInstalledBlockType( {
dispatch.addInstalledBlockType( {
...block,
links: { ...block.links, ...links },
} );

yield loadAssets();
const registeredBlocks = yield controls.select(
blocksStore,
'getBlockTypes'
);
await loadAssets();
const registeredBlocks = registry.select( blocksStore ).getBlockTypes();
if ( ! registeredBlocks.some( ( i ) => i.name === block.name ) ) {
throw new Error(
__( 'Error registering block. Try reloading the page.' )
);
}

yield controls.dispatch(
noticesStore,
'createInfoNotice',
registry.dispatch( noticesStore ).createInfoNotice(
sprintf(
// translators: %s is the block title.
__( 'Block %s installed and added.' ),
Expand Down Expand Up @@ -131,43 +123,43 @@ export function* installBlockType( block ) {
message = fatalAPIErrors[ error.code ];
}

yield setErrorNotice( id, message, isFatal );
yield controls.dispatch( noticesStore, 'createErrorNotice', message, {
dispatch.setErrorNotice( id, message, isFatal );
registry.dispatch( noticesStore ).createErrorNotice( message, {
speak: true,
isDismissible: true,
} );
}
yield setIsInstalling( id, false );
dispatch.setIsInstalling( id, false );
return success;
}
};

/**
* Action triggered to uninstall a block plugin.
*
* @param {Object} block The blockType object.
*/
export function* uninstallBlockType( block ) {
export const uninstallBlockType = ( block ) => async ( {
registry,
dispatch,
} ) => {
try {
yield apiFetch( {
url: getPluginUrl( block ),
data: {
status: 'inactive',
},
const url = getPluginUrl( block );
await apiFetch( {
method: 'PUT',
url,
data: { status: 'inactive' },
} );
yield apiFetch( {
url: getPluginUrl( block ),
await apiFetch( {
method: 'DELETE',
url,
} );
yield removeInstalledBlockType( block );
dispatch.removeInstalledBlockType( block );
} catch ( error ) {
yield controls.dispatch(
noticesStore,
'createErrorNotice',
error.message || __( 'An error occurred.' )
);
registry
.dispatch( noticesStore )
.createErrorNotice( error.message || __( 'An error occurred.' ) );
}
}
};

/**
* Returns an action object used to add a block type to the "newly installed"
Expand Down
6 changes: 2 additions & 4 deletions packages/block-directory/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@
* WordPress dependencies
*/
import { createReduxStore, register } from '@wordpress/data';
import { controls as dataControls } from '@wordpress/data-controls';

/**
* Internal dependencies
*/
import reducer from './reducer';
import * as selectors from './selectors';
import * as actions from './actions';
import resolvers from './resolvers';
import controls from './controls';
import * as resolvers from './resolvers';

/**
* Module Constants
Expand All @@ -29,8 +27,8 @@ export const storeConfig = {
reducer,
selectors,
actions,
controls: { ...dataControls, ...controls },
resolvers,
__experimentalUseThunks: true,
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,47 +49,33 @@ export const loadAsset = ( el ) => {

/**
* Load the asset files for a block
*
* @return {Object} Control descriptor.
*/
export function loadAssets() {
return {
type: 'LOAD_ASSETS',
};
}

const controls = {
async LOAD_ASSETS() {
/*
* Fetch the current URL (post-new.php, or post.php?post=1&action=edit) and compare the
* JavaScript and CSS assets loaded between the pages. This imports the required assets
* for the block into the current page while not requiring that we know them up-front.
* In the future this can be improved by reliance upon block.json and/or a script-loader
* dependency API.
*/
const response = await apiFetch( {
url: document.location.href,
parse: false,
} );

const data = await response.text();
export async function loadAssets() {
/*
* Fetch the current URL (post-new.php, or post.php?post=1&action=edit) and compare the
* JavaScript and CSS assets loaded between the pages. This imports the required assets
* for the block into the current page while not requiring that we know them up-front.
* In the future this can be improved by reliance upon block.json and/or a script-loader
* dependency API.
*/
const response = await apiFetch( {
url: document.location.href,
parse: false,
} );

const doc = new window.DOMParser().parseFromString( data, 'text/html' );
const data = await response.text();

const newAssets = Array.from(
doc.querySelectorAll( 'link[rel="stylesheet"],script' )
).filter(
( asset ) => asset.id && ! document.getElementById( asset.id )
);
const doc = new window.DOMParser().parseFromString( data, 'text/html' );

/*
* Load each asset in order, as they may depend upon an earlier loaded script.
* Stylesheets and Inline Scripts will resolve immediately upon insertion.
*/
for ( const newAsset of newAssets ) {
await loadAsset( newAsset );
}
},
};
const newAssets = Array.from(
doc.querySelectorAll( 'link[rel="stylesheet"],script' )
).filter( ( asset ) => asset.id && ! document.getElementById( asset.id ) );

export default controls;
/*
* Load each asset in order, as they may depend upon an earlier loaded script.
* Stylesheets and Inline Scripts will resolve immediately upon insertion.
*/
for ( const newAsset of newAssets ) {
await loadAsset( newAsset );
}
}
36 changes: 17 additions & 19 deletions packages/block-directory/src/store/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,29 @@ import { camelCase, mapKeys } from 'lodash';
/**
* WordPress dependencies
*/
import { apiFetch } from '@wordpress/data-controls';
import apiFetch from '@wordpress/api-fetch';

/**
* Internal dependencies
*/
import { fetchDownloadableBlocks, receiveDownloadableBlocks } from './actions';

export default {
*getDownloadableBlocks( filterValue ) {
if ( ! filterValue ) {
return;
}
export const getDownloadableBlocks = ( filterValue ) => async ( {
dispatch,
} ) => {
if ( ! filterValue ) {
return;
}

try {
yield fetchDownloadableBlocks( filterValue );
const results = yield apiFetch( {
path: `wp/v2/block-directory/search?term=${ filterValue }`,
} );
const blocks = results.map( ( result ) =>
mapKeys( result, ( value, key ) => {
return camelCase( key );
} )
);
try {
dispatch( fetchDownloadableBlocks( filterValue ) );
const results = await apiFetch( {
path: `wp/v2/block-directory/search?term=${ filterValue }`,
} );
const blocks = results.map( ( result ) =>
mapKeys( result, ( value, key ) => camelCase( key ) )
);

yield receiveDownloadableBlocks( blocks, filterValue );
} catch ( error ) {}
},
dispatch( receiveDownloadableBlocks( blocks, filterValue ) );
} catch {}
};
Loading

0 comments on commit f2a0b6c

Please sign in to comment.