Skip to content

Commit

Permalink
Connnect gutenberg widgets screen to widget area endpoints (#15779)
Browse files Browse the repository at this point in the history
* Connect gutenberg widget screen to widget-area endpoints.

* Use saveEntityRecord.

* Enhancements

* Add test cases

* Extracted a WidgetAreas component.

* Improve the setup action to avoid the need for a parameter.

* update test case

* Refactor pass widget are by id, have a save action.

* id instead of widgetAreaId + lint fix

* Correct controls import
  • Loading branch information
jorgefilipecosta authored May 22, 2019
1 parent 27a6ead commit f1bbc00
Show file tree
Hide file tree
Showing 18 changed files with 728 additions and 29 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,27 @@
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/compose';
import { useEffect } from '@wordpress/element';
import { withDispatch } from '@wordpress/data';

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

function EditWidgetsInitializer( { setupWidgetAreas } ) {
useEffect( () => {
setupWidgetAreas();
}, [] );
return <Layout />;
}

export default compose( [
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 );

14 changes: 2 additions & 12 deletions packages/edit-widgets/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,9 @@ import { navigateRegions } from '@wordpress/components';
*/
import Header from '../header';
import Sidebar from '../sidebar';
import WidgetArea from '../widget-area';
import WidgetAreas from '../widget-areas';

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

return (
<>
<Header />
Expand All @@ -28,11 +22,7 @@ function Layout() {
aria-label={ __( 'Widgets screen content' ) }
tabIndex="-1"
>
{ areas.map( ( area, index ) => (
<div key={ index } className="edit-widgets-layout__area">
<WidgetArea title={ area } initialOpen={ index === 0 } />
</div>
) ) }
<WidgetAreas />
</div>
</>
);
Expand Down
5 changes: 0 additions & 5 deletions packages/edit-widgets/src/components/layout/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,3 @@
margin-top: $header-height;
}
}

.edit-widgets-layout__area {
max-width: $content-width;
margin: 0 auto 30px;
}
39 changes: 32 additions & 7 deletions packages/edit-widgets/src/components/widget-area/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
/**
* 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( {
blocks,
initialOpen,
updateBlocks,
widgetAreaName,
} ) {
return (
<Panel>
<Panel className="edit-widgets-widget-area">
<PanelBody
title={ title }
title={ widgetAreaName }
initialOpen={ initialOpen }
>
<BlockEditorProvider
Expand All @@ -29,4 +33,25 @@ function WidgetArea( { title, initialOpen } ) {
);
}

export default WidgetArea;
export default compose( [
withSelect( ( select, { id } ) => {
const {
getBlocksFromWidgetArea,
getWidgetArea,
} = select( 'core/edit-widgets' );
const blocks = getBlocksFromWidgetArea( id );
const widgetAreaName = ( getWidgetArea( id ) || {} ).name;
return {
blocks,
widgetAreaName,
};
} ),
withDispatch( ( dispatch, { id } ) => {
return {
updateBlocks( blocks ) {
const { updateBlocksInWidgetArea } = dispatch( 'core/edit-widgets' );
updateBlocksInWidgetArea( id, blocks );
},
};
} ),
] )( WidgetArea );
4 changes: 4 additions & 0 deletions packages/edit-widgets/src/components/widget-area/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.edit-widgets-widget-area {
max-width: $content-width;
margin: 0 auto 30px;
}
30 changes: 30 additions & 0 deletions packages/edit-widgets/src/components/widget-areas/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import WidgetArea from '../widget-area';

function WidgetAreas( { areas } ) {
return areas.map( ( { id }, index ) => (
<WidgetArea
key={ id }
id={ id }
initialOpen={ index === 0 }
/>
) );
}

export default compose( [
withSelect( ( select ) => {
const { getWidgetAreas } = select( 'core/edit-widgets' );
const areas = getWidgetAreas();
return {
areas,
};
} ),
] )( WidgetAreas );
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 )
);
}
76 changes: 76 additions & 0 deletions packages/edit-widgets/src/store/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* External dependencies
*/
import { get, map } from 'lodash';

/**
* WordPress dependencies
*/
import { parse, serialize } from '@wordpress/blocks';
import { dispatch, select } from '@wordpress/data-controls';

/**
* Yields an action object that setups the widget areas.
*
* @yields {Object} Action object.
*/
export function* setupWidgetAreas() {
const widgetAreas = yield select(
'core',
'getEntityRecords',
'root',
'widgetArea'
);
yield {
type: 'SETUP_WIDGET_AREAS',
widgetAreas: map( widgetAreas, ( { content, ...widgetAreaProperties } ) => {
return {
...widgetAreaProperties,
blocks: parse( get( content, [ 'raw' ], '' ) ),
};
} ),
};
}

/**
* Returns an action object used to update the blocks in a specific widget area.
*
* @param {string} widgetAreaId Id of the widget area.
* @param {Object[]} blocks Array of blocks that should be part of the widget area.
*
* @return {Object} Action object.
*/
export function updateBlocksInWidgetArea( widgetAreaId, blocks = [] ) {
return {
type: 'UPDATE_BLOCKS_IN_WIDGET_AREA',
widgetAreaId,
blocks,
};
}

/**
* Action that performs the logic to save widget areas.
*
* @yields {Object} Action object.
*/
export function* saveWidgetAreas() {
const widgetAreas = yield select(
'core/edit-widgets',
'getWidgetAreas',
);
for ( const { id } of widgetAreas ) {
const blocks = yield select(
'core/edit-widgets',
'getBlocksFromWidgetArea',
id
);
yield dispatch(
'core',
'saveWidgetArea',
{
id,
content: serialize( blocks ),
}
);
}
}
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';

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

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

const store = registerStore( 'core/edit-widgets', {
reducer,
actions,
selectors,
controls,
} );

store.dispatch( { type: 'INIT' } );

export default store;
Loading

0 comments on commit f1bbc00

Please sign in to comment.