Merge pull request #506 from mailpoet/alc_update

Multiple ALC block support for newsletter editor
This commit is contained in:
Jonathan Labreuille
2016-06-01 15:15:26 +02:00
14 changed files with 1491 additions and 456 deletions

View File

@@ -13,6 +13,7 @@ define([
'newsletter_editor/blocks/divider',
'newsletter_editor/components/communication',
'mailpoet',
'backbone.supermodel',
'underscore',
'jquery'
], function(
@@ -22,6 +23,7 @@ define([
DividerBlock,
CommunicationComponent,
MailPoet,
SuperModel,
_,
jQuery
) {
@@ -31,6 +33,36 @@ define([
var Module = {},
base = BaseBlock;
Module.ALCSupervisor = SuperModel.extend({
initialize: function() {
this.listenTo(App.getChannel(), 'automatedLatestContentRefresh', this.refresh);
},
refresh: function() {
var models = App.findModels(function(model) {
return model.get('type') === 'automatedLatestContent';
}) || [];
if (models.length === 0) return;
var blocks = _.map(models, function(model) {
return model.toJSON();
});
CommunicationComponent.getBulkTransformedPosts({
blocks: blocks,
}).then(_.partial(this.refreshBlocks, models));
},
refreshBlocks: function(models, renderedBlocks) {
_.each(
_.zip(models, renderedBlocks),
function(args) {
var model = args[0],
contents = args[1];
model.trigger('refreshPosts', contents);
}
);
},
});
Module.AutomatedLatestContentBlockModel = base.BlockModel.extend({
stale: ['_container'],
defaults: function() {
@@ -72,34 +104,32 @@ define([
},
initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments);
this.fetchPosts();
this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:featuredImagePosition change:titleAlignment change:titleIsLink change:imageFullWidth change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:sortBy change:showDivider', this._scheduleFetchPosts, this);
this.listenTo(this.get('readMoreButton'), 'change', this._scheduleFetchPosts);
this.listenTo(this.get('divider'), 'change', this._scheduleFetchPosts);
},
fetchPosts: function() {
var that = this;
CommunicationComponent.getTransformedPosts(this.toJSON()).done(function(content) {
that.get('_container').get('blocks').reset(content, {parse: true});
that.trigger('postsChanged');
}).fail(function(error) {
MailPoet.Notice.error(MailPoet.I18n.t('failedToFetchRenderedPosts'));
this.on('add remove update reset', function(model, collection, options) {
App.getChannel().trigger('automatedLatestContentRefresh');
});
this.on('refreshPosts', this.updatePosts, this);
},
updatePosts: function(posts) {
this.get('_container.blocks').reset(posts, {parse: true});
},
/**
* Batch more changes during a specific time, instead of fetching
* ALC posts on each model change
*/
_scheduleFetchPosts: function() {
var timeout = 500,
var TIMEOUT = 500,
that = this;
if (this._fetchPostsTimer !== undefined) {
clearTimeout(this._fetchPostsTimer);
}
this._fetchPostsTimer = setTimeout(function() {
that.fetchPosts();
//that.fetchPosts();
App.getChannel().trigger('automatedLatestContentRefresh');
that._fetchPostsTimer = undefined;
}, timeout);
}, TIMEOUT);
},
});
@@ -363,5 +393,10 @@ define([
});
});
App.on('start', function() {
App._ALCSupervisor = new Module.ALCSupervisor();
App._ALCSupervisor.refresh();
});
return Module;
});

View File

@@ -40,6 +40,9 @@ define([
// Remove stale attributes from resulting JSON object
return _.omit(SuperModel.prototype.toJSON.call(this), this.stale);
},
getChildren: function() {
return [];
},
});
Module.BlockView = AugmentedView.extend({

View File

@@ -65,6 +65,13 @@ define([
}
return response;
},
getChildren: function() {
var models = this.get('blocks').map(function(model, index, list) {
return [model, model.getChildren()];
});
return _.flatten(models);
},
});
Module.ContainerBlockView = Marionette.CompositeView.extend({

View File

@@ -61,6 +61,8 @@ define([
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
invalid_elements: "script",
block_formats: 'Paragraph=p',
relative_urls: false,
remove_script_host: false,
plugins: "link textcolor colorpicker mailpoet_custom_fields",

View File

@@ -61,6 +61,8 @@ define([
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
invalid_elements: "script",
block_formats: 'Paragraph=p',
relative_urls: false,
remove_script_host: false,
plugins: "link textcolor colorpicker mailpoet_custom_fields",

View File

@@ -59,6 +59,8 @@ define([
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],h1[class|style],h2[class|style],h3[class|style],ol[class|style],ul[class|style],li[class|style],strong[class|style],em[class|style],strike,br,blockquote[class|style],table[class|style],tr[class|style],th[class|style],td[class|style]",
invalid_elements: "script",
block_formats: 'Heading 1=h1;Heading 2=h2;Heading 3=h3;Paragraph=p',
relative_urls: false,
remove_script_host: false,
plugins: "link code textcolor colorpicker mailpoet_custom_fields",

View File

@@ -62,6 +62,13 @@ define([
});
};
Module.getBulkTransformedPosts = function(options) {
return Module._query({
action: 'getBulkTransformedPosts',
options: options,
});
};
Module.saveNewsletter = function(options) {
return MailPoet.Ajax.post({
endpoint: 'newsletters',

View File

@@ -60,6 +60,11 @@ define([
return Module.newsletter;
};
Module.findModels = function(predicate) {
var blocks = App._contentContainer.getChildren();
return _.filter(blocks, predicate);
};
App.on('before:start', function(options) {
// Expose block methods globally
App.registerBlockType = Module.registerBlockType;
@@ -68,6 +73,7 @@ define([
App.toJSON = Module.toJSON;
App.getBody = Module.getBody;
App.getNewsletter = Module.getNewsletter;
App.findModels = Module.findModels;
Module.newsletter = new Module.NewsletterModel(_.omit(_.clone(options.newsletter), ['body']));
});

View File

@@ -283,8 +283,10 @@ define([
return;
}
var contents = JSON.stringify(jsonObject);
if (App.getConfig().get('validation.validateUnsubscribeLinkPresent') &&
JSON.stringify(jsonObject).indexOf("[link:subscription_unsubscribe_url]") < 0) {
contents.indexOf("[link:subscription_unsubscribe_url]") < 0 &&
contents.indexOf("[link:subscription_unsubscribe]") < 0) {
this.showValidationError(MailPoet.I18n.t('unsubscribeLinkMissing'));
return;
}