diff --git a/client/src/lib/i18n.js b/client/src/lib/i18n.js
index 7b9440b4..224d1d16 100644
--- a/client/src/lib/i18n.js
+++ b/client/src/lib/i18n.js
@@ -45,7 +45,8 @@ i18n
},
react: {
- wait: true
+ wait: true,
+ defaultTransParent: 'span' // This is because we use React < v16
},
detection: {
diff --git a/client/src/lists/forms/CUD.js b/client/src/lists/forms/CUD.js
index 45d719fe..9fbd5b8a 100644
--- a/client/src/lists/forms/CUD.js
+++ b/client/src/lists/forms/CUD.js
@@ -16,6 +16,7 @@ import {
AlignedRow,
Button,
ButtonRow,
+ CheckBox,
Dropdown,
Fieldset,
Form,
@@ -33,6 +34,7 @@ import {
import {DeleteModalDialog} from "../../lib/modals";
import mailtrainConfig
from 'mailtrainConfig';
+import {langCodes} from "../../../../shared/langs";
@withTranslation()
@withForm
@@ -82,7 +84,7 @@ export default class CUD extends Component {
const t = props.t;
const helpEmailText = t('thePlaintextVersionForThisEmail');
- const helpMjmlGeneral = Custom forms use MJML for formatting. See the MJML documentation here;
+ const helpMjmlGeneral = Custom forms use MJML for formatting. See the MJML documentation here;
this.templateSettings = {
layout: {
@@ -283,6 +285,7 @@ export default class CUD extends Component {
name: '',
description: '',
selectedTemplate: 'layout',
+ selectedLanguage: '',
namespace: mailtrainConfig.user.namespace
};
supplyDefaults(data);
@@ -378,6 +381,11 @@ export default class CUD extends Component {
});
}
+ const langOptions = [{key: '', label: t('Default')}];
+ for (const lng of mailtrainConfig.enabledLanguages) {
+ langOptions.push({key: lng, label: langCodes[lng].getLabel(t)});
+ }
+
const listsColumns = [
{ data: 0, title: "#" },
@@ -388,6 +396,7 @@ export default class CUD extends Component {
const previewListId = this.getFormValue('previewList');
const selectedTemplate = this.getFormValue('selectedTemplate');
+ const selectedLanguage = this.getFormValue('selectedLanguage');
return (
@@ -448,8 +457,10 @@ export default class CUD extends Component {
{ selectedTemplate &&
}
diff --git a/locales/extract.js b/locales/extract.js
index 3a5479bf..3f25e442 100644
--- a/locales/extract.js
+++ b/locales/extract.js
@@ -145,7 +145,7 @@ function parseSpec(specStr) {
}
// see http://blog.stevenlevithan.com/archives/match-quoted-string
-const tMatcher = /(^|[ {+(=])((?:tUI|tLog|t|tMark)\s*\(\s*(?:\/\*(.*?)\*\/)?\s*)(["'])((?:(?!\4)[^\\]|\\.)*)(\4)/;
+const tMatcher = /(^|[ {+(=.])((?:tUI|tLog|t|tMark)\s*\(\s*(?:\/\*(.*?)\*\/)?\s*)(["'])((?:(?!\4)[^\\]|\\.)*)(\4)/;
const transMatcher = /(\/\*(.*?)\*\/\s*)?(\
][\s\S]*?\<\/Trans\>)/;
const jsxParser = acorn.Parser.extend(acornJsx());
diff --git a/server/models/forms.js b/server/models/forms.js
index 15425794..c788f8ea 100644
--- a/server/models/forms.js
+++ b/server/models/forms.js
@@ -7,7 +7,6 @@ const dtHelpers = require('../lib/dt-helpers');
const interoperableErrors = require('../../shared/interoperable-errors');
const shares = require('./shares');
const namespaceHelpers = require('../lib/namespace-helpers');
-const bluebird = require('bluebird');
const fs = require('fs-extra');
const path = require('path');
const mjml = require('mjml');
@@ -189,7 +188,7 @@ async function getDefaultCustomFormValues() {
async function getContents(fileName) {
try {
- const template = await fs.readFile(path.join(basePath, fileName), 'utf8');
+ return await fs.readFile(path.join(basePath, fileName), 'utf8');
} catch (err) {
return false;
}
@@ -205,12 +204,13 @@ async function getDefaultCustomFormValues() {
}
form.layout = await getContents('views/subscription/layout.mjml.hbs') || '';
- form.form_input_style = await getContents('static/subscription/form-input-style.css') || '@import url(/subscription/form-input-style.css);';
+ form.form_input_style = await getContents('../client/static/subscription/form-input-style.css') || '@import url(/subscription/form-input-style.css);';
return form;
}
+// TODO - this could run in the browser too - move to shared
function checkForMjmlErrors(form) {
let testLayout = '{{{body}}}';
@@ -234,9 +234,15 @@ function checkForMjmlErrors(form) {
const template = form[key];
const errs = hasMjmlError(template);
- const msgs = errs.map(x => x.formattedMessage);
+ let msgs;
+ if (Array.isArray(errs)) {
+ msgs = errs.map(x => x.formattedMessage)
+ } else {
+ msgs = [ errs.message ];
+ }
+
if (key === 'mail_confirm_html' && !template.includes('{{confirmUrl}}')) {
- msgs.push('Missing {{confirmUrl}}');
+ msgs.push('Missing {{confirmUrl}}'); // TODO - add localization support
}
if (msgs.length) {
@@ -255,7 +261,7 @@ function checkForMjmlErrors(form) {
}
if (!layout.includes('{{{body}}}')) {
- msgs.push(`{{{body}}} not found`);
+ msgs.push(`{{{body}}} not found`); // TODO - add localization support
}
if (msgs.length) {