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

SPT: move storing to higher component #35618

Merged
merged 17 commits into from
Aug 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { isEmpty, noop } from 'lodash';
import { isEmpty, noop, map } from 'lodash';
import classnames from 'classnames';

/**
Expand All @@ -17,19 +17,17 @@ import { memo } from '@wordpress/element';
import TemplateSelectorItem from './template-selector-item';
import replacePlaceholders from '../utils/replace-placeholders';

// Load config passed from backend.
const { siteInformation = {} } = window.starterPageTemplatesConfig;

const TemplateSelectorControl = ( {
label,
className,
help,
instanceId,
templates = [],
templates = {},
blocksByTemplates = {},
useDynamicPreview = false,
numBlocksInPreview,
onTemplateSelect = noop,
onTemplateFocus = noop,
siteInformation = {},
} ) => {
if ( isEmpty( templates ) ) {
return null;
Expand All @@ -45,7 +43,7 @@ const TemplateSelectorControl = ( {
className={ classnames( className, 'template-selector-control' ) }
>
<ul className="template-selector-control__options">
{ templates.map( ( { slug, title, content, preview, previewAlt, value } ) => (
{ map( templates, ( { slug, title, preview, previewAlt, value } ) => (
<li key={ `${ id }-${ value }` } className="template-selector-control__template">
<TemplateSelectorItem
id={ id }
Expand All @@ -56,9 +54,8 @@ const TemplateSelectorControl = ( {
onFocus={ onTemplateFocus }
staticPreviewImg={ preview }
staticPreviewImgAlt={ previewAlt }
rawContent={ replacePlaceholders( content, siteInformation ) }
blocks={ blocksByTemplates.hasOwnProperty( slug ) ? blocksByTemplates[ slug ] : [] }
useDynamicPreview={ useDynamicPreview }
numBlocksInPreview={ numBlocksInPreview }
/>
</li>
) ) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* External dependencies
*/
import { debounce } from 'lodash';

/**
* Internal dependencies
Expand All @@ -10,9 +9,7 @@ import { debounce } from 'lodash';
/**
* WordPress dependencies
*/
import { useState, useMemo } from '@wordpress/element';
import BlockPreview from './block-template-preview';
import { parse as parseBlocks } from '@wordpress/blocks';
import { Disabled } from '@wordpress/components';

