From aeb2c0d391d906b14a51013fd1c38a22954ef1e7 Mon Sep 17 00:00:00 2001 From: Rostislav Wolny Date: Thu, 2 Jul 2020 13:53:58 +0200 Subject: [PATCH] Add columns gradient mapping from server data to block [MAILPOET-3005] --- .../form_editor/store/form_body_to_blocks.jsx | 41 ++++++++++--- .../src/form_editor/store/form_data_types.ts | 5 ++ .../store/mapping/to_blocks/styles_mapper.ts | 6 ++ assets/js/src/form_editor/store/store.jsx | 3 +- .../store/form_body_to_blocks.spec.js | 61 ++++++++++++------- 5 files changed, 87 insertions(+), 29 deletions(-) diff --git a/assets/js/src/form_editor/store/form_body_to_blocks.jsx b/assets/js/src/form_editor/store/form_body_to_blocks.jsx index bc4d772974..6a19ac82c8 100644 --- a/assets/js/src/form_editor/store/form_body_to_blocks.jsx +++ b/assets/js/src/form_editor/store/form_body_to_blocks.jsx @@ -1,7 +1,12 @@ /* eslint-disable camelcase */ import { has } from 'lodash'; import asNum from './server_value_as_num'; -import { mapInputBlockStyles, mapColorSlug, mapFontSizeSlug } from './mapping/to_blocks/styles_mapper'; +import { + mapInputBlockStyles, + mapColorSlug, + mapFontSizeSlug, + mapGradientSlug, +} from './mapping/to_blocks/styles_mapper'; import formatCustomFieldBlockName from '../blocks/format_custom_field_block_name.jsx'; import { defaultAttributes as dividerDefaultAttributes } from '../blocks/divider/divider_types'; @@ -67,15 +72,23 @@ const mapCustomField = (item, customFields, mappedCommonProperties) => { /** * @param {Object} data - column or columns block data - * @param {Array.<{name: string, slug: string, color: string}>} colorDefinitions * @param {Array.<{name: string, slug: string, size: number}>} fontSizeDefinitions + * @param {Array.<{name: string, slug: string, color: string}>} colorDefinitions + * @param {Array.<{name: string, slug: string, gradient: string}>} gradientDefinitions * @param customFields - list of all custom Fields */ -const mapColumnBlocks = (data, fontSizeDefinitions, colorDefinitions, customFields = []) => { +const mapColumnBlocks = ( + data, + fontSizeDefinitions, + colorDefinitions, + gradientDefinitions, + customFields = [] +) => { // eslint-disable-next-line no-use-before-define const mapFormBodyToBlocks = formBodyToBlocksFactory( - colorDefinitions, fontSizeDefinitions, + colorDefinitions, + gradientDefinitions, customFields ); const mapped = { @@ -91,6 +104,7 @@ const mapColumnBlocks = (data, fontSizeDefinitions, colorDefinitions, customFiel }; const textColorSlug = mapColorSlug(colorDefinitions, data.params.text_color); const backgroundColorSlug = mapColorSlug(colorDefinitions, data.params.background_color); + const gradientSlug = mapGradientSlug(gradientDefinitions, data.params.gradient); if (has(data.params, 'width')) { mapped.attributes.width = parseFloat(data.params.width); } @@ -106,6 +120,11 @@ const mapColumnBlocks = (data, fontSizeDefinitions, colorDefinitions, customFiel mapped.attributes.style.color.background = !backgroundColorSlug ? data.params.background_color : undefined; } + if (has(data.params, 'gradient')) { + mapped.attributes.gradient = gradientSlug; + mapped.attributes.style.color.gradient = !gradientSlug + ? data.params.gradient : undefined; + } if (has(data.params, 'class_name') && data.params.class_name) { mapped.attributes.className = data.params.class_name; } @@ -114,13 +133,15 @@ const mapColumnBlocks = (data, fontSizeDefinitions, colorDefinitions, customFiel /** * Factory for form data to blocks mapper - * @param {Array.<{name: string, slug: string, color: string}>} colorDefinitions * @param {Array.<{name: string, slug: string, size: number}>} fontSizeDefinitions + * @param {Array.<{name: string, slug: string, color: string}>} colorDefinitions + * @param {Array.<{name: string, slug: string, gradient: string}>} gradientsDefinitions * @param customFields - list of all custom Fields */ export const formBodyToBlocksFactory = ( - colorDefinitions, fontSizeDefinitions, + colorDefinitions, + gradientsDefinitions, customFields = [] ) => { if (!Array.isArray(customFields)) { @@ -138,7 +159,13 @@ export const formBodyToBlocksFactory = ( return data.map((item) => { if (['column', 'columns'].includes(item.type)) { - return mapColumnBlocks(item, fontSizeDefinitions, colorDefinitions, customFields); + return mapColumnBlocks( + item, + fontSizeDefinitions, + colorDefinitions, + gradientsDefinitions, + customFields + ); } const mapped = { diff --git a/assets/js/src/form_editor/store/form_data_types.ts b/assets/js/src/form_editor/store/form_data_types.ts index bbcc0e5dce..b963beb222 100644 --- a/assets/js/src/form_editor/store/form_data_types.ts +++ b/assets/js/src/form_editor/store/form_data_types.ts @@ -71,6 +71,11 @@ export type ColorDefinition = { color: string, } +export type GradientDefinition = { + name: string, + slug: string, + gradient: string, +} export type FontSizeDefinition = { name: string, diff --git a/assets/js/src/form_editor/store/mapping/to_blocks/styles_mapper.ts b/assets/js/src/form_editor/store/mapping/to_blocks/styles_mapper.ts index b9610baf26..996c31d334 100644 --- a/assets/js/src/form_editor/store/mapping/to_blocks/styles_mapper.ts +++ b/assets/js/src/form_editor/store/mapping/to_blocks/styles_mapper.ts @@ -4,6 +4,7 @@ import { InputBlockStylesServerData, FontSizeDefinition, ColorDefinition, + GradientDefinition, } from 'form_editor/store/form_data_types'; import asNum from '../../server_value_as_num'; @@ -61,6 +62,11 @@ export const mapColorSlug = (colorDefinitions: ColorDefinition[], colorValue) => return result ? result.slug : undefined; }; +export const mapGradientSlug = (definitions: GradientDefinition[], value) => { + const result = definitions.find((color) => color.gradient === value); + return result ? result.slug : undefined; +}; + export const mapFontSizeSlug = (fontSizeDefinitions: FontSizeDefinition[], fontSizeValue) => { let value = 0; if (fontSizeValue) { diff --git a/assets/js/src/form_editor/store/store.jsx b/assets/js/src/form_editor/store/store.jsx index ae1dbefe53..3e5588bd40 100644 --- a/assets/js/src/form_editor/store/store.jsx +++ b/assets/js/src/form_editor/store/store.jsx @@ -26,8 +26,9 @@ export default () => { ); const formBodyToBlocks = formBodyToBlocksFactory( - SETTINGS_DEFAULTS.colors, SETTINGS_DEFAULTS.fontSizes, + SETTINGS_DEFAULTS.colors, + SETTINGS_DEFAULTS.gradients, customFields ); diff --git a/tests/javascript/form_editor/store/form_body_to_blocks.spec.js b/tests/javascript/form_editor/store/form_body_to_blocks.spec.js index c506b4d9f7..d7c686a4a9 100644 --- a/tests/javascript/form_editor/store/form_body_to_blocks.spec.js +++ b/tests/javascript/form_editor/store/form_body_to_blocks.spec.js @@ -1,4 +1,5 @@ import { expect } from 'chai'; +import { partial } from 'lodash'; import { formBodyToBlocksFactory } from '../../../../assets/js/src/form_editor/store/form_body_to_blocks.jsx'; import { @@ -24,9 +25,16 @@ import { import { fontSizeDefinitions, colorDefinitions, + gradientDefinitions, } from './editor_settings'; -const formBodyToBlocks = formBodyToBlocksFactory(colorDefinitions, fontSizeDefinitions, []); +const getMapper = partial( + formBodyToBlocksFactory, + fontSizeDefinitions, + colorDefinitions, + gradientDefinitions +); +const formBodyToBlocks = getMapper([]); const checkBlockBasics = (block) => { expect(block.clientId).to.be.a('string'); @@ -47,10 +55,10 @@ describe('Form Body To Blocks', () => { it('Should throw an error for wrong custom fields input', () => { const error = 'Mapper expects customFields to be an array.'; - expect(() => formBodyToBlocksFactory([], [], null)).to.throw(error); - expect(() => formBodyToBlocksFactory([], [], 'hello')).to.throw(error); - expect(() => formBodyToBlocksFactory([], [], () => {})).to.throw(error); - expect(() => formBodyToBlocksFactory([], [], 1)).to.throw(error); + expect(() => getMapper(null)).to.throw(error); + expect(() => getMapper('hello')).to.throw(error); + expect(() => getMapper(() => {})).to.throw(error); + expect(() => getMapper(1)).to.throw(error); }); it('Should map email input to block', () => { @@ -88,11 +96,7 @@ describe('Form Body To Blocks', () => { type: 'textarea', updated_at: '2019-12-10T15:05:06+00:00', }; - const map = formBodyToBlocksFactory( - colorDefinitions, - [], - [customFieldText, customFieldTextarea] - ); + const map = getMapper([customFieldText, customFieldTextarea]); const [email, firstName, lastName, customText, customTextArea, submit] = map([ { ...emailInput, position: '1' }, { ...firstNameInput, position: '2' }, @@ -140,7 +144,7 @@ describe('Form Body To Blocks', () => { border_color: '#cccccc', }; - const map = formBodyToBlocksFactory(colorDefinitions, [], [customFieldText]); + const map = getMapper([customFieldText]); const [email, customText] = map([ { ...emailInput, styles: emailStyles }, { ...customTextInput, styles: customTextStyles }, @@ -176,9 +180,7 @@ describe('Form Body To Blocks', () => { font_color: '#aaaaaa', }; - const map = formBodyToBlocksFactory(colorDefinitions); - - const [defaultSubmit, styledSubmit] = map([ + const [defaultSubmit, styledSubmit] = formBodyToBlocks([ { ...submitInput, styles: defaultSubmitStyles }, { ...submitInput, styles: styledSubmitStyles }, ]); @@ -335,7 +337,7 @@ describe('Form Body To Blocks', () => { type: 'text', updated_at: '2019-12-10T15:05:06+00:00', }; - const map = formBodyToBlocksFactory(colorDefinitions, fontSizeDefinitions, [customField]); + const map = getMapper([customField]); const [block] = map([customTextInput]); checkBlockBasics(block); expect(block.clientId).to.be.include('1_'); @@ -363,7 +365,7 @@ describe('Form Body To Blocks', () => { type: 'radio', updated_at: '2019-12-10T15:05:06+00:00', }; - const map = formBodyToBlocksFactory(colorDefinitions, fontSizeDefinitions, [customField]); + const map = getMapper([customField]); const [block] = map([customRadioInput]); checkBlockBasics(block); expect(block.clientId).to.be.include('3_'); @@ -393,7 +395,7 @@ describe('Form Body To Blocks', () => { }, position: null, }; - const map = formBodyToBlocksFactory(colorDefinitions, fontSizeDefinitions, [customField]); + const map = getMapper([customField]); const [block] = map([customCheckboxInput]); checkBlockBasics(block); expect(block.clientId).to.be.include('4_'); @@ -422,7 +424,7 @@ describe('Form Body To Blocks', () => { }, position: null, }; - const map = formBodyToBlocksFactory(colorDefinitions, fontSizeDefinitions, [customField]); + const map = getMapper([customField]); const [block] = map([customSelectInput]); checkBlockBasics(block); expect(block.clientId).to.be.include('5_'); @@ -449,7 +451,7 @@ describe('Form Body To Blocks', () => { updated_at: '2019-12-13T15:22:07+00:00', }; - const map = formBodyToBlocksFactory(colorDefinitions, fontSizeDefinitions, [customField]); + const map = getMapper([customField]); const [block] = map([customDateInput]); checkBlockBasics(block); expect(block.clientId).to.be.include('6_'); @@ -529,6 +531,23 @@ describe('Form Body To Blocks', () => { expect(block2.attributes.style.color.background).to.be.equal('#bbbbbb'); }); + it('Should map columns gradient', () => { + const nested = { ...nestedColumns }; + nested.params = { + gradient: 'linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(255,255,255,1) 100%)', + }; + const [block] = formBodyToBlocks([nested]); + expect(block.attributes.gradient).to.be.equal('black-white'); + expect(block.attributes.style.color.gradient).to.be.undefined; + + nested.params = { + gradient: 'linear-gradient(95deg, rgba(0,0,0,1) 0%, rgba(255,255,255,1) 100%)', + }; + const [block2] = formBodyToBlocks([nested]); + expect(block2.attributes.gradient).to.be.undefined; + expect(block2.attributes.style.color.gradient).to.be.equal('linear-gradient(95deg, rgba(0,0,0,1) 0%, rgba(255,255,255,1) 100%)'); + }); + it('Should map class name', () => { const nested = { ...nestedColumns }; nested.params = { @@ -556,7 +575,7 @@ describe('Form Body To Blocks', () => { }; const customText = { ...customTextInput, position: '1' }; customText.params.class_name = 'custom-class-3 custom-class-4'; - const map = formBodyToBlocksFactory(colorDefinitions, [], [customField]); + const map = getMapper([customField]); const [mappedCustomText] = map([customText]); expect(mappedCustomText.attributes.className).to.be.equal('custom-class-3 custom-class-4'); }); @@ -676,7 +695,7 @@ describe('Form Body To Blocks', () => { }; const customFields = [customField]; // Map columns with custom field - const map = formBodyToBlocksFactory(colorDefinitions, fontSizeDefinitions, customFields); + const map = getMapper(customFields); const [columns] = map([columnsWithCustomField]); const firstColumn = columns.innerBlocks[0]; expect(firstColumn.innerBlocks.length).to.be.equal(1);