Skip to content

Commit

Permalink
Fields UI Cleanup - Better approach to post meta management by separa…
Browse files Browse the repository at this point in the history
…ting "Fields" from "Blocks" (#87)

* remove visibility toggle and makes fields ui panel more intuitive

* remove inline comments

* separate tabs for blocks and fields

* split fields and blocks into distinct data

* combine item list

* cleans up icons with hardcoded references

* updates tab name

* remove unnecessary disableds
  • Loading branch information
bacoords authored Sep 2, 2024
1 parent 6c7c8c3 commit 05195bc
Show file tree
Hide file tree
Showing 6 changed files with 327 additions and 188 deletions.
16 changes: 16 additions & 0 deletions includes/manager/class-content-model-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,22 @@ private function register_post_type() {
)
);

register_post_meta(
Content_Model_Manager::POST_TYPE_NAME,
'blocks',
array(
'type' => 'string',
'single' => true,
'sanitize_callback' => '',
'default' => '[]',
'show_in_rest' => array(
'schema ' => array(
'type' => 'string',
),
),
)
);

$cpt_fields = array(
'plural_label' => array(
'type' => 'string',
Expand Down
31 changes: 15 additions & 16 deletions includes/manager/src/components/attribute-binder-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@ export const AttributeBinderPanel = ( { attributes, setAttributes, name } ) => {
'meta'
);

const fields = useMemo( () => {
// Saving the fields as serialized JSON because I was tired of fighting the REST API.
return meta?.fields ? JSON.parse( meta.fields ) : [];
}, [ meta.fields ] );
const blocks = useMemo( () => {
return meta?.blocks ? JSON.parse( meta.blocks ) : [];
}, [ meta.blocks ] );

const boundField = fields.find(
( field ) => field.slug === attributes.metadata?.slug
const boundField = blocks.find(
( block ) => block.slug === attributes.metadata?.slug
);

const removeBindings = useCallback( () => {
Expand All @@ -55,25 +54,25 @@ export const AttributeBinderPanel = ( { attributes, setAttributes, name } ) => {
delete newAttributes.metadata[ BLOCK_VARIATION_NAME_ATTR ];
delete newAttributes.metadata.slug;

const newFields = fields.filter(
( field ) => field.slug !== attributes.metadata.slug
const newBlocks = blocks.filter(
( block ) => block.slug !== attributes.metadata.slug
);

setMeta( {
fields: JSON.stringify( newFields ),
blocks: JSON.stringify( newBlocks ),
} );

setAttributes( newAttributes );
}, [ attributes.metadata, setAttributes, fields, setMeta ] );
}, [ attributes.metadata, setAttributes, blocks, setMeta ] );

const setBinding = useCallback(
( field ) => {
( block ) => {
const newBindings = supportedAttributes.reduce(
( acc, attribute ) => {
acc[ attribute ] =
'post_content' === field.slug
? field.slug
: `${ field.slug }__${ attribute }`;
'post_content' === block.slug
? block.slug
: `${ block.slug }__${ attribute }`;

return acc;
},
Expand All @@ -83,8 +82,8 @@ export const AttributeBinderPanel = ( { attributes, setAttributes, name } ) => {
const newAttributes = {
metadata: {
...( attributes.metadata ?? {} ),
[ BLOCK_VARIATION_NAME_ATTR ]: field.label,
slug: field.slug,
[ BLOCK_VARIATION_NAME_ATTR ]: block.label,
slug: block.slug,
[ BINDINGS_KEY ]: newBindings,
},
};
Expand Down
134 changes: 134 additions & 0 deletions includes/manager/src/components/edit-block.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {
Button,
ButtonGroup,
TextControl,
__experimentalGrid as Grid,
CardBody,
Card,
__experimentalItemGroup as ItemGroup,
__experimentalItem as Item,
Flex,
FlexBlock,
FlexItem,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useState, useEffect } from '@wordpress/element';
import {
blockDefault,
paragraph,
image,
heading,
group,
button,
} from '@wordpress/icons';

import { SUPPORTED_BLOCK_ATTRIBUTES } from '../constants';

const EditBlockForm = ( {
block = {
label: '',
slug: '',
description: '',
type: 'text',
visible: false,
},
onChange = () => {},
} ) => {
const [ formData, setFormData ] = useState( block );

useEffect( () => {
onChange( formData );
}, [ formData ] );

return (
<>
<Card>
<CardBody>
<ButtonGroup
style={ {
marginBottom: '1rem',
} }
>
<Button
icon={ blockIcon( formData.type ) }
title={ formData.type }
>
{ __( 'Block Binding' ) }
</Button>
</ButtonGroup>

<Grid columns={ 3 }>
<TextControl
label={ __( 'Name' ) }
value={ formData.label }
disabled={ true }
/>
<TextControl
label={ __( 'Key' ) }
value={ formData.slug }
disabled={ true }
/>
<TextControl
label={ __( 'Description (optional)' ) }
value={ formData.description }
onChange={ ( value ) =>
setFormData( {
...formData,
description: value,
} )
}
/>
</Grid>

<BlockAttributes
slug={ formData.slug }
type={ formData.type }
/>
</CardBody>
</Card>
</>
);
};

const BlockAttributes = ( { slug, type } ) => {
const supportedAttributes = SUPPORTED_BLOCK_ATTRIBUTES[ type ];
return (
<ItemGroup isBordered isSeparated>
{ supportedAttributes.map( ( attribute ) => (
<Item key={ attribute }>
<Flex>
<FlexBlock>{ attribute }</FlexBlock>
<FlexItem>
<span>
{ 'post_content' === slug ? (
<code>{ slug }</code>
) : (
<code>{ `${ slug }__${ attribute }` }</code>
) }
</span>
</FlexItem>
</Flex>
</Item>
) ) }
</ItemGroup>
);
};

const blockIcon = ( type ) => {
switch ( type ) {
case 'core/paragraph':
return paragraph;
case 'core/image':
return image;
case 'core/heading':
return heading;
case 'core/group':
return group;
case 'core/button':
return button;
default:
return blockDefault;
}
};

export default EditBlockForm;
Loading

0 comments on commit 05195bc

Please sign in to comment.