Update preview logic, render select dialog conditionally

This commit is contained in:
Michael Thomas 2022-02-02 09:42:30 -05:00
parent 4b9095782d
commit 85973c58ed
3 changed files with 130 additions and 138 deletions

View File

@ -2,27 +2,16 @@
* WordPress dependencies * WordPress dependencies
*/ */
import * as React from 'react'; import * as React from 'react';
import { Button, Modal, FocusableIframe } from '@wordpress/components'; import { Modal, FocusableIframe } from '@wordpress/components';
import { baseUrl } from '@/globals'; import { baseUrl } from '@/globals';
type DialogProps = { type DialogProps = {
setOpen: Function;
onSelectForm: Function; onSelectForm: Function;
}; };
type DialogState = { class SelectDialog extends React.Component<DialogProps> {
isOpen: boolean;
};
class SelectDialog extends React.Component<DialogProps, DialogState> {
constructor( props: any ) {
super( props );
this.state = {
isOpen: false,
};
}
componentDidMount() { componentDidMount() {
window.addEventListener( 'message', this.handlePostMessage, false ); window.addEventListener( 'message', this.handlePostMessage, false );
} }
@ -32,32 +21,25 @@ class SelectDialog extends React.Component<DialogProps, DialogState> {
} }
handlePostMessage = ( event: MessageEvent ) => { handlePostMessage = ( event: MessageEvent ) => {
if (event.origin === baseUrl && event.data.type === 'cog-form-selected') { if ( event.origin === baseUrl && event.data.type === 'cog-form-selected' ) {
this.props.onSelectForm( event.data ); this.props.onSelectForm( event.data );
this.setState({ isOpen: false }); // Close Dialog this.props.setOpen( false );
} }
} }
render() { render() {
return ( return (
<div> <Modal
<Button isPrimary={true} onClick={ () => this.setState( { isOpen: true } ) }> title="Cognito Forms"
Choose a form className="cognito-modal"
</Button> onRequestClose={ () => this.props.setOpen( false ) }
{ this.state.isOpen && ( shouldCloseOnClickOutside={ false }
<Modal >
title="Cognito Forms" <FocusableIframe
className="cognito-modal" style={ { width: '500px', height: '500px', display: 'block' } }
onRequestClose={ () => this.setState( { isOpen: false } ) } src={ `${ baseUrl }/integrations/cms` }
shouldCloseOnClickOutside={ false } ></FocusableIframe>
> </Modal>
<FocusableIframe
style={ { width: '500px', height: '500px', display: 'block' } }
src={ `${ baseUrl }/integrations/cms` }
></FocusableIframe>
</Modal>
) }
</div>
); );
} }
} }

View File

