Display usnaved form changes in preview

[MAILPOET-2743]
This commit is contained in:
Rostislav Wolny
2020-04-15 18:35:31 +02:00
committed by Veljko V
parent 51f138483c
commit ac359dacf1
4 changed files with 46 additions and 41 deletions

View File

@ -10,6 +10,7 @@ import { useDispatch, useSelect } from '@wordpress/data';
import Preview from '../../common/preview/preview.jsx'; import Preview from '../../common/preview/preview.jsx';
import Modal from '../../common/modal/modal.jsx'; import Modal from '../../common/modal/modal.jsx';
import { blocksToFormBodyFactory } from '../store/blocks_to_form_body.jsx'; import { blocksToFormBodyFactory } from '../store/blocks_to_form_body.jsx';
import mapFormDataBeforeSaving from '../store/map_form_data_before_saving.jsx';
import { onChange } from '../../common/functions'; import { onChange } from '../../common/functions';
function getFormType(settings) { function getFormType(settings) {
@ -30,8 +31,9 @@ function getFormType(settings) {
} }
const getPreviewType = () => (window.localStorage.getItem('mailpoet_form_preview_last_preview_type') || 'desktop'); const getPreviewType = () => (window.localStorage.getItem('mailpoet_form_preview_last_preview_type') || 'desktop');
const FormPreview = () => { const FormPreview = () => {
const [form, setForm] = useState(null); const [formPersisted, setFormPersisted] = useState(false);
const [iframeLoaded, setIframeLoaded] = useState(false); const [iframeLoaded, setIframeLoaded] = useState(false);
const formBlocks = useSelect( const formBlocks = useSelect(
@ -57,7 +59,7 @@ const FormPreview = () => {
[] []
); );
const loadFormPreviewFromServer = useCallback(() => { const saveFormDataForPreview = useCallback(() => {
const blocksToFormBody = blocksToFormBodyFactory( const blocksToFormBody = blocksToFormBodyFactory(
editorSettings.colors, editorSettings.colors,
editorSettings.fontSizes, editorSettings.fontSizes,
@ -68,26 +70,25 @@ const FormPreview = () => {
endpoint: 'forms', endpoint: 'forms',
action: 'previewEditor', action: 'previewEditor',
data: { data: {
...mapFormDataBeforeSaving(formData),
body: blocksToFormBody(formBlocks), body: blocksToFormBody(formBlocks),
settings: formData.settings,
}, },
}).done((response) => { }).done(() => {
setForm(response.data); setFormPersisted(true);
}); });
}, [formBlocks, customFields, formData, editorSettings.colors, editorSettings.fontSizes]); }, [formBlocks, customFields, formData, editorSettings.colors, editorSettings.fontSizes]);
useEffect(() => { useEffect(() => {
if (isPreview) { if (isPreview) {
loadFormPreviewFromServer(); saveFormDataForPreview();
} }
setIframeLoaded(false); setIframeLoaded(false);
}, [isPreview, loadFormPreviewFromServer]); }, [isPreview, saveFormDataForPreview]);
if (!isPreview) return null; if (!isPreview) return null;
function onClose() { function onClose() {
setForm(null); setFormPersisted(false);
hidePreview(); hidePreview();
} }
@ -117,12 +118,12 @@ const FormPreview = () => {
fullScreen fullScreen
contentClassName="mailpoet_form_preview_modal" contentClassName="mailpoet_form_preview_modal"
> >
{form === null && ( {!formPersisted && (
<div className="mailpoet_spinner_wrapper"> <div className="mailpoet_spinner_wrapper">
<Spinner /> <Spinner />
</div> </div>
)} )}
{form !== null && ( {formPersisted && (
<> <>
<div className="mailpoet_form_preview_type_select"> <div className="mailpoet_form_preview_type_select">
<label> <label>

View File

@ -7,7 +7,7 @@ use MailPoet\API\JSON\Error as APIError;
use MailPoet\Config\AccessControl; use MailPoet\Config\AccessControl;
use MailPoet\Form\DisplayFormInWPContent; use MailPoet\Form\DisplayFormInWPContent;
use MailPoet\Form\FormFactory; use MailPoet\Form\FormFactory;
use MailPoet\Form\Renderer as FormRenderer; use MailPoet\Form\PreviewPage;
use MailPoet\Form\Util; use MailPoet\Form\Util;
use MailPoet\Listing; use MailPoet\Listing;
use MailPoet\Models\Form; use MailPoet\Models\Form;
@ -23,18 +23,15 @@ class Forms extends APIEndpoint {
/** @var Listing\Handler */ /** @var Listing\Handler */
private $listingHandler; private $listingHandler;
/** @var Util\Styles */
private $formStylesUtils;
/** @var UserFlagsController */ /** @var UserFlagsController */
private $userFlags; private $userFlags;
/** @var FormRenderer */
private $formRenderer;
/** @var FormFactory */ /** @var FormFactory */
private $formFactory; private $formFactory;
/** @var WPFunctions */
private $wp;
public $permissions = [ public $permissions = [
'global' => AccessControl::PERMISSION_MANAGE_FORMS, 'global' => AccessControl::PERMISSION_MANAGE_FORMS,
]; ];
@ -42,17 +39,15 @@ class Forms extends APIEndpoint {
public function __construct( public function __construct(
Listing\BulkActionController $bulkAction, Listing\BulkActionController $bulkAction,
Listing\Handler $listingHandler, Listing\Handler $listingHandler,
Util\Styles $formStylesUtils,
UserFlagsController $userFlags, UserFlagsController $userFlags,
FormRenderer $formRenderer, FormFactory $formFactory,
FormFactory $formFactory WPFunctions $wp
) { ) {
$this->bulkAction = $bulkAction; $this->bulkAction = $bulkAction;
$this->listingHandler = $listingHandler; $this->listingHandler = $listingHandler;
$this->formStylesUtils = $formStylesUtils;
$this->userFlags = $userFlags; $this->userFlags = $userFlags;
$this->formRenderer = $formRenderer;
$this->formFactory = $formFactory; $this->formFactory = $formFactory;
$this->wp = $wp;
} }
public function get($data = []) { public function get($data = []) {
@ -107,20 +102,12 @@ class Forms extends APIEndpoint {
} }
public function previewEditor($data = []) { public function previewEditor($data = []) {
// html $formId = $data['id'] ?? null;
$html = $this->formRenderer->renderHTML($data); if (!$formId) {
$this->badRequest();
// convert shortcodes }
$html = WPFunctions::get()->doShortcode($html); $this->wp->setTransient(PreviewPage::PREVIEW_DATA_TRANSIENT_PREFIX . $formId, $data, PreviewPage::PREVIEW_DATA_EXPIRATION);
return $this->successResponse();
// styles
$css = $this->formStylesUtils->render($this->formRenderer->getStyles($data));
return $this->successResponse([
'html' => $html,
'css' => $css,
'form_element_styles' => $this->formRenderer->renderFormElementStyles($data),
]);
} }
public function exportsEditor($data = []) { public function exportsEditor($data = []) {

View File

@ -6,6 +6,9 @@ use MailPoet\Config\Renderer as TemplateRenderer;
use MailPoet\WP\Functions as WPFunctions; use MailPoet\WP\Functions as WPFunctions;
class PreviewPage { class PreviewPage {
const PREVIEW_DATA_TRANSIENT_PREFIX = 'mailpoet_form_preview_';
const PREVIEW_DATA_EXPIRATION = 84600; // 1 DAY
/** @var WPFunctions */ /** @var WPFunctions */
private $wp; private $wp;
@ -52,6 +55,10 @@ class PreviewPage {
* @return array|null * @return array|null
*/ */
private function fetchFormData(int $id) { private function fetchFormData(int $id) {
$formData = $this->wp->getTransient(self::PREVIEW_DATA_TRANSIENT_PREFIX . $id);
if (is_array($formData)) {
return $formData;
}
$form = $this->formRepository->findOneById($id); $form = $this->formRepository->findOneById($id);
if ($form) { if ($form) {
return [ return [

View File

@ -5,8 +5,10 @@ namespace MailPoet\Test\API\JSON\v1;
use MailPoet\API\JSON\Response as APIResponse; use MailPoet\API\JSON\Response as APIResponse;
use MailPoet\API\JSON\v1\Forms; use MailPoet\API\JSON\v1\Forms;
use MailPoet\DI\ContainerWrapper; use MailPoet\DI\ContainerWrapper;
use MailPoet\Form\PreviewPage;
use MailPoet\Models\Form; use MailPoet\Models\Form;
use MailPoet\Models\Segment; use MailPoet\Models\Segment;
use MailPoet\WP\Functions as WPFunctions;
class FormsTest extends \MailPoetTest { class FormsTest extends \MailPoetTest {
public $form3; public $form3;
@ -16,9 +18,13 @@ class FormsTest extends \MailPoetTest {
/** @var Forms */ /** @var Forms */
private $endpoint; private $endpoint;
/** @var WPFunctions */
private $wp;
public function _before() { public function _before() {
parent::_before(); parent::_before();
$this->endpoint = ContainerWrapper::getInstance()->get(Forms::class); $this->endpoint = ContainerWrapper::getInstance()->get(Forms::class);
$this->wp = WPFunctions::get();
$this->form1 = Form::createOrUpdate(['name' => 'Form 1']); $this->form1 = Form::createOrUpdate(['name' => 'Form 1']);
$this->form2 = Form::createOrUpdate(['name' => 'Form 2']); $this->form2 = Form::createOrUpdate(['name' => 'Form 2']);
$this->form3 = Form::createOrUpdate(['name' => 'Form 3']); $this->form3 = Form::createOrUpdate(['name' => 'Form 3']);
@ -78,17 +84,21 @@ class FormsTest extends \MailPoetTest {
); );
} }
public function testItCanPreviewAForm() { public function testItCanStoreDataForPreview() {
$response = $this->endpoint->create(); $response = $this->endpoint->create();
$formId = $response->data['id'];
expect($response->status)->equals(APIResponse::STATUS_OK); expect($response->status)->equals(APIResponse::STATUS_OK);
expect($response->data)->equals( expect($response->data)->equals(
Form::where('id', $response->data['id'])->findOne()->asArray() Form::where('id', $formId)->findOne()->asArray()
); );
$response->data['styles'] = '/* Custom Styles */';
$response = $this->endpoint->previewEditor($response->data); $response = $this->endpoint->previewEditor($response->data);
expect($response->status)->equals(APIResponse::STATUS_OK); expect($response->status)->equals(APIResponse::STATUS_OK);
expect($response->data['html'])->notEmpty(); $storedData = $this->wp->getTransient(PreviewPage::PREVIEW_DATA_TRANSIENT_PREFIX . $formId);
expect($response->data['css'])->notEmpty(); expect($storedData['body'])->notEmpty();
expect($storedData['styles'])->notEmpty();
expect($storedData['settings'])->notEmpty();
} }
public function testItCanExportAForm() { public function testItCanExportAForm() {