diff --git a/assets/js/src/form_editor/components/form_settings/form_placement_panel.jsx b/assets/js/src/form_editor/components/form_settings/form_placement_panel.jsx index 8de2deb692..1ed5937e9b 100644 --- a/assets/js/src/form_editor/components/form_settings/form_placement_panel.jsx +++ b/assets/js/src/form_editor/components/form_settings/form_placement_panel.jsx @@ -5,7 +5,7 @@ import { TextareaControl, ToggleControl, } from '@wordpress/components'; -import { useSelect } from '@wordpress/data'; +import { useDispatch, useSelect } from '@wordpress/data'; import MailPoet from 'mailpoet'; import ReactStringReplace from 'react-string-replace'; import { curry } from 'lodash'; @@ -29,6 +29,8 @@ const FormPlacementPanel = ({ onToggle, isOpened }) => { [] ); + const { setPlaceFormBellowAllPages, setPlaceFormBellowAllPosts } = useDispatch('mailpoet-form-editor'); + const exportLinkClicked = curry((type, event) => { event.preventDefault(); MailPoet.trackEvent('Forms > Embed', { @@ -97,12 +99,12 @@ const FormPlacementPanel = ({ onToggle, isOpened }) => { {}} + onChange={setPlaceFormBellowAllPages} /> {}} + onChange={setPlaceFormBellowAllPosts} />

{addFormShortcodeHint}

{addFormWidgetHint}

diff --git a/assets/js/src/form_editor/store/actions.jsx b/assets/js/src/form_editor/store/actions.jsx index 0f200d7741..0166cf5f3c 100644 --- a/assets/js/src/form_editor/store/actions.jsx +++ b/assets/js/src/form_editor/store/actions.jsx @@ -20,6 +20,20 @@ export function changeFormName(name) { }; } +export function setPlaceFormBellowAllPages(place) { + return { + type: 'PLACE_FORM_BELLOW_ALL_PAGES', + place, + }; +} + +export function setPlaceFormBellowAllPosts(place) { + return { + type: 'PLACE_FORM_BELLOW_ALL_POSTS', + place, + }; +} + export function deleteCustomFieldStarted() { return { type: 'DELETE_CUSTOM_FIELD_STARTED', diff --git a/assets/js/src/form_editor/store/controls.jsx b/assets/js/src/form_editor/store/controls.jsx index 2bdf96234f..4fccacb753 100644 --- a/assets/js/src/form_editor/store/controls.jsx +++ b/assets/js/src/form_editor/store/controls.jsx @@ -6,6 +6,7 @@ import blocksToFormBody from './blocks_to_form_body.jsx'; import formatCustomFieldBlockName from '../blocks/format_custom_field_block_name.jsx'; import getCustomFieldBlockSettings from '../blocks/custom_fields_blocks.jsx'; import { registerCustomFieldBlock } from '../blocks/blocks.jsx'; +import mapFormDataBeforeSaving from './map_form_data_before_saving.jsx'; const formatApiErrorMessage = (response) => { let errorMessage = null; @@ -30,7 +31,7 @@ export default { const formBlocks = select('mailpoet-form-editor').getFormBlocks(); const customFields = select('mailpoet-form-editor').getAllAvailableCustomFields(); const requestData = { - ...formData, + ...mapFormDataBeforeSaving(formData), body: blocksToFormBody(formBlocks, customFields), editor_version: 2, }; diff --git a/assets/js/src/form_editor/store/map_form_data_after_loading.jsx b/assets/js/src/form_editor/store/map_form_data_after_loading.jsx new file mode 100644 index 0000000000..41dab37876 --- /dev/null +++ b/assets/js/src/form_editor/store/map_form_data_after_loading.jsx @@ -0,0 +1,10 @@ +export default function mapFormDataAfterLoading(data) { + return { + ...data, + settings: { + ...data.settings, + placeFormBellowAllPages: data.settings.placeFormBellowAllPages === '1', + placeFormBellowAllPosts: data.settings.placeFormBellowAllPosts === '1', + }, + }; +} diff --git a/assets/js/src/form_editor/store/map_form_data_before_saving.jsx b/assets/js/src/form_editor/store/map_form_data_before_saving.jsx new file mode 100644 index 0000000000..b940788913 --- /dev/null +++ b/assets/js/src/form_editor/store/map_form_data_before_saving.jsx @@ -0,0 +1,10 @@ +export default function mapFormDataBeforeSaving(data) { + return { + ...data, + settings: { + ...data.settings, + placeFormBellowAllPages: data.settings.placeFormBellowAllPages === true ? '1' : '', + placeFormBellowAllPosts: data.settings.placeFormBellowAllPosts === true ? '1' : '', + }, + }; +} diff --git a/assets/js/src/form_editor/store/reducer.jsx b/assets/js/src/form_editor/store/reducer.jsx index f9f59177b0..f926a3f8a4 100644 --- a/assets/js/src/form_editor/store/reducer.jsx +++ b/assets/js/src/form_editor/store/reducer.jsx @@ -4,6 +4,10 @@ import createCustomFieldFailed from './reducers/create_custom_field_failed.jsx'; import customFieldEdited from './reducers/custom_field_edited.jsx'; import createCustomFieldStartedFactory from './reducers/create_custom_field_started.jsx'; import changeFormName from './reducers/change_form_name.jsx'; +import { + placeFormBellowAllPages, + placeFormBellowAllPosts, +} from './reducers/form_placement.jsx'; import changeFormSettings from './reducers/change_form_settings.jsx'; import changeFormStyles from './reducers/change_form_styles.jsx'; import removeNotice from './reducers/remove_notice.jsx'; @@ -49,6 +53,8 @@ export default (defaultState) => (state = defaultState, action) => { case 'DELETE_CUSTOM_FIELD_STARTED': return customFieldDeleteStart(state, action); case 'DELETE_CUSTOM_FIELD_DONE': return customFieldDeleteDone(state, action); case 'DELETE_CUSTOM_FIELD_FAILED': return customFieldDeleteFailed(state, action); + case 'PLACE_FORM_BELLOW_ALL_PAGES': return placeFormBellowAllPages(state, action); + case 'PLACE_FORM_BELLOW_ALL_POSTS': return placeFormBellowAllPosts(state, action); default: return state; } diff --git a/assets/js/src/form_editor/store/reducers/form_placement.jsx b/assets/js/src/form_editor/store/reducers/form_placement.jsx new file mode 100644 index 0000000000..383fbb084d --- /dev/null +++ b/assets/js/src/form_editor/store/reducers/form_placement.jsx @@ -0,0 +1,23 @@ +export const placeFormBellowAllPosts = (state, action) => ({ + ...state, + formData: { + ...state.formData, + hasUnsavedChanges: true, + settings: { + ...state.formData.settings, + placeFormBellowAllPosts: action.place, + }, + }, +}); + +export const placeFormBellowAllPages = (state, action) => ({ + ...state, + formData: { + ...state.formData, + hasUnsavedChanges: true, + settings: { + ...state.formData.settings, + placeFormBellowAllPages: action.place, + }, + }, +}); diff --git a/assets/js/src/form_editor/store/store.jsx b/assets/js/src/form_editor/store/store.jsx index ef4d2fa883..42a817976a 100644 --- a/assets/js/src/form_editor/store/store.jsx +++ b/assets/js/src/form_editor/store/store.jsx @@ -9,6 +9,7 @@ import selectors from './selectors.jsx'; import controls from './controls.jsx'; import validateForm from './form_validator.jsx'; import { formBodyToBlocks } from './form_body_to_blocks.jsx'; +import mapFormDataAfterLoading from './map_form_data_after_loading.jsx'; export default () => { const formData = { ...window.mailpoet_form_data }; @@ -22,7 +23,7 @@ export default () => { formData.settings.segments = formData.settings.segments ? formData.settings.segments : []; const defaultState = { formBlocks, - formData, + formData: mapFormDataAfterLoading(formData), dateSettingData, sidebarOpened: true, formExports: window.mailpoet_form_exports, diff --git a/tests/javascript/form_editor/store/map_form_data_after_loading.jsx b/tests/javascript/form_editor/store/map_form_data_after_loading.jsx new file mode 100644 index 0000000000..ea6af48c8e --- /dev/null +++ b/tests/javascript/form_editor/store/map_form_data_after_loading.jsx @@ -0,0 +1,62 @@ +import { expect } from 'chai'; +import map from '../../../../assets/js/src/form_editor/store/map_form_data_after_loading.jsx'; + +const data = { + id: '1', + name: 'My First Form', + settings: { + segments: ['3'], + on_success: 'message', + success_message: 'Check your inbox or spam folder to confirm your subscription.', + success_page: '5', + segments_selected_by: 'admin', + placeFormBellowAllPages: '1', + placeFormBellowAllPosts: '', + }, + styles: 'styles definition', + created_at: '2020-01-15 07:39:15', + updated_at: '2020-01-28 10:28:02', + deleted_at: null, +}; + + +describe('Form Data Load Mapper', () => { + it('Returns ID', () => { + expect(map(data)).to.have.property('id', '1'); + }); + + it('Returns name', () => { + expect(map(data)).to.have.property('name', 'My First Form'); + }); + + it('Returns styles', () => { + expect(map(data)).to.have.property('styles', 'styles definition'); + }); + + it('Returns dates', () => { + expect(map(data)).to.have.property('created_at', '2020-01-15 07:39:15'); + expect(map(data)).to.have.property('updated_at', '2020-01-28 10:28:02'); + expect(map(data)).to.have.property('deleted_at').that.is.null; + }); + + describe('Settings', () => { + it('Maps settings', () => { + expect(map(data)).to.have.property('settings').that.is.an('object'); + }); + + it('Maps segments', () => { + expect(map(data).settings).to.have.property('segments').that.deep.eq(['3']); + }); + + it('Maps Success', () => { + expect(map(data).settings).to.have.property('on_success', 'message'); + expect(map(data).settings).to.have.property('success_message', 'Check your inbox or spam folder to confirm your subscription.'); + expect(map(data).settings).to.have.property('success_page', '5'); + }); + + it('maps placement', () => { + expect(map(data).settings).to.have.property('placeFormBellowAllPages', true); + expect(map(data).settings).to.have.property('placeFormBellowAllPosts', false); + }); + }); +}); diff --git a/tests/javascript/form_editor/store/map_form_data_before_saving.spec.js b/tests/javascript/form_editor/store/map_form_data_before_saving.spec.js new file mode 100644 index 0000000000..0f61d0d7de --- /dev/null +++ b/tests/javascript/form_editor/store/map_form_data_before_saving.spec.js @@ -0,0 +1,62 @@ +import { expect } from 'chai'; +import map from '../../../../assets/js/src/form_editor/store/map_form_data_before_saving.jsx'; + +const data = { + id: '1', + name: 'My First Form', + settings: { + segments: ['3'], + on_success: 'message', + success_message: 'Check your inbox or spam folder to confirm your subscription.', + success_page: '5', + segments_selected_by: 'admin', + placeFormBellowAllPages: true, + placeFormBellowAllPosts: false, + }, + styles: 'styles definition', + created_at: '2020-01-15 07:39:15', + updated_at: '2020-01-28 10:28:02', + deleted_at: null, +}; + + +describe('Form Data Save Mapper', () => { + it('Returns ID', () => { + expect(map(data)).to.have.property('id', '1'); + }); + + it('Returns name', () => { + expect(map(data)).to.have.property('name', 'My First Form'); + }); + + it('Returns styles', () => { + expect(map(data)).to.have.property('styles', 'styles definition'); + }); + + it('Returns dates', () => { + expect(map(data)).to.have.property('created_at', '2020-01-15 07:39:15'); + expect(map(data)).to.have.property('updated_at', '2020-01-28 10:28:02'); + expect(map(data)).to.have.property('deleted_at').that.is.null; + }); + + describe('Settings', () => { + it('Maps settings', () => { + expect(map(data)).to.have.property('settings').that.is.an('object'); + }); + + it('Maps segments', () => { + expect(map(data).settings).to.have.property('segments').that.deep.eq(['3']); + }); + + it('Maps Success', () => { + expect(map(data).settings).to.have.property('on_success', 'message'); + expect(map(data).settings).to.have.property('success_message', 'Check your inbox or spam folder to confirm your subscription.'); + expect(map(data).settings).to.have.property('success_page', '5'); + }); + + it('maps placement', () => { + expect(map(data).settings).to.have.property('placeFormBellowAllPages', '1'); + expect(map(data).settings).to.have.property('placeFormBellowAllPosts', ''); + }); + }); +});