@ -1,5 +1,4 @@
import * as React from 'react'; import * as React from 'react';
import { __ } from '@wordpress/i18n';
import { BlockEditProps } from '@wordpress/blocks'; import { BlockEditProps } from '@wordpress/blocks';
import { import {
@ -9,17 +8,23 @@ import {
PanelBody, PanelBody,
PanelRow, PanelRow,
ExternalLink, ExternalLink,
Button,
Icon,
} from '@wordpress/components'; } from '@wordpress/components';
import { edit } from '@wordpress/icons'; import { edit, external } from '@wordpress/icons';
import { useState } from '@wordpress/element';
import { BlockControls, InspectorControls } from '@wordpress/block-editor'; import { BlockControls, InspectorControls } from '@wordpress/block-editor';
import { BlockAttributes, EmbedMode } from '@/types';
import { baseUrl } from './globals';
import { ReactComponent as CogIcon } from '@/assets/cogicon.svg'; import { ReactComponent as CogIcon } from '@/assets/cogicon.svg';
import SelectDialog from '@/components/select-dialog'; import SelectDialog from '@/components/select-dialog';
import PreviewForm from '@/components/preview-form'; import PreviewForm from '@/components/preview-form';
import { BlockAttributes, EmbedMode } from '@/types';
const Edit: React.FC<BlockEditProps<BlockAttributes>> = ( { attributes, setAttributes, className } ) => { const Edit: React.FC<BlockEditProps<BlockAttributes>> = ( { attributes, setAttributes, className } ) => {
const [ selectDialogOpen, setSelectDialogOpen ] = useState( false );
const handleForm = ( form: { [key: string]: any } ) => { const handleForm = ( form: { [key: string]: any } ) => {
setAttributes( { setAttributes( {
formId: form.formId, formId: form.formId,
@ -30,71 +35,71 @@ const Edit: React.FC<BlockEditProps<BlockAttributes>> = ( { attributes, setAttri
} ); } );
}; };
const resetForm = () => {
// Create a new object which sets all attributes to null
const nullAttributes = Object.keys( attributes ).reduce(
( accumulator, current ) => {
// @ts-ignore
accumulator[ current ] = null;
return accumulator;
}, {} );
setAttributes( nullAttributes );
};
if ( ! attributes.formId ) {
return (
<div>
<Placeholder
icon={ CogIcon }
label="Cognito Forms"
className={ className }
instructions={ __(
'Click the button below to choose a form to embed.'
) }
>
<SelectDialog onSelectForm={ handleForm }></SelectDialog>
</Placeholder>
</div>
);
}
return ( return (
<div> <div className={ className }>
{ { attributes.formId ?
<BlockControls> // A form has already been selected, so render the form preview.
<ToolbarButton <div>
icon={ edit } <BlockControls>
label="Edit" <ToolbarButton
onClick={ () => resetForm() } icon={ edit }
label="Edit"
onClick={ () => setSelectDialogOpen( true ) }
/>
</BlockControls>
<InspectorControls key="setting">
<PanelBody title="Form Settings">
<PanelRow>
<RadioControl
label="Embed Mode"
help={
<span>
The type of embed code to use with your form. <ExternalLink href="https://www.cognitoforms.com/support/10/style-publish">Learn more</ExternalLink>
</span>
}
selected={ attributes.embedMode }
options={ [
{ label: 'Seamless', value: EmbedMode.Seamless },
{ label: 'Iframe', value: EmbedMode.IFrame },
] }
onChange={ ( value: EmbedMode ) => setAttributes( { embedMode: parseInt( value.toString() ) } ) }
/>
</PanelRow>
</PanelBody>
</InspectorControls>
<PreviewForm
embedCode={ attributes.iframeEmbedCode }
/> />
</BlockControls> </div>
:
// No form has been selected yet, so render the placeholder
<div>
<Placeholder
icon={ CogIcon }
label="Cognito Forms"
instructions="Choose an existing form to embed or create a new one."
>
<div>
<Button isPrimary onClick={ () => setSelectDialogOpen( true ) }>
Select Form
</Button>
<Button isTertiary href={ `${ baseUrl }/forms/new` } target="_blank">
New Form&thinsp;<Icon icon={ external } size={ 16 }></Icon>
</Button>
</div>
</Placeholder>
</div>
} }
<InspectorControls key="setting"> { selectDialogOpen &&
<PanelBody title="Embed Settings"> // Selectively render the select dialog
<PanelRow> <SelectDialog
<RadioControl setOpen={ ( val: boolean ) => setSelectDialogOpen( val ) }
label="Embed Mode" onSelectForm={ handleForm }
help={ ></SelectDialog>
<span> }
The type of embed code to use with your form. <ExternalLink href="https://www.cognitoforms.com/support/10/style-publish">Learn more</ExternalLink>
</span>
}
selected={ attributes.embedMode }
options={ [
{ label: 'Seamless', value: EmbedMode.Seamless },
{ label: 'Iframe', value: EmbedMode.IFrame },
] }
onChange={ ( value: EmbedMode ) => setAttributes( { embedMode: parseInt( value.toString() ) } ) }
/>
</PanelRow>
</PanelBody>
</InspectorControls>
<PreviewForm
embedCode={ attributes.iframeEmbedCode }
/>
</div> </div>
); );
}; };

View File

@ -7,51 +7,56 @@
*/ */
// Remove modal padding // Remove modal padding
.cognito-modal > .components-modal__content { .wp-block-cognito-forms-cognito-embed {
padding: initial; .components-placeholder__label svg {
} height: 24px;
width: 24px;
.cognito-modal > .components-modal__content > .components-modal__header {
margin: initial;
}
// .cog-wp-embed__preview > iframe {
// height: 500px;
// }
.form-preview {
min-height: 200px;
.focus-grabber {
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
} }
.loader { .form-preview {
padding: 1em;
background: #fff;
text-align: center;
min-height: 200px; min-height: 200px;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #1e1e1e;
display: flex; .focus-grabber {
gap: 0.5em; position: absolute;
flex-direction: column; width: 100%;
align-items: center; height: 100%;
justify-content: center; z-index: 1;
.icon {
width: 2em;
height: 2em;
margin: 0 auto;
} }
p { .loader {
font-size: 13px; padding: 1em;
margin: 0; background: #fff;
text-align: center;
min-height: 200px;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #1e1e1e;
display: flex;
gap: 0.5em;
flex-direction: column;
align-items: center;
justify-content: center;
.icon {
width: 2em;
height: 2em;
margin: 0 auto;
}
p {
font-size: 13px;
margin: 0;
}
} }
} }
} }
.cognito-modal {
.components-modal__content {
padding: initial;
}
.components-modal__content .components-modal__header {
margin: initial;
}
}