const TemplateSelectorItem = props => {
Expand All @@ -26,30 +23,13 @@ const TemplateSelectorItem = props => {
useDynamicPreview = false,
staticPreviewImg,
staticPreviewImgAlt = '',
rawContent,
numBlocksInPreview,
blocks = [],
} = props;

const ON_FOCUS_DELAY = 500;

const [ blocksLimit, setBlockLimit ] = useState( numBlocksInPreview );
const blocks = useMemo( () => ( rawContent ? parseBlocks( rawContent ) : null ), [ rawContent ] );

const onFocusHandler = debounce( () => {
if ( blocks && blocks.length > blocksLimit ) {
setBlockLimit( null ); // not blocks limit to template preview
}

onFocus( value, label, blocks );
}, ON_FOCUS_DELAY );

// Define static or dynamic preview.
const innerPreview = useDynamicPreview ? (
<Disabled>
<BlockPreview
blocks={ blocksLimit && blocks ? blocks.slice( 0, blocksLimit ) : blocks }
viewportWidth={ 960 }
/>
<BlockPreview blocks={ blocks } viewportWidth={ 960 } />
</Disabled>
) : (
<img
Expand All @@ -65,10 +45,8 @@ const TemplateSelectorItem = props => {
id={ `${ id }-${ value }` }
className="template-selector-item__label"
value={ value }
// onFocus={ onFocusHandler }
onMouseEnter={ onFocusHandler }
onMouseLeave={ onFocusHandler.cancel }
onClick={ () => onSelect( value, label, blocks ) }
onMouseEnter={ () => onFocus( value, label ) }
onClick={ () => onSelect( value, label ) }
aria-describedby={ help ? `${ id }__help` : undefined }
>
<div className="template-selector-item__preview-wrap">{ innerPreview }</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { isEmpty } from 'lodash';
import { isEmpty, reduce } from 'lodash';
import { __, sprintf } from '@wordpress/i18n';
import { compose } from '@wordpress/compose';
import { Button, Modal } from '@wordpress/components';
Expand All @@ -17,18 +17,27 @@ import './styles/starter-page-templates-editor.scss';
import TemplateSelectorControl from './components/template-selector-control';
import TemplateSelectorPreview from './components/template-selector-preview';
import { trackDismiss, trackSelection, trackView, initializeWithIdentity } from './utils/tracking';
import { parse as parseBlocks } from '@wordpress/blocks';
import replacePlaceholders from './utils/replace-placeholders';

// Load config passed from backend.
const {
templates = [],
vertical,
segment,
tracksUserData,
siteInformation = {},
} = window.starterPageTemplatesConfig;

class PageTemplateModal extends Component {
state = {
isLoading: false,
previewBlocks: [],
slug: '',
title: '',
blocks: {},
};

constructor( props ) {
// eslint-disable-next-line no-console
console.time( 'PageTemplateModal' );
super();
this.state.isOpen = ! isEmpty( props.templates );
}
Expand All @@ -37,36 +46,50 @@ class PageTemplateModal extends Component {
if ( this.state.isOpen ) {
trackView( this.props.segment.id, this.props.vertical.id );
}
// eslint-disable-next-line no-console
console.timeEnd( 'PageTemplateModal' );

// Parse templates blocks and store them into the state.
const blocks = reduce(
templates,
( prev, { slug, content } ) => {
prev[ slug ] = content
? parseBlocks( replacePlaceholders( content, siteInformation ) )
: [];
return prev;
},
{}
);

// eslint-disable-next-line react/no-did-mount-set-state
marekhrabe marked this conversation as resolved.
Show resolved Hide resolved
this.setState( { blocks } );
}

setTemplate = ( slug, title, previewBlocks ) => {
setTemplate = ( slug, title ) => {
this.setState( { isOpen: false } );
trackSelection( this.props.segment.id, this.props.vertical.id, slug );

this.props.saveTemplateChoice( slug );

const previewBlocks = this.state.blocks[ slug ];
retrofox marked this conversation as resolved.
Show resolved Hide resolved

// Skip inserting if there's nothing to insert.
if ( ! previewBlocks || previewBlocks.length === 0 ) {
if ( ! previewBlocks || ! previewBlocks.length ) {
return;
}

this.props.insertTemplate( title, previewBlocks );
};

selectTemplate = () =>
this.setTemplate( this.state.slug, this.state.title, this.state.previewBlocks );
handleConfirmation = () => this.setTemplate( this.state.slug, this.state.title );

focusTemplate = ( slug, title, previewBlocks ) => {
this.setState( { slug, title, previewBlocks } );
previewTemplate = ( slug, title ) => {
this.setState( { slug, title } );
if ( slug === 'blank' ) {
this.setTemplate( slug, title, previewBlocks );
this.setTemplate( slug, title );
}
};

closeModal = event => {
// Check to see if the Blur event occured on the buttons inside of the Modal.
// Check to see if the Blur event occurred on the buttons inside of the Modal.
// If it did then we don't want to dismiss the Modal for this type of Blur.
if ( event.target.matches( 'button.template-selector-item__label' ) ) {
return false;
Expand All @@ -75,6 +98,18 @@ class PageTemplateModal extends Component {
trackDismiss( this.props.segment.id, this.props.vertical.id );
};

getBlocksByTemplateSlug( slug = this.state.slug ) {
if ( ! slug ) {
return [];
}

if ( ! this.state.blocks.hasOwnProperty( slug ) ) {
return [];
}

return this.state.blocks[ slug ];
}

render() {
if ( ! this.state.isOpen ) {
return null;
Expand All @@ -93,14 +128,17 @@ class PageTemplateModal extends Component {
<TemplateSelectorControl
label={ __( 'Template', 'full-site-editing' ) }
templates={ this.props.templates }
onTemplateSelect={ this.focusTemplate }
// onTemplateFocus={ this.focusTemplate }
blocksByTemplates={ this.state.blocks }
onTemplateSelect={ this.previewTemplate }
useDynamicPreview={ true }
numBlocksInPreview={ 10 }
siteInformation={ siteInformation }
/>
</fieldset>
</form>
<TemplateSelectorPreview blocks={ this.state.previewBlocks } viewportWidth={ 960 } />
<TemplateSelectorPreview
blocks={ this.getBlocksByTemplateSlug() }
viewportWidth={ 960 }
/>
</div>
<div className="page-template-modal__buttons">
<Button isDefault isLarge onClick={ this.closeModal }>
Expand All @@ -110,7 +148,7 @@ class PageTemplateModal extends Component {
isPrimary
isLarge
disabled={ isEmpty( this.state.slug ) }
onClick={ this.selectTemplate }
onClick={ this.handleConfirmation }
>
{ sprintf( __( 'Use %s template', 'full-site-editing' ), this.state.title ) }
</Button>
Expand Down Expand Up @@ -160,9 +198,6 @@ const PageTemplatesPlugin = compose(
} )
)( PageTemplateModal );

// Load config passed from backend.
const { templates = [], vertical, segment, tracksUserData } = window.starterPageTemplatesConfig;

if ( tracksUserData ) {
initializeWithIdentity( tracksUserData );
}
Expand Down