Use block editor's color settings for block colors mapping

[MAILPOET-2754]
This commit is contained in:
Rostislav Wolny
2020-03-11 10:25:01 +01:00
committed by Veljko V
parent 4ec53d2d52
commit 8a66fd1811
7 changed files with 364 additions and 270 deletions

View File

@@ -60,140 +60,161 @@ const mapCustomField = (block, customFields, mappedCommonProperties) => {
};
/**
* Transforms blocks to form.body data structure.
* @param blocks - blocks representation taken from @wordpress/block-editor
* @param customFields - list of all custom Fields
* @param parent - parent block of nested block
* @param {Array.<{name: string, slug: string, color: string}>} colorDefinitions
* @param {string} colorSlug
* @param {string} colorValue
*/
const mapBlocks = (blocks, customFields = [], parent = null) => {
if (!Array.isArray(blocks)) {
throw new Error('Mapper expects blocks to be an array.');
}
if (!Array.isArray(customFields)) {
throw new Error('Mapper expects customFields to be an array.');
}
return blocks.map((block, index) => {
const mapped = {
type: 'text',
unique: '0',
static: '1',
position: (index + 1).toString(),
params: {
label: block.attributes.label,
},
};
if (block.attributes.mandatory) {
mapped.params.required = '1';
}
if (block.attributes.labelWithinInput) {
mapped.params.label_within = '1';
}
const childrenCount = parent ? parent.innerBlocks.length : 1;
switch (block.name) {
case 'core/column':
return {
position: (index + 1).toString(),
type: 'column',
params: {
class_name: block.attributes.className || null,
vertical_alignment: block.attributes.verticalAlignment || null,
width: block.attributes.width
? block.attributes.width : Math.round(100 / childrenCount),
},
body: mapBlocks(block.innerBlocks, customFields, block),
};
case 'core/columns':
return {
position: (index + 1).toString(),
type: 'columns',
body: mapBlocks(block.innerBlocks, customFields, block),
params: {
vertical_alignment: block.attributes.verticalAlignment || null,
class_name: block.attributes.className || null,
text_color: block.attributes.textColor || null,
background_color: block.attributes.backgroundColor || null,
custom_text_color: block.attributes.customTextColor || null,
custom_background_color: block.attributes.customBackgroundColor || null,
},
};
case 'mailpoet-form/email-input':
return {
...mapped,
id: 'email',
name: 'Email',
params: {
...mapped.params,
required: '1',
},
};
case 'mailpoet-form/first-name-input':
return {
...mapped,
id: 'first_name',
unique: '1',
static: '0',
name: 'First name',
};
case 'mailpoet-form/last-name-input':
return {
...mapped,
id: 'last_name',
unique: '1',
static: '0',
name: 'Last name',
};
case 'mailpoet-form/segment-select':
return {
...mapped,
id: 'segments',
type: 'segment',
unique: '1',
static: '0',
name: 'List selection',
params: {
...mapped.params,
values: block.attributes.values.map((segment) => ({
id: segment.id,
is_checked: segment.isChecked ? '1' : undefined,
name: segment.name,
})),
},
};
case 'mailpoet-form/submit-button':
return {
...mapped,
id: 'submit',
type: 'submit',
name: 'Submit',
};
case 'mailpoet-form/divider':
return {
...mapped,
id: 'divider',
type: 'divider',
name: 'Divider',
static: '0',
params: '',
};
case 'mailpoet-form/html':
return {
...mapped,
id: 'html',
type: 'html',
name: 'Custom text or HTML',
static: '0',
params: {
text: block.attributes && block.attributes.content ? block.attributes.content : '',
nl2br: block.attributes && block.attributes.nl2br ? '1' : '0',
},
};
default:
if (block.name.startsWith('mailpoet-form/custom-')) {
return mapCustomField(block, customFields, mapped);
}
return null;
}
}).filter(Boolean);
const mapColor = (colorDefinitions, colorSlug, colorValue = null) => {
const result = colorDefinitions.find((color) => color.slug === colorSlug);
return result ? result.color : colorValue;
};
export default mapBlocks;
/**
* Factory for block to form data mapper
* @param {Array.<{name: string, slug: string, color: string}>} colorDefinitions
* @param customFields - list of all custom Fields
*/
export default (colorDefinitions, customFields = []) => {
/**
* @param blocks
* @param parent - parent block of nested block
* @returns {*}
*/
const mapBlocks = (blocks, parent = null) => {
if (!Array.isArray(blocks)) {
throw new Error('Mapper expects blocks to be an array.');
}
if (!Array.isArray(customFields)) {
throw new Error('Mapper expects customFields to be an array.');
}
return blocks.map((block, index) => {
const mapped = {
type: 'text',
unique: '0',
static: '1',
position: (index + 1).toString(),
params: {
label: block.attributes.label,
},
};
if (block.attributes.mandatory) {
mapped.params.required = '1';
}
if (block.attributes.labelWithinInput) {
mapped.params.label_within = '1';
}
const childrenCount = parent ? parent.innerBlocks.length : 1;
switch (block.name) {
case 'core/column':
return {
position: (index + 1).toString(),
type: 'column',
params: {
class_name: block.attributes.className || null,
vertical_alignment: block.attributes.verticalAlignment || null,
width: block.attributes.width
? block.attributes.width : Math.round(100 / childrenCount),
},
body: mapBlocks(block.innerBlocks, block),
};
case 'core/columns':
return {
position: (index + 1).toString(),
type: 'columns',
body: mapBlocks(block.innerBlocks, block),
params: {
vertical_alignment: block.attributes.verticalAlignment || null,
class_name: block.attributes.className || null,
text_color: mapColor(
colorDefinitions,
block.attributes.textColor,
block.attributes.customTextColor
),
background_color: mapColor(
colorDefinitions,
block.attributes.backgroundColor,
block.attributes.customBackgroundColor
),
},
};
case 'mailpoet-form/email-input':
return {
...mapped,
id: 'email',
name: 'Email',
params: {
...mapped.params,
required: '1',
},
};
case 'mailpoet-form/first-name-input':
return {
...mapped,
id: 'first_name',
unique: '1',
static: '0',
name: 'First name',
};
case 'mailpoet-form/last-name-input':
return {
...mapped,
id: 'last_name',
unique: '1',
static: '0',
name: 'Last name',
};
case 'mailpoet-form/segment-select':
return {
...mapped,
id: 'segments',
type: 'segment',
unique: '1',
static: '0',
name: 'List selection',
params: {
...mapped.params,
values: block.attributes.values.map((segment) => ({
id: segment.id,
is_checked: segment.isChecked ? '1' : undefined,
name: segment.name,
})),
},
};
case 'mailpoet-form/submit-button':
return {
...mapped,
id: 'submit',
type: 'submit',
name: 'Submit',
};
case 'mailpoet-form/divider':
return {
...mapped,
id: 'divider',
type: 'divider',
name: 'Divider',
static: '0',
params: '',
};
case 'mailpoet-form/html':
return {
...mapped,
id: 'html',
type: 'html',
name: 'Custom text or HTML',
static: '0',
params: {
text: block.attributes && block.attributes.content ? block.attributes.content : '',
nl2br: block.attributes && block.attributes.nl2br ? '1' : '0',
},
};
default:
if (block.name.startsWith('mailpoet-form/custom-')) {
return mapCustomField(block, customFields, mapped);
}
return null;
}
}).filter(Boolean);
};
return mapBlocks;
};

View File

@@ -2,7 +2,7 @@ import { select, dispatch } from '@wordpress/data';
import MailPoet from 'mailpoet';
import { merge } from 'lodash';
import { createBlock, unregisterBlockType } from '@wordpress/blocks';
import blocksToFormBody from './blocks_to_form_body.jsx';
import blocksToFormBodyFactory 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';
@@ -31,9 +31,11 @@ export default {
const formData = select('mailpoet-form-editor').getFormData();
const formBlocks = select('mailpoet-form-editor').getFormBlocks();
const customFields = select('mailpoet-form-editor').getAllAvailableCustomFields();
const { getSettings } = select('core/block-editor');
const blocksToFormBody = blocksToFormBodyFactory(getSettings().colors, customFields);
const requestData = {
...mapFormDataBeforeSaving(formData),
body: blocksToFormBody(formBlocks, customFields),
body: blocksToFormBody(formBlocks),
editor_version: 2,
};
MailPoet.Ajax.post({

View File

@@ -57,15 +57,27 @@ const mapCustomField = (item, customFields, mappedCommonProperties) => {
return mapped;
};
const mapColumnBlocks = (data, customFields = []) => {
/**
* @param {Array.<{name: string, slug: string, color: string}>} colorDefinitions
* @param {string} colorValue
*/
const mapColorSlug = (colorDefinitions, colorValue) => {
const result = colorDefinitions.find((color) => color.color === colorValue);
return result ? result.slug : undefined;
};
const mapColumnBlocks = (data, colorDefinitions, customFields = []) => {
// eslint-disable-next-line no-use-before-define
const mapFormBodyToBlocks = formBodyToBlocksFactory(colorDefinitions, customFields);
const mapped = {
clientId: generateId(),
name: `core/${data.type}`,
isValid: true,
attributes: {},
// eslint-disable-next-line no-use-before-define
innerBlocks: formBodyToBlocks(data.body ? data.body : [], customFields),
innerBlocks: mapFormBodyToBlocks(data.body ? data.body : []),
};
const textColorSlug = mapColorSlug(colorDefinitions, data.params.text_color);
const backgroundColorSlug = mapColorSlug(colorDefinitions, data.params.background_color);
if (has(data.params, 'width')) {
mapped.attributes.width = parseFloat(data.params.width);
}
@@ -73,16 +85,13 @@ const mapColumnBlocks = (data, customFields = []) => {
mapped.attributes.verticalAlignment = data.params.vertical_alignment;
}
if (has(data.params, 'text_color')) {
mapped.attributes.textColor = data.params.text_color;
}
if (has(data.params, 'custom_text_color')) {
mapped.attributes.customTextColor = data.params.custom_text_color;
mapped.attributes.textColor = textColorSlug;
mapped.attributes.customTextColor = !textColorSlug ? data.params.text_color : undefined;
}
if (has(data.params, 'background_color')) {
mapped.attributes.backgroundColor = data.params.background_color;
}
if (has(data.params, 'custom_background_color')) {
mapped.attributes.customBackgroundColor = data.params.custom_background_color;
mapped.attributes.backgroundColor = backgroundColorSlug;
mapped.attributes.customBackgroundColor = !backgroundColorSlug
? data.params.background_color : undefined;
}
if (has(data.params, 'class_name') && data.params.class_name) {
mapped.attributes.className = data.params.class_name;
@@ -91,101 +100,110 @@ const mapColumnBlocks = (data, customFields = []) => {
};
/**
* Transforms form body items to array of blocks which can be passed to block editor.
* @param {array} data - from form.body property
* @param {array} customFields - list of all custom fields
* Factory for form data to blocks mapper
* @param {Array.<{name: string, slug: string, color: string}>} colorDefinitions
* @param customFields - list of all custom Fields
*/
export const formBodyToBlocks = (data, customFields = []) => {
if (!Array.isArray(data)) {
throw new Error('Mapper expects form body to be an array.');
}
export const formBodyToBlocksFactory = (colorDefinitions, customFields = []) => {
if (!Array.isArray(customFields)) {
throw new Error('Mapper expects customFields to be an array.');
}
return data.map((item, index) => {
if (['column', 'columns'].includes(item.type)) {
return mapColumnBlocks(item, customFields);
/**
* Transforms form body items to array of blocks which can be passed to block editor.
* @param {array} data - from form.body property
*/
const formBodyToBlocks = (data) => {
if (!Array.isArray(data)) {
throw new Error('Mapper expects form body to be an array.');
}
const mapped = {
clientId: `${item.id}_${index}`,
isValid: true,
innerBlocks: [],
attributes: {
labelWithinInput: false,
mandatory: false,
},
};
if (item.params && has(item.params, 'required')) {
mapped.attributes.mandatory = !!item.params.required;
}
if (item.params && has(item.params, 'label_within')) {
mapped.attributes.labelWithinInput = !!item.params.label_within;
}
if (item.params) {
mapped.attributes.label = item.params.label ? item.params.label : '';
}
switch (item.id) {
case 'email':
return {
...mapped,
name: 'mailpoet-form/email-input',
};
case 'first_name':
return {
...mapped,
name: 'mailpoet-form/first-name-input',
};
case 'last_name':
return {
...mapped,
name: 'mailpoet-form/last-name-input',
};
case 'segments':
if (
item.params
&& has(item.params, 'values')
&& Array.isArray(item.params.values)
) {
mapped.attributes.values = item.params.values.map((value) => ({
id: value.id,
name: value.name,
isChecked: value.is_checked === '1' ? true : undefined,
}));
} else {
mapped.attributes.values = [];
}
return {
...mapped,
name: 'mailpoet-form/segment-select',
};
case 'submit':
return {
...mapped,
name: 'mailpoet-form/submit-button',
};
case 'divider':
delete mapped.attributes.label;
return {
...mapped,
name: 'mailpoet-form/divider',
};
case 'html':
delete mapped.attributes.label;
return {
...mapped,
name: 'mailpoet-form/html',
attributes: {
content: item.params && item.params.text ? item.params.text : '',
nl2br: item.params && item.params.nl2br ? !!item.params.nl2br : false,
},
};
default:
if (Number.isInteger(parseInt(item.id, 10))) {
return mapCustomField(item, customFields, mapped);
}
return null;
}
}).filter(Boolean);
return data.map((item, index) => {
if (['column', 'columns'].includes(item.type)) {
return mapColumnBlocks(item, colorDefinitions, customFields);
}
const mapped = {
clientId: `${item.id}_${index}`,
isValid: true,
innerBlocks: [],
attributes: {
labelWithinInput: false,
mandatory: false,
},
};
if (item.params && has(item.params, 'required')) {
mapped.attributes.mandatory = !!item.params.required;
}
if (item.params && has(item.params, 'label_within')) {
mapped.attributes.labelWithinInput = !!item.params.label_within;
}
if (item.params) {
mapped.attributes.label = item.params.label ? item.params.label : '';
}
switch (item.id) {
case 'email':
return {
...mapped,
name: 'mailpoet-form/email-input',
};
case 'first_name':
return {
...mapped,
name: 'mailpoet-form/first-name-input',
};
case 'last_name':
return {
...mapped,
name: 'mailpoet-form/last-name-input',
};
case 'segments':
if (
item.params
&& has(item.params, 'values')
&& Array.isArray(item.params.values)
) {
mapped.attributes.values = item.params.values.map((value) => ({
id: value.id,
name: value.name,
isChecked: value.is_checked === '1' ? true : undefined,
}));
} else {
mapped.attributes.values = [];
}
return {
...mapped,
name: 'mailpoet-form/segment-select',
};
case 'submit':
return {
...mapped,
name: 'mailpoet-form/submit-button',
};
case 'divider':
delete mapped.attributes.label;
return {
...mapped,
name: 'mailpoet-form/divider',
};
case 'html':
delete mapped.attributes.label;
return {
...mapped,
name: 'mailpoet-form/html',
attributes: {
content: item.params && item.params.text ? item.params.text : '',
nl2br: item.params && item.params.nl2br ? !!item.params.nl2br : false,
},
};
default:
if (Number.isInteger(parseInt(item.id, 10))) {
return mapCustomField(item, customFields, mapped);
}
return null;
}
}).filter(Boolean);
};
return formBodyToBlocks;
};

View File

@@ -3,17 +3,23 @@
* @see https://developer.wordpress.org/block-editor/packages/packages-data/
*/
import { registerStore } from '@wordpress/data';
import { SETTINGS_DEFAULTS } from '@wordpress/block-editor';
import * as actions from './actions.jsx';
import createReducer from './reducer.jsx';
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 { formBodyToBlocksFactory } from './form_body_to_blocks.jsx';
import mapFormDataAfterLoading from './map_form_data_after_loading.jsx';
const formBodyToBlocks = formBodyToBlocksFactory(
SETTINGS_DEFAULTS.colors,
window.mailpoet_custom_fields
);
export default () => {
const formData = { ...window.mailpoet_form_data };
const formBlocks = formBodyToBlocks(formData.body, window.mailpoet_custom_fields);
const formBlocks = formBodyToBlocks(formData.body);
delete formData.body;
const dateSettingData = {
dateTypes: window.mailpoet_date_types,