More elements for mosaico mjml support. Added "MJML Sample" wizard to mosaico templates.

This commit is contained in:
Tomas Bures 2019-04-03 23:39:10 +02:00
parent ec0f288d81
commit 94a2cdf89e
7 changed files with 415 additions and 12 deletions

View file

@ -27,7 +27,7 @@ import {
} from '../../lib/namespace';
import {DeleteModalDialog} from "../../lib/modals";
import {getVersafix} from "../../../../shared/mosaico-templates";
import {getVersafix, getMJMLSample} from "../../../../shared/mosaico-templates";
import {
getTemplateTypes,
getTemplateTypesOrder
@ -87,6 +87,15 @@ export default class CUD extends Component {
html: getVersafix()
});
} else if (wizard === 'mjml-sample') {
this.populateFormValues({
name: '',
description: '',
namespace: mailtrainConfig.user.namespace,
type: 'mjml',
mjml: getMJMLSample()
});
} else {
this.populateFormValues({
name: '',
@ -183,7 +192,7 @@ export default class CUD extends Component {
<Form stateOwner={this} onSubmitAsync={::this.submitHandler}>
<InputField id="name" label={t('name')}/>
<TextArea id="description" label={t('description')}/>
{isEdit ?
{isEdit || this.props.wizard ?
<StaticField id="type" className={styles.formDisabled} label={t('type')}>
{typeKey && this.templateTypes[typeKey].typeName}
</StaticField>

View file

@ -123,6 +123,7 @@ export default class List extends Component {
<ButtonDropdown buttonClassName="btn-primary" menuClassName="dropdown-menu-right" label={t('createMosaicoTemplate')}>
<DropdownLink to="/templates/mosaico/create">{t('blank')}</DropdownLink>
<DropdownLink to="/templates/mosaico/create/versafix">{t('versafixOne')}</DropdownLink>
<DropdownLink to="/templates/mosaico/create/mjml-sample">{t('MJML Sample')}</DropdownLink>
</ButtonDropdown>
</Toolbar>
}

View file

@ -52,6 +52,7 @@ export function getTemplateTypes(t) {
owner.setFormStatusMessage('success', t('MJML is valid.'));
}
} catch (err) {
console.log(err);
owner.setFormStatusMessage('danger', t('Invalid MJML.'));
}
}

View file

@ -45,7 +45,7 @@ function handleMosaicoEditable(block, src) {
for (const attrMatch of attrsMatches) {
if (attrMatch[1] === 'mosaico-editable') {
if (attrMatch[1] === 'mj-mosaico-editable') {
const propertyId = attrMatch[2];
block.addMosaicoProperty(propertyId);
@ -80,13 +80,24 @@ class MjMosaicoProperty extends HeadComponent {
static allowedAttributes = {
'property-id': 'string',
label: 'string',
widget: 'string',
type: 'enum(image,link)'
}
handler() {
const { add } = this.context;
add('style', ` @supports -ko-blockdefs { ${this.getAttribute('property-id')} { label: ${this.getAttribute('label')}; widget: ${this.getAttribute('widget')} } }`);
let properties = null;
const type = this.getAttribute('type');
if (type === 'image') {
properties = 'src url alt';
} else if (type === 'link') {
properties = 'text url';
}
const propertiesStr = properties ? ` properties: ${properties}` : '';
add('style', ` @supports -ko-blockdefs { ${this.getAttribute('property-id')} { label: ${this.getAttribute('label')};${propertiesStr} } }`);
}
}
@ -247,7 +258,10 @@ class MjMosaicoImage extends BodyComponent {
const propertyId = this.getAttribute('property-id');
this.propertyId = propertyId || `image_${getId()}`;
getParent().addMosaicoProperty(this.propertyId);
const parentBlock = getParent();
if (parentBlock) {
parentBlock.addMosaicoProperty(this.propertyId);
}
}
static tagOmission = true
@ -425,6 +439,154 @@ class MjMosaicoImage extends BodyComponent {
}
// Adapted from https://github.com/mjmlio/mjml/blob/master/packages/mjml-button/src/index.js
class MjMosaicoButton extends BodyComponent {
constructor(initialDatas = {}) {
super(initialDatas);
const propertyId = this.getAttribute('property-id');
this.propertyId = propertyId || `button_${getId()}`;
const parentBlock = getParent();
if (parentBlock) {
parentBlock.addMosaicoProperty(this.propertyId);
}
}
static endingTag = true
static allowedAttributes = {
'property-id': 'string',
align: 'enum(left,center,right)',
'background-color': 'color',
'border-bottom': 'string',
'border-left': 'string',
'border-radius': 'string',
'border-right': 'string',
'border-top': 'string',
border: 'string',
color: 'color',
'container-background-color': 'color',
'font-family': 'string',
'font-size': 'unit(px)',
'font-style': 'string',
'font-weight': 'string',
height: 'unit(px,%)',
name: 'string',
'inner-padding': 'unit(px,%)',
'line-height': 'unit(px,%)',
'padding-bottom': 'unit(px,%)',
'padding-left': 'unit(px,%)',
'padding-right': 'unit(px,%)',
'padding-top': 'unit(px,%)',
padding: 'unit(px,%){1,4}',
rel: 'string',
target: 'string',
'text-decoration': 'string',
'text-transform': 'string',
'vertical-align': 'enum(top,bottom,middle)',
'text-align': 'enum(left,right,center)',
width: 'unit(px,%)',
}
static defaultAttributes = {
align: 'center',
'background-color': '#414141',
border: 'none',
'border-radius': '3px',
color: '#ffffff',
'font-family': 'Ubuntu, Helvetica, Arial, sans-serif',
'font-size': '13px',
'font-weight': 'normal',
'inner-padding': '10px 25px',
'line-height': '120%',
padding: '10px 25px',
target: '_blank',
'text-decoration': 'none',
'text-transform': 'none',
'vertical-align': 'middle',
}
getStyles() {
return {
table: {
'border-collapse': 'separate',
width: this.getAttribute('width'),
'line-height': '100%',
},
td: {
border: this.getAttribute('border'),
'border-bottom': this.getAttribute('border-bottom'),
'border-left': this.getAttribute('border-left'),
'border-radius': this.getAttribute('border-radius'),
'border-right': this.getAttribute('border-right'),
'border-top': this.getAttribute('border-top'),
cursor: 'auto',
'font-style': this.getAttribute('font-style'),
height: this.getAttribute('height'),
padding: this.getAttribute('inner-padding'),
'text-align': this.getAttribute('text-align'),
background: this.getAttribute('background-color'),
},
content: {
background: this.getAttribute('background-color'),
color: this.getAttribute('color'),
'font-family': this.getAttribute('font-family'),
'font-size': this.getAttribute('font-size'),
'font-style': this.getAttribute('font-style'),
'font-weight': this.getAttribute('font-weight'),
'line-height': this.getAttribute('line-height'),
Margin: '0',
'text-decoration': this.getAttribute('text-decoration'),
'text-transform': this.getAttribute('text-transform'),
},
}
}
render() {
return `
<table
${this.htmlAttributes({
border: '0',
cellpadding: '0',
cellspacing: '0',
role: 'presentation',
style: 'table',
})}
>
<tr>
<td
${this.htmlAttributes({
align: 'center',
bgcolor:
this.getAttribute('background-color') === 'none'
? undefined
: this.getAttribute('background-color'),
role: 'presentation',
style: 'td',
valign: this.getAttribute('vertical-align'),
})}
>
<a
${this.htmlAttributes({
rel: this.getAttribute('rel'),
name: this.getAttribute('name'),
style: 'content',
target: this.getAttribute('target'),
'data-ko-editable': this.getAttribute('property-id') + '.text',
'data-ko-link': this.getAttribute('property-id') + '.url'
})}
>
${this.getContent()}
</a>
</td>
</tr>
</table>
`;
}
}
const mjmlInstance = new MJML();
@ -432,15 +594,21 @@ mjmlInstance.registerComponent(MjMosaicoContainer);
mjmlInstance.registerComponent(MjMosaicoBlock);
mjmlInstance.registerComponent(MjMosaicoInnerBlock);
mjmlInstance.registerComponent(MjMosaicoImage);
mjmlInstance.registerComponent(MjMosaicoButton);
mjmlInstance.registerComponent(MjMosaicoProperty);
mjmlInstance.registerDependencies({
'mj-mosaico-container': ['mj-mosaico-block', 'mj-mosaico-inner-block'],
'mj-body': ['mj-mosaico-container', 'mj-mosaico-block'],
'mj-section': ['mj-mosaico-container', 'mj-mosaico-block'],
'mj-column': ['mj-mosaico-container', 'mj-mosaico-inner-block', 'mj-mosaico-image'],
'mj-column': ['mj-mosaico-container', 'mj-mosaico-inner-block', 'mj-mosaico-image', 'mj-mosaico-button'],
'mj-mosaico-block': ['mj-section', 'mj-column'],
'mj-mosaico-inner-block': ['mj-mosaico-image', 'mj-divider', 'mj-text', 'mj-image', 'mj-table']
'mj-mosaico-inner-block': [
'mj-mosaico-image', 'mj-mosaico-button',
'mj-accordion', 'mj-button', 'mj-carousel', 'mj-divider', 'mj-html', 'mj-image', 'mj-invoice', 'mj-list',
'mj-location', 'mj-raw', 'mj-social', 'mj-spacer', 'mj-table', 'mj-text', 'mj-navbar'
],
'mj-head': ['mj-mosaico-property']
});
mjmlInstance.addToHeader(`