Skip to content

Commit

Permalink
Connect gutenberg widget screen to widget-area endpoints.
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgefilipecosta committed Apr 19, 2019
1 parent fab0281 commit 21b434e
Show file tree
Hide file tree
Showing 12 changed files with 364 additions and 20 deletions.
1 change: 1 addition & 0 deletions packages/core-data/src/entities.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const defaultEntities = [
{ name: 'postType', kind: 'root', key: 'slug', baseURL: '/wp/v2/types' },
{ name: 'media', kind: 'root', baseURL: '/wp/v2/media', plural: 'mediaItems' },
{ name: 'taxonomy', kind: 'root', key: 'slug', baseURL: '/wp/v2/taxonomies', plural: 'taxonomies' },
{ name: 'widgetArea', kind: 'root', baseURL: '/__experimental/widget-areas', plural: 'widgetAreas' },
];

export const kinds = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/compose';
import { useEffect } from '@wordpress/element';
import { withDispatch, withSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import Layout from '../layout';

function EditWidgetsInitializer( { widgetAreas, setupWidgetAreas } ) {
useEffect( () => {
if ( ! widgetAreas ) {
return;
}
console.log( widgetAreas );
setupWidgetAreas( widgetAreas );
}, [ widgetAreas, setupWidgetAreas ] );
return <Layout />;
}

export default compose( [
withSelect( ( select ) => {
const widgetAreas = select( 'core' ).getEntityRecords( 'root', 'widgetArea' );
return {
widgetAreas,
};
} ),
withDispatch( ( dispatch ) => {
const { setupWidgetAreas } = dispatch( 'core/edit-widgets' );
return {
setupWidgetAreas,
};
} ),
] )( EditWidgetsInitializer );
16 changes: 13 additions & 3 deletions packages/edit-widgets/src/components/header/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/compose';
import { Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { withDispatch } from '@wordpress/data';

function Header() {
function Header( { saveWidgetAreas } ) {
return (
<div
className="edit-widgets-header"
Expand All @@ -17,12 +19,20 @@ function Header() {
</h1>

<div className="edit-widgets-header__actions">
<Button isPrimary isLarge>
<Button isPrimary isLarge onClick={ saveWidgetAreas }>
{ __( 'Update' ) }
</Button>
</div>
</div>
);
}

export default Header;
export default compose( [
withDispatch( ( dispatch ) => {
const { saveWidgetAreas } = dispatch( 'core/edit-widgets' );
return {
saveWidgetAreas,
};
} ),
] )( Header );

23 changes: 14 additions & 9 deletions packages/edit-widgets/src/components/layout/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/compose';
import { Fragment } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { navigateRegions } from '@wordpress/components';
import { withSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -12,13 +14,7 @@ import Header from '../header';
import Sidebar from '../sidebar';
import WidgetArea from '../widget-area';

function Layout() {
const areas = [
__( 'Sidebar' ),
__( 'Footer' ),
__( 'Header' ),
];

function Layout( { areas } ) {
return (
<Fragment>
<Header />
Expand All @@ -31,12 +27,21 @@ function Layout() {
>
{ areas.map( ( area, index ) => (
<div key={ index } className="edit-widgets-layout__area">
<WidgetArea title={ area } initialOpen={ index === 0 } />
<WidgetArea area={ area } initialOpen={ index === 0 } />
</div>
) ) }
</div>
</Fragment>
);
}

export default navigateRegions( Layout );
export default compose( [
withSelect( ( select ) => {
const { getWidgetAreas } = select( 'core/edit-widgets' );
const areas = getWidgetAreas();
return {
areas,
};
} ),
navigateRegions,
] )( Layout );
27 changes: 21 additions & 6 deletions packages/edit-widgets/src/components/widget-area/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/compose';
import { Panel, PanelBody } from '@wordpress/components';
import {
BlockEditorProvider,
BlockList,
} from '@wordpress/block-editor';
import { useState } from '@wordpress/element';

function WidgetArea( { title, initialOpen } ) {
const [ blocks, updateBlocks ] = useState( [] );
import { withDispatch, withSelect } from '@wordpress/data';

function WidgetArea( { area, initialOpen, blocks, updateBlocks } ) {
return (
<Panel>
<PanelBody
title={ title }
title={ area.name }
initialOpen={ initialOpen }
>
<BlockEditorProvider
Expand All @@ -29,4 +28,20 @@ function WidgetArea( { title, initialOpen } ) {
);
}

export default WidgetArea;
export default compose( [
withSelect( ( select, { area } ) => {
const { getWidgetAreaBlocks } = select( 'core/edit-widgets' );
const blocks = getWidgetAreaBlocks( area.id );
return {
blocks,
};
} ),
withDispatch( ( dispatch, { area } ) => {
return {
updateBlocks( blocks ) {
const { updateBlocksInWidgetArea } = dispatch( 'core/edit-widgets' );
updateBlocksInWidgetArea( area.id, blocks );
},
};
} ),
] )( WidgetArea );
5 changes: 3 additions & 2 deletions packages/edit-widgets/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { registerCoreBlocks } from '@wordpress/block-library';
/**
* Internal dependencies
*/
import Layout from './components/layout';
import './store';
import EditWidgetsInitializer from './components/edit-widgets-initializer';

/**
* Initilizes the widgets screen
Expand All @@ -17,7 +18,7 @@ import Layout from './components/layout';
export function initialize( id ) {
registerCoreBlocks();
render(
<Layout />,
<EditWidgetsInitializer />,
document.getElementById( id )
);
}
62 changes: 62 additions & 0 deletions packages/edit-widgets/src/store/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* External dependencies
*/
import { map } from 'lodash';

/**
* WordPress dependencies
*/
import {
parse,
serialize,
} from '@wordpress/blocks';

/**
* Internal dependencies
*/
import { STORE_KEY } from './constants';
import {
select,
apiFetch,
} from './controls';

export function setupWidgetAreas( widgetAreas ) {
return {
type: 'SETUP_WIDGET_AREAS',
widgetAreas: map( widgetAreas, ( area ) => {
return {
...area,
blocks: parse( ( area.content && area.content.raw ) || '' ),
};
} ),
};
}

export function updateBlocksInWidgetArea( widgetAreaId, blocks ) {
return {
type: 'UPDATE_BLOCKS_IN_WIDGET_AREA',
widgetAreaId,
blocks,
};
}

export function* saveWidgetAreas() {
const widgetAreas = yield select(
STORE_KEY,
'getWidgetAreas'
);
for ( const widgetArea of widgetAreas ) {
const widgetAreaBlocks = yield select(
STORE_KEY,
'getWidgetAreaBlocks',
widgetArea.id
);
const content = serialize( widgetAreaBlocks );
const path = `/__experimental/widget-areas/${ widgetArea.id }`;
yield apiFetch( {
path,
method: 'POST',
data: { content },
} );
}
}
6 changes: 6 additions & 0 deletions packages/edit-widgets/src/store/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Constant for the store module (or reducer) key.
* @type {string}
*/
export const STORE_KEY = 'core/edit-widgets';

113 changes: 113 additions & 0 deletions packages/edit-widgets/src/store/controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* WordPress dependencies
*/
import triggerFetch from '@wordpress/api-fetch';
import { createRegistryControl } from '@wordpress/data';

/**
* Dispatches a control action for triggering an api fetch call.
*
* @param {Object} request Arguments for the fetch request.
*
* @return {Object} control descriptor.
*/
export function apiFetch( request ) {
return {
type: 'API_FETCH',
request,
};
}

/**
* Dispatches a control action for triggering a registry select.
*
* @param {string} storeKey
* @param {string} selectorName
* @param {Array} args Arguments for the select.
*
* @return {Object} control descriptor.
*/
export function select( storeKey, selectorName, ...args ) {
return {
type: 'SELECT',
storeKey,
selectorName,
args,
};
}

/**
* Dispatches a control action for triggering a registry select that has a
* resolver.
*
* @param {string} storeKey
* @param {string} selectorName
* @param {Array} args Arguments for the select.
*
* @return {Object} control descriptor.
*/
export function resolveSelect( storeKey, selectorName, ...args ) {
return {
type: 'RESOLVE_SELECT',
storeKey,
selectorName,
args,
};
}

/**
* Dispatches a control action for triggering a registry dispatch.
*
* @param {string} storeKey
* @param {string} actionName
* @param {Array} args Arguments for the dispatch action.
*
* @return {Object} control descriptor.
*/
export function dispatch( storeKey, actionName, ...args ) {
return {
type: 'DISPATCH',
storeKey,
actionName,
args,
};
}

export default {
API_FETCH( { request } ) {
return triggerFetch( request );
},
SELECT: createRegistryControl(
( registry ) => ( { storeKey, selectorName, args } ) => {
return registry.select( storeKey )[ selectorName ]( ...args );
}
),
DISPATCH: createRegistryControl(
( registry ) => ( { storeKey, actionName, args } ) => {
return registry.dispatch( storeKey )[ actionName ]( ...args );
}
),
RESOLVE_SELECT: createRegistryControl(
( registry ) => ( { storeKey, selectorName, args } ) => {
return new Promise( ( resolve ) => {
const hasFinished = () => registry.select( 'core/data' )
.hasFinishedResolution( storeKey, selectorName, args );
const getResult = () => registry.select( storeKey )[ selectorName ]
.apply( null, args );

// trigger the selector (to trigger the resolver)
const result = getResult();
if ( hasFinished() ) {
return resolve( result );
}

const unsubscribe = registry.subscribe( () => {
if ( hasFinished() ) {
unsubscribe();
resolve( getResult() );
}
} );
} );
}
),
};
Loading

0 comments on commit 21b434e

Please sign in to comment.