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

Connnect gutenberg widgets screen to widget area endpoints #15779

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