Skip to content
This repository has been archived by the owner on Nov 6, 2022. It is now read-only.

Commit

Permalink
Add a function to save a new field value
Browse files Browse the repository at this point in the history
Also, add a unit test for that.
@todo: test the 'happy path' of that function.
  • Loading branch information
kienstra committed Dec 30, 2019
1 parent 422f024 commit 8350ee6
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 63 deletions.
2 changes: 1 addition & 1 deletion js/src/block-lab-editor/components/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Editor extends Component {
<div className="fields">
{
!! fields && Object.values( fields ).map( ( field, index ) => {
return <Field field={ field } uid={ index } key={ `field-row-${ index }` } />;
return <Field field={ field } uiud={ index } key={ `field-row-${ index }` } />;
} )
}
<div className="add-field-container">
Expand Down
33 changes: 22 additions & 11 deletions js/src/block-lab-editor/components/field-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ const { Button, TextControl } = wp.components;
const { Component } = wp.element;

/**
* A field row.
* Internal dependencies
*/
import saveFieldValue from '../helpers/saveFieldValue';

/**
* A field's editing section.
*/
class FieldEdit extends Component {
/**
* Renders the field row.
* Renders the field's editing section.
*
* @return {Function} The rendered component.
*/
render() {
const { field, uid } = this.props;
const { field, uiud } = this.props;
const isFieldDisabled = false;

return (
Expand All @@ -24,7 +29,7 @@ class FieldEdit extends Component {
<tr className="block-fields-edit-label">
<td className="spacer"></td>
<th scope="row">
<label htmlFor={ `block-fields-edit-label-input_${ uid } ` }>
<label htmlFor={ `block-fields-edit-label-input_${ uiud } ` }>
{ __( 'Field Label', 'block-lab' ) }
</label>
<p className="description">
Expand All @@ -34,18 +39,21 @@ class FieldEdit extends Component {
<td>
<TextControl
type="text"
id={ `block-fields-edit-label-input_${ uid }` }
id={ `block-fields-edit-label-input_${ uiud }` }
className="regular-text"
value={ field.label }
data-sync={ `block-fields-label_${ uid }` }
onChange={ ( newValue ) => {
saveFieldValue( field.name, 'label', newValue );
} }
data-sync={ `block-fields-label_${ uiud }` }
readOnly={ isFieldDisabled }
/>
</td>
</tr>
<tr className="block-fields-edit-name">
<td className="spacer"></td>
<th scope="row">
<label id={ `block-fields-edit-name-${ uid }` } htmlFor={ `block-fields-edit-name-input_${ uid }` }>
<label id={ `block-fields-edit-name-${ uiud }` } htmlFor={ `block-fields-edit-name-input_${ uiud }` }>
{ __( 'Field Name', 'block-lab' ) }
</label>
<p className="description">
Expand All @@ -54,9 +62,12 @@ class FieldEdit extends Component {
</th>
<td>
<TextControl
id={ `block-fields-edit-name-input_${ uid }` }
id={ `block-fields-edit-name-input_${ uiud }` }
className="regular-text"
value={ field.name }
onChange={ ( newValue ) => {
saveFieldValue( field.name, 'name', newValue );
} }
data-sync="block-fields-name-code"
readOnly={ isFieldDisabled }
/>
Expand All @@ -65,14 +76,14 @@ class FieldEdit extends Component {
<tr className="block-fields-edit-control">
<td className="spacer"></td>
<th scope="row">
<label htmlFor={ `block-fields-edit-control-input_${ uid }` }>
<label htmlFor={ `block-fields-edit-control-input_${ uiud }` }>
{ __( 'Field Type', 'block-lab' ) }
</label>
</th>
<td>
<select
id={ `block-fields-edit-control-input_${ uid }` }
data-sync={ `block-fields-control_${ uid }` }
id={ `block-fields-edit-control-input_${ uiud }` }
data-sync={ `block-fields-control_${ uiud }` }
disabled={ isFieldDisabled }
>
{
Expand Down
4 changes: 2 additions & 2 deletions js/src/block-lab-editor/components/field.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Field extends Component {
* @return {Function} The rendered component.
*/
render() {
const { field } = this.props;
const { field, uiud } = this.props;

return (
<div className="field">
Expand All @@ -44,7 +44,7 @@ class Field extends Component {
</svg>
</div>
</div>
<FieldEdit field={ field } />
<FieldEdit field={ field } uiud={ uiud } />
</div>
);
}
Expand Down
40 changes: 40 additions & 0 deletions js/src/block-lab-editor/helpers/saveFieldValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* WordPress dependencies
*/
const { dispatch, select } = wp.data;

/**
* Internal dependencies
*/
import getBlockFromContent from './getBlockFromContent';

/**
* Parses the block from the post content into an object.
*
* @param {string} fieldSlug The slug of the field.
* @param {string} key The key of the field value to change, like 'label'.
* @param {string} value The new field value.
* @return {boolean} Whether saving the field value succeeded.
*/
const saveFieldValue = ( fieldSlug, key, value ) => {
if ( ! fieldSlug ) {
return false;
}

const content = select( 'core/editor' ).getEditedPostContent();
const block = getBlockFromContent( content ) || {};
if ( ! block.hasOwnProperty( 'fields' ) ) {
block.fields = {};
}

if ( ! block.fields.hasOwnProperty( fieldSlug ) || 'object' !== typeof block.fields[ fieldSlug ] ) {
return false;
}

block.fields[ fieldSlug ][ key ] = value;
dispatch( 'core/editor' ).editPost( { content: JSON.stringify( [ block ] ) } );
dispatch( 'core/block-editor' ).resetBlocks( [] ); // Prevent the block editor from overwriting the saved content.
return true;
};

export default saveFieldValue;
21 changes: 21 additions & 0 deletions js/src/block-lab-editor/helpers/test/saveFieldValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Internal dependencies
*/
import saveFieldValue from '../saveFieldValue';

describe( 'saveFieldValue', () => {
it( 'should not update the post if the field argument is an empty string', () => {
saveFieldValue( '', 'example-email', 'you@example.com' );
expect( global.wp.data.dispatch( 'core/editor' ).editPost ).toHaveBeenCalledTimes( 0 );
} );

it( 'should not attempt to update the post if there is no fields index', () => {
saveFieldValue( 'real-field-slug', 'example-email', 'you@example.com' );
expect( global.wp.data.dispatch( 'core/editor' ).editPost ).toHaveBeenCalledTimes( 0 );
} );

it( 'should not update the post if the field does not exist yet', () => {
saveFieldValue( 'real-field-slug', 'example-email', 'you@example.com' );
expect( global.wp.data.dispatch( 'core/editor' ).editPost ).toHaveBeenCalledTimes( 0 );
} );
} );
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"url": "https://github.com/getblocklab/block-lab"
},
"scripts": {
"dev": "cross-env BABEL_ENV=default webpack --watch",
"dev": "wp-scripts start",
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
"lint": "npm-run-all --parallel lint:*",
"lint:js": "eslint js",
Expand Down
6 changes: 6 additions & 0 deletions php/blocks/class-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ protected function get_callback( $method_name ) {
* Launch the blocks inside Gutenberg.
*/
protected function editor_assets() {
// There's no need to for these assets on the Block Lab block editor (the 'Edit Block' UI).
$screen = get_current_screen();
if ( is_object( $screen ) && block_lab()->get_post_type_slug() === $screen->post_type ) {
return;
}

wp_enqueue_script(
'block-lab-blocks',
$this->assets['url']['entry'],
Expand Down
16 changes: 15 additions & 1 deletion tests/js/setup-globals.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
// Mock wp object.

global.wp = {
blocks: { registerBlockType: jest.fn() },
blocks: {
registerBlockType: jest.fn(),
},
data: {
dispatch: ( store ) => {
if ( 'core/editor' === store ) {
return { editPost: jest.fn() };
}
},
select: ( store ) => {
if ( 'core/editor' === store ) {
return { getEditedPostContent: jest.fn() };
}
},
}
};
78 changes: 31 additions & 47 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,20 @@
const path = require( 'path' );
const ExtractTextPlugin = require( 'extract-text-webpack-plugin' );
const UglifyJSPlugin = require( 'uglifyjs-webpack-plugin' );

// Set different CSS extraction for editor only and common block styles
const blocksCSSPlugin = new ExtractTextPlugin( {
filename: './css/blocks.style.css',
} );
const editBlocksCSSPlugin = new ExtractTextPlugin( {
filename: './css/blocks.editor.css',
} );
const uglifyJSPlugin = new UglifyJSPlugin( {
uglifyOptions: {
mangle: {},
compress: true
},
sourceMap: false
} );

// Configuration for the ExtractTextPlugin.
const extractConfig = {
use: [
{ loader: 'raw-loader' },
{
loader: 'postcss-loader',
options: {
plugins: [ require( 'autoprefixer' ) ],
},
},
{
loader: 'sass-loader',
query: {
outputStyle: 'compressed',
},
},
],
};
const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
const isProduction = process.env.NODE_ENV === 'production';

module.exports = {
...defaultConfig,
entry: {
'./js/build/block-lab-editor': './js/src/block-editor/index.js',
'./js/build/block-editor': './js/src/block-lab-editor/index.js',
'./js/build/block-lab-editor': './js/src/block-lab-editor/index.js',
'./js/build/block-editor': './js/src/block-editor/index.js',
},
output: {
path: path.resolve( __dirname ),
filename: '[name].js',
},
watch: false,
// devtool: 'cheap-eval-source-map',
mode: isProduction ? 'production' : 'development',
module: {
rules: [
{
Expand All @@ -56,19 +24,35 @@ module.exports = {
loader: 'babel-loader',
},
},
{
test: /style\.s?css$/,
use: blocksCSSPlugin.extract( extractConfig ),
},
{
test: /editor\.s?css$/,
use: editBlocksCSSPlugin.extract( extractConfig ),
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// Only allow hot module reloading in development.
hmr: process.env.NODE_ENV === 'development',
// Force reloading if hot module reloading does not work.
reloadAll: true,
},
},
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: [ require( 'autoprefixer' ) ],
},
},
{
loader: 'sass-loader',
},
],
},
],
},
plugins: [
blocksCSSPlugin,
editBlocksCSSPlugin,
uglifyJSPlugin,
new MiniCssExtractPlugin( {
filename: './css/blocks.editor.css',
} ),
],
};

0 comments on commit 8350ee6

Please sign in to comment.