diff --git a/ang/crmMosaico/EditMailingCtrl/bootstrap-single.html b/ang/crmMosaico/EditMailingCtrl/bootstrap-single.html
index 019784766d..efea9b3fd3 100644
--- a/ang/crmMosaico/EditMailingCtrl/bootstrap-single.html
+++ b/ang/crmMosaico/EditMailingCtrl/bootstrap-single.html
@@ -7,12 +7,29 @@
-
{{ts('Design')}}
+
+
+
+
+
+
+
{{design.title}}
-
-
+
diff --git a/ang/crmMosaico/EditMailingCtrl/bootstrap-wizard.html b/ang/crmMosaico/EditMailingCtrl/bootstrap-wizard.html
index 9d41e0f605..31baf381d0 100644
--- a/ang/crmMosaico/EditMailingCtrl/bootstrap-wizard.html
+++ b/ang/crmMosaico/EditMailingCtrl/bootstrap-wizard.html
@@ -7,7 +7,43 @@
-
+
+
+
+
+
+
+
+
+
+
+
({{ts('Define two options for the design. We will use A/B testing to determine which is better.')}})
+
+
+
+
+
+
+
+
{{design.title}}
+
+
+
+
+
+
@@ -21,30 +57,30 @@
+
+ {{ts('Back')}}
+
+
+ {{ts('Delete Draft')}}
+
+
+ {{ts('Save Draft')}}
+
+
+ {{ts('Continue')}}
+
+
+ {{ts('Submit Mailing')}}
+
diff --git a/ang/crmMosaico/MixinCtrl.js b/ang/crmMosaico/MixinCtrl.js
index 4aea10def7..3ce61f24f0 100644
--- a/ang/crmMosaico/MixinCtrl.js
+++ b/ang/crmMosaico/MixinCtrl.js
@@ -2,99 +2,31 @@
// This provides additional actions for editing a Mosaico mailing.
// It coexists with crmMailing's EditMailingCtrl.
- angular.module('crmMosaico').controller('CrmMosaicoMixinCtrl', function CrmMosaicoMixinCtrl($scope, dialogService, crmMosaicoTemplates, crmStatus, CrmMosaicoIframe, $timeout) {
- // var ts = $scope.ts = CRM.ts(null);
-
- // Main data is in $scope.mailing, $scope.mosaicoCtrl.template
-
- var crmMosaicoIframe = null, activeDialogs = {};
-
- // Hrm, would like `ng-controller="CrmMosaicoMixinCtrl as mosaicoCtrl`, but that's not working...
- $scope.mosaicoCtrl = {
- templates: [],
- // Fill a given "mailing" which the chosen "template".
- select: function(mailing, template) {
- var topt = mailing.template_options = mailing.template_options || {};
- var promise = crmMosaicoTemplates.getFull(template).then(function(tplCtnt){
- topt.mosaicoTemplate = template.id;
- topt.mosaicoMetadata = tplCtnt.metadata;
- topt.mosaicoContent = tplCtnt.content;
- mailing.body_html = tplCtnt.html;
- // console.log('select', {isAr1: _.isArray(mailing.template_options), isAr2: _.isArray(topt), m: mailing, t: template});
- $scope.mosaicoCtrl.edit(mailing);
- });
- return crmStatus({start: ts('Loading...'), success: null}, promise);
- },
- // Figure out which "template" was previously used with a "mailing."
- getTemplate: function(mailing) {
- if (!mailing || !mailing.template_options || !mailing.template_options.mosaicoTemplate) {
- return null;
- }
- var matches = _.where($scope.mosaicoCtrl.templates, {
- id: mailing.template_options.mosaicoTemplate
- });
- return matches.length > 0 ? matches[0] : null;
- },
- // Reset all Mosaico data in a "mailing'.
- reset: function(mailing) {
- if (crmMosaicoIframe) crmMosaicoIframe.destroy();
- crmMosaicoIframe = null;
- delete mailing.template_options.mosaicoTemplate;
- delete mailing.template_options.mosaicoMetadata;
- delete mailing.template_options.mosaicoContent;
- mailing.body_html = '';
- },
- // Edit a mailing in Mosaico.
- edit: function(mailing) {
- if (crmMosaicoIframe) {
- crmMosaicoIframe.show();
- return;
- }
-
- function syncModel(viewModel) {
- mailing.body_html = viewModel.exportHTML();
- mailing.template_options = mailing.template_options || {};
- // Mosaico exports JSON. Keep their original encoding... or else the loader throws an error.
- mailing.template_options.mosaicoMetadata = viewModel.exportMetadata();
- mailing.template_options.mosaicoContent = viewModel.exportJSON();
- }
-
- crmMosaicoIframe = new CrmMosaicoIframe({
- model: {
- template: $scope.mosaicoCtrl.getTemplate(mailing).path,
- metadata: mailing.template_options.mosaicoMetadata,
- content: mailing.template_options.mosaicoContent
- },
- actions: {
- sync: function(ko, viewModel) {
- syncModel(viewModel);
- },
- close: function(ko, viewModel) {
- viewModel.metadata.changed = Date.now();
- syncModel(viewModel);
- // TODO: When autosave is better integrated, remove this.
- $timeout(function(){$scope.save();}, 100);
- crmMosaicoIframe.hide('crmMosaicoEditorDialog');
- },
- test: function(ko, viewModel) {
- syncModel(viewModel);
+ angular.module('crmMosaico').controller('CrmMosaicoMixinCtrl', function CrmMosaicoMixinCtrl($scope, dialogService, crmMosaicoVariants) {
+ const ts = $scope.ts = CRM.ts('mosaico');
+
+ const singleDesign = [
+ {title: ts('Design'), vid: null, action: 'split'}
+ ];
+ const abDesign = [
+ {title: ts('Design (A)'), vid: 0, action: 'unsplit'},
+ {title: ts('Design (B)'), vid: 1, action: 'unsplit'},
+ ];
+
+ $scope.getDesigns = function(mailing) {
+ if (!mailing) return [];
+ return crmMosaicoVariants.isSplit(mailing, 'body_html') ? abDesign : singleDesign;
+ }
+ $scope.unsplitDesign = function(mailing, vid) {
+ crmMosaicoVariants.remove(mailing, ['mosaicoTemplate', 'mosaicoMetadata', 'mosaicoContent', 'body_html'], vid);
+ };
+ $scope.splitDesign = function(mailing) {
+ crmMosaicoVariants.split(mailing, ['mosaicoTemplate', 'mosaicoMetadata', 'mosaicoContent', 'body_html']);
+ };
- var model = {mailing: $scope.mailing, attachments: $scope.attachments};
- var options = CRM.utils.adjustDialogDefaults(angular.extend(
- {autoOpen: false, title: ts('Preview / Test'), width: 550},
- options
- ));
- activeDialogs.crmMosaicoPreviewDialog = 1;
- var pr = dialogService.open('crmMosaicoPreviewDialog', '~/crmMosaico/PreviewDialogCtrl.html', model, options)
- .finally(function(){ delete activeDialogs.crmMosaicoPreviewDialog; });
- return pr;
- }
- }
- });
+ $scope.isMailingSplit = (mailing, field) => crmMosaicoVariants.isSplit(mailing, field);
- return crmStatus({start: ts('Loading...'), success: null}, crmMosaicoIframe.open());
- }
- };
+ var activeDialogs = {};
// Open a dialog of advanced options.
$scope.openAdvancedOptions = function() {
@@ -113,21 +45,10 @@
.finally(function(){ delete activeDialogs.crmMosaicoAdvancedDialog; });
};
- crmMosaicoTemplates.whenLoaded().then(function(){
- $scope.mosaicoCtrl.templates = crmMosaicoTemplates.getAll();
- $scope.mosaicoCtrl.categoryFilters = _.transform(crmMosaicoTemplates.getCategories(), function(filters, category) {
- filters.push({id: filters.length, text: category.label, filter: {category_id: category.value}});
- }, [{id: 0, text: ts('Base Template'), filter: {isBase: true}}]);
- });
-
$scope.$on("$destroy", function() {
angular.forEach(activeDialogs, function(v,name){
dialogService.cancel(name);
});
- if (crmMosaicoIframe) {
- crmMosaicoIframe.destroy();
- crmMosaicoIframe = null;
- }
});
});
diff --git a/ang/crmMosaico/PreviewDialogCtrl.html b/ang/crmMosaico/PreviewDialogCtrl.html
index 8e8258f2ae..901016f935 100644
--- a/ang/crmMosaico/PreviewDialogCtrl.html
+++ b/ang/crmMosaico/PreviewDialogCtrl.html
@@ -1,5 +1,5 @@
diff --git a/ang/crmMosaico/PreviewDialogCtrl.js b/ang/crmMosaico/PreviewDialogCtrl.js
index a42b2a74a4..2a363613e8 100644
--- a/ang/crmMosaico/PreviewDialogCtrl.js
+++ b/ang/crmMosaico/PreviewDialogCtrl.js
@@ -5,17 +5,18 @@
// - [input] "model": Object
// - "mailing": Object, CiviMail mailing
// - "attachments": Object, CrmAttachment
- angular.module('crmMosaico').controller('CrmMosaicoPreviewDialogCtrl', function CrmMosaicoPreviewDialogCtrl($scope, crmMailingMgr, crmMailingPreviewMgr, crmBlocker, crmStatus) {
+ angular.module('crmMosaico').controller('CrmMosaicoPreviewDialogCtrl', function CrmMosaicoPreviewDialogCtrl($scope, crmMailingMgr, crmMailingPreviewMgr, crmBlocker, crmStatus, crmMosaicoVariants) {
var ts = $scope.ts = CRM.ts(null);
var block = $scope.block = crmBlocker();
// @return Promise
- $scope.previewMailing = function previewMailing(mailing, mode) {
- return crmMailingPreviewMgr.preview(mailing, mode);
+ $scope.previewMailing = function previewMailing(mailing, variantId, mode) {
+ const preview = crmMosaicoVariants.preview(mailing, variantId);
+ return crmMailingPreviewMgr.preview(preview, mode);
};
// @return Promise
- $scope.sendTest = function sendTest(mailing, attachments, recipient) {
+ $scope.sendTest = function sendTest(mailing, variantId, attachments, recipient) {
var savePromise = crmMailingMgr.save(mailing)
.then(function() {
return attachments.save();
diff --git a/ang/crmMosaico/SubjectList.html b/ang/crmMosaico/SubjectList.html
index 89b3e47f2a..538264d48d 100644
--- a/ang/crmMosaico/SubjectList.html
+++ b/ang/crmMosaico/SubjectList.html
@@ -1,4 +1,4 @@
-