Skip to content

Commit

Permalink
Form: Remove old block editor back-compat code and improve code quali…
Browse files Browse the repository at this point in the history
…ty (#41348)
  • Loading branch information
talldan authored Jan 28, 2025
1 parent 13838d9 commit fd115d1
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 141 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Forms: Remove old back compat code and improve code quality
176 changes: 35 additions & 141 deletions projects/packages/forms/src/blocks/contact-form/edit.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
import { ThemeProvider } from '@automattic/jetpack-components';
import {
getJetpackData,
isAtomicSite,
isSimpleSite,
useModuleStatus,
} from '@automattic/jetpack-shared-extension-utils';
import {
InnerBlocks,
InspectorControls,
URLInput,
useBlockProps,
__experimentalBlockVariationPicker as BlockVariationPicker, // eslint-disable-line @wordpress/no-unsafe-wp-apis
__experimentalBlockPatternSetup as BlockPatternSetup, // eslint-disable-line @wordpress/no-unsafe-wp-apis
useInnerBlocksProps,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { createBlock, registerBlockVariation } from '@wordpress/blocks';
import {
Button,
Modal,
PanelBody,
SelectControl,
TextareaControl,
TextControl,
Notice,
} from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { useDispatch, useSelect } from '@wordpress/data';
import { useEffect, useRef, useState } from '@wordpress/element';
import { store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';
import { useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import clsx from 'clsx';
import { filter, get, isArray, map } from 'lodash';
import { filter, isArray, map } from 'lodash';
import { childBlocks } from './child-blocks';
import InspectorHint from './components/inspector-hint';
import { ContactFormPlaceholder } from './components/jetpack-contact-form-placeholder';
Expand All @@ -38,7 +35,7 @@ import JetpackEmailConnectionSettings from './components/jetpack-email-connectio
import JetpackManageResponsesSettings from './components/jetpack-manage-responses-settings';
import NewsletterIntegrationSettings from './components/jetpack-newsletter-integration-settings';
import SalesforceLeadFormSettings from './components/jetpack-salesforce-lead-form/jetpack-salesforce-lead-form-settings';
import defaultVariations from './variations';
import VariationPicker from './variation-picker';
import './util/form-styles.js';

const validFields = filter( childBlocks, ( { settings } ) => {
Expand Down Expand Up @@ -66,12 +63,8 @@ const ALLOWED_BLOCKS = [
'core/subhead',
'core/video',
];

const PRIORITIZED_INSERTER_BLOCKS = [ ...map( validFields, block => `jetpack/${ block.name }` ) ];

const RESPONSES_PATH = `${ get( getJetpackData(), 'adminUrl', false ) }edit.php?post_type=feedback`;
const CUSTOMIZING_FORMS_URL = 'https://jetpack.com/support/jetpack-blocks/contact-form/';

function JetpackContactFormEdit( { name, attributes, setAttributes, clientId, className } ) {
const {
to,
Expand All @@ -84,97 +77,53 @@ function JetpackContactFormEdit( { name, attributes, setAttributes, clientId, cl
salesforceData,
} = attributes;
const instanceId = useInstanceId( JetpackContactFormEdit );
const { replaceInnerBlocks, selectBlock } = useDispatch( 'core/block-editor' );
const {
blockType,
canUserInstallPlugins,
defaultVariation,
variations,
hasInnerBlocks,
postAuthorEmail,
} = useSelect(
const { canUserInstallPlugins, hasInnerBlocks, postAuthorEmail } = useSelect(
select => {
const { getBlockType, getBlockVariations, getDefaultBlockVariation } =
select( 'core/blocks' );
const { getBlocks } = select( 'core/block-editor' );
const { getEditedPostAttribute } = select( 'core/editor' );
const { getUser, canUser } = select( 'core' );
const { getBlocks } = select( blockEditorStore );
const { getEditedPostAttribute } = select( editorStore );
const { getUser, canUser } = select( coreStore );
const innerBlocks = getBlocks( clientId );

const authorId = getEditedPostAttribute( 'author' );
const authorEmail = authorId && getUser( authorId ) && getUser( authorId ).email;
const authorEmail = authorId && getUser( authorId )?.email;
const submitButton = innerBlocks.find( block => block.name === 'jetpack/button' );
if ( submitButton && ! submitButton.attributes.lock ) {
const lock = { move: false, remove: true };
submitButton.attributes.lock = lock;
}

return {
blockType: getBlockType && getBlockType( name ),
canUserInstallPlugins: canUser( 'create', 'plugins' ),
defaultVariation: getDefaultBlockVariation && getDefaultBlockVariation( name, 'block' ),
variations: getBlockVariations && getBlockVariations( name, 'block' ),
hasInnerBlocks: innerBlocks.length > 0,
postAuthorEmail: authorEmail,
};
},
[ clientId, name ]
[ clientId ]
);
const [ isPatternsModalOpen, setIsPatternsModalOpen ] = useState( false );
const wrapperRef = useRef();
const innerRef = useRef();
const blockProps = useBlockProps( { ref: wrapperRef } );
const formClassnames = clsx( className, 'jetpack-contact-form' );
const innerBlocksProps = useInnerBlocksProps(
{
ref: innerRef,
className: formClassnames,
style: window.jetpackForms.generateStyleVariables( innerRef.current ),
},
{
allowedBlocks: ALLOWED_BLOCKS,
prioritizedInserterBlocks: PRIORITIZED_INSERTER_BLOCKS,
templateInsertUpdatesSelection: false,
}
);
const { isLoadingModules, isChangingStatus, isModuleActive, changeStatus } =
useModuleStatus( 'contact-form' );

const formClassnames = clsx( className, 'jetpack-contact-form', {
'is-placeholder': ! hasInnerBlocks && registerBlockVariation,
} );

const isSalesForceExtensionEnabled =
!! window?.Jetpack_Editor_Initial_State?.available_blocks[
'contact-form/salesforce-lead-form'
];

const createBlocksFromInnerBlocksTemplate = innerBlocksTemplate => {
const blocks = map( innerBlocksTemplate, ( [ blockName, attr, innerBlocks = [] ] ) =>
createBlock( blockName, attr, createBlocksFromInnerBlocksTemplate( innerBlocks ) )
);

return blocks;
};

const setVariation = variation => {
if ( variation.attributes ) {
setAttributes( variation.attributes );
}

if ( variation.innerBlocks ) {
replaceInnerBlocks( clientId, createBlocksFromInnerBlocksTemplate( variation.innerBlocks ) );
}

selectBlock( clientId );
};

useEffect( () => {
// Populate default variation on older versions of WP or GB that don't support variations.
if ( ! hasInnerBlocks && ! registerBlockVariation ) {
setVariation( defaultVariations[ 0 ] );
}
} );

useEffect( () => {
if (
! hasInnerBlocks &&
registerBlockVariation &&
! isPatternsModalOpen &&
window.location.search.indexOf( 'showJetpackFormsPatterns' ) !== -1
) {
setIsPatternsModalOpen( true );
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [] );

let elt;

if ( ! isModuleActive ) {
Expand All @@ -189,64 +138,16 @@ function JetpackContactFormEdit( { name, attributes, setAttributes, clientId, cl
/>
);
}
} else if ( ! hasInnerBlocks && registerBlockVariation ) {
} else if ( ! hasInnerBlocks ) {
elt = (
<div className={ formClassnames }>
<BlockVariationPicker
icon={ get( blockType, [ 'icon', 'src' ] ) }
label={ get( blockType, [ 'title' ] ) }
instructions={ __(
'Start building a form by selecting one of these form templates, or search in the patterns library for more forms:',
'jetpack-forms'
) }
variations={ filter( variations, v => ! v.hiddenFromPicker ) }
onSelect={ ( nextVariation = defaultVariation ) => {
setVariation( nextVariation );
} }
/>
<div className="form-placeholder__footer">
<Button variant="secondary" onClick={ () => setIsPatternsModalOpen( true ) }>
{ __( 'Explore Form Patterns', 'jetpack-forms' ) }
</Button>
<div className="form-placeholder__footer-links">
<Button
variant="link"
className="form-placeholder__external-link"
href={ CUSTOMIZING_FORMS_URL }
target="_blank"
>
{ __( 'Learn more about customizing forms', 'jetpack-forms' ) }
</Button>
<Button
variant="link"
className="form-placeholder__external-link"
href={ RESPONSES_PATH }
target="_blank"
>
{ __( 'View and export your form responses here', 'jetpack-forms' ) }
</Button>
</div>
</div>
{ isPatternsModalOpen && (
<Modal
className="form-placeholder__patterns-modal"
title={ __( 'Choose a pattern', 'jetpack-forms' ) }
closeLabel={ __( 'Cancel', 'jetpack-forms' ) }
onRequestClose={ () => setIsPatternsModalOpen( false ) }
>
<BlockPatternSetup
initialViewMode="grid"
filterPatternsFn={ pattern => {
return pattern.content.indexOf( 'jetpack/contact-form' ) !== -1;
} }
clientId={ clientId }
/>
</Modal>
) }
</div>
<VariationPicker
blockName={ name }
setAttributes={ setAttributes }
clientId={ clientId }
classNames={ formClassnames }
/>
);
} else {
const style = window.jetpackForms.generateStyleVariables( innerRef.current );
elt = (
<>
<InspectorControls>
Expand Down Expand Up @@ -348,14 +249,7 @@ function JetpackContactFormEdit( { name, attributes, setAttributes, clientId, cl
</>
) }
</InspectorControls>

<div className={ formClassnames } style={ style } ref={ innerRef }>
<InnerBlocks
allowedBlocks={ ALLOWED_BLOCKS }
prioritizedInserterBlocks={ PRIORITIZED_INSERTER_BLOCKS }
templateInsertUpdatesSelection={ false }
/>
</div>
<div { ...innerBlocksProps } />
</>
);
}
Expand Down
119 changes: 119 additions & 0 deletions projects/packages/forms/src/blocks/contact-form/variation-picker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { getJetpackData } from '@automattic/jetpack-shared-extension-utils';
import {
__experimentalBlockVariationPicker as BlockVariationPicker, // eslint-disable-line @wordpress/no-unsafe-wp-apis
__experimentalBlockPatternSetup as BlockPatternSetup, // eslint-disable-line @wordpress/no-unsafe-wp-apis
store as blockEditorStore,
} from '@wordpress/block-editor';
import { createBlock, store as blocksStore } from '@wordpress/blocks';
import { Button, Modal } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import clsx from 'clsx';
import { filter, get, map } from 'lodash';
import './util/form-styles.js';

const RESPONSES_PATH = `${ get( getJetpackData(), 'adminUrl', false ) }edit.php?post_type=feedback`;
const CUSTOMIZING_FORMS_URL = 'https://jetpack.com/support/jetpack-blocks/contact-form/';

const createBlocksFromInnerBlocksTemplate = innerBlocksTemplate => {
const blocks = map( innerBlocksTemplate, ( [ blockName, attr, innerBlocks = [] ] ) =>
createBlock( blockName, attr, createBlocksFromInnerBlocksTemplate( innerBlocks ) )
);

return blocks;
};

export default function VariationPicker( { blockName, setAttributes, clientId, classNames } ) {
const [ isPatternsModalOpen, setIsPatternsModalOpen ] = useState( false );
const { replaceInnerBlocks, selectBlock } = useDispatch( blockEditorStore );
const { blockType, defaultVariation, variations } = useSelect(
select => {
const { getBlockType, getBlockVariations, getDefaultBlockVariation } = select( blocksStore );

return {
blockType: getBlockType( blockName ),
defaultVariation: getDefaultBlockVariation( blockName, 'block' ),
variations: getBlockVariations( blockName, 'block' ),
};
},
[ blockName ]
);

useEffect( () => {
if (
! isPatternsModalOpen &&
window.location.search.indexOf( 'showJetpackFormsPatterns' ) !== -1
) {
setIsPatternsModalOpen( true );
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [] );

return (
<div className={ clsx( classNames, 'is-placeholder' ) }>
<BlockVariationPicker
icon={ get( blockType, [ 'icon', 'src' ] ) }
label={ get( blockType, [ 'title' ] ) }
instructions={ __(
'Start building a form by selecting one of these form templates, or search in the patterns library for more forms:',
'jetpack-forms'
) }
variations={ filter( variations, v => ! v.hiddenFromPicker ) }
onSelect={ ( nextVariation = defaultVariation ) => {
if ( nextVariation.attributes ) {
setAttributes( nextVariation.attributes );
}

if ( nextVariation.innerBlocks ) {
replaceInnerBlocks(
clientId,
createBlocksFromInnerBlocksTemplate( nextVariation.innerBlocks )
);
}

selectBlock( clientId );
} }
/>
<div className="form-placeholder__footer">
<Button variant="secondary" onClick={ () => setIsPatternsModalOpen( true ) }>
{ __( 'Explore Form Patterns', 'jetpack-forms' ) }
</Button>
<div className="form-placeholder__footer-links">
<Button
variant="link"
className="form-placeholder__external-link"
href={ CUSTOMIZING_FORMS_URL }
target="_blank"
>
{ __( 'Learn more about customizing forms', 'jetpack-forms' ) }
</Button>
<Button
variant="link"
className="form-placeholder__external-link"
href={ RESPONSES_PATH }
target="_blank"
>
{ __( 'View and export your form responses here', 'jetpack-forms' ) }
</Button>
</div>
</div>
{ isPatternsModalOpen && (
<Modal
className="form-placeholder__patterns-modal"
title={ __( 'Choose a pattern', 'jetpack-forms' ) }
closeLabel={ __( 'Cancel', 'jetpack-forms' ) }
onRequestClose={ () => setIsPatternsModalOpen( false ) }
>
<BlockPatternSetup
initialViewMode="grid"
filterPatternsFn={ pattern => {
return pattern.content.indexOf( 'jetpack/contact-form' ) !== -1;
} }
clientId={ clientId }
/>
</Modal>
) }
</div>
);
}

0 comments on commit fd115d1

Please sign in to comment.