[ADD] mass_mailing, web_editor: add editor message on empty mass_mailing
When choosing the empty template for mass_mailing, it was confusing to face a blank page with a tiny dropzone. With this we adopt the website builder's solution, which is to include a message when the page is empty. That message functions as a bigger dropzone. task-2734469 closes odoo/odoo#84356 X-original-commit: fbe048c202ff7878984adf26bef0651a45851f0a Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
This commit is contained in:
@@ -97,6 +97,10 @@
|
||||
'web/static/lib/bootstrap/scss/_variables.scss',
|
||||
'mass_mailing/static/src/scss/mass_mailing.ui.scss',
|
||||
],
|
||||
'web_editor.assets_wysiwyg': [
|
||||
'mass_mailing/static/src/js/snippets.editor.js',
|
||||
'mass_mailing/static/src/js/wysiwyg.js',
|
||||
],
|
||||
'web.assets_common': [
|
||||
'mass_mailing/static/src/js/tours/**/*',
|
||||
],
|
||||
|
||||
@@ -72,7 +72,10 @@ var MassMailingFieldHtml = FieldHtml.extend({
|
||||
self._isDirty = self.wysiwyg.isDirty();
|
||||
self._doAction();
|
||||
|
||||
const $editorEnable = $editable.closest('.editor_enable');
|
||||
$editorEnable.removeClass('editor_enable');
|
||||
convertInline.toInline($editable, self.cssRules, self.wysiwyg.$iframe);
|
||||
$editorEnable.addClass('editor_enable');
|
||||
|
||||
self.trigger_up('field_changed', {
|
||||
dataPointID: self.dataPointID,
|
||||
@@ -105,6 +108,18 @@ var MassMailingFieldHtml = FieldHtml.extend({
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Adds automatic editor messages on drag&drop zone elements.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_addEditorMessages: function () {
|
||||
const $editable = this.wysiwyg.getEditable().find('.o_editable');
|
||||
this.$editorMessageElements = $editable
|
||||
.not('[data-editor-message]')
|
||||
.attr('data-editor-message', _t('DRAG BUILDING BLOCKS HERE'));
|
||||
$editable.filter(':empty').attr('contenteditable', false);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -304,7 +319,9 @@ var MassMailingFieldHtml = FieldHtml.extend({
|
||||
const options = this._super.apply(this, arguments);
|
||||
options.resizable = false;
|
||||
options.defaultDataForLinkTools = { isNewWindow: true };
|
||||
if (!this._wysiwygSnippetsActive) {
|
||||
if (this._wysiwygSnippetsActive) {
|
||||
options.wysiwygAlias = 'mass_mailing.wysiwyg';
|
||||
} else {
|
||||
delete options.snippets;
|
||||
}
|
||||
return options;
|
||||
@@ -508,6 +525,7 @@ var MassMailingFieldHtml = FieldHtml.extend({
|
||||
}
|
||||
|
||||
selectTheme(e);
|
||||
this._addEditorMessages();
|
||||
// Wait the next tick because some mutation have to be processed by
|
||||
// the Odoo editor before resetting the history.
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
odoo.define('mass_mailing.snippets.editor', function (require) {
|
||||
'use strict';
|
||||
|
||||
const snippetsEditor = require('web_editor.snippet.editor');
|
||||
|
||||
const MassMailingSnippetsMenu = snippetsEditor.SnippetsMenu.extend({
|
||||
custom_events: _.extend({}, snippetsEditor.SnippetsMenu.prototype.custom_events, {
|
||||
drop_zone_over: '_onDropZoneOver',
|
||||
drop_zone_out: '_onDropZoneOut',
|
||||
drop_zone_start: '_onDropZoneStart',
|
||||
drop_zone_stop: '_onDropZoneStop',
|
||||
}),
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
return this._super(...arguments).then(() => {
|
||||
this.$editable = this.options.wysiwyg.getEditable();
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_insertDropzone: function ($hook) {
|
||||
const $hookParent = $hook.parent();
|
||||
const $dropzone = this._super(...arguments);
|
||||
$dropzone.attr('data-editor-message', $hookParent.attr('data-editor-message'));
|
||||
$dropzone.attr('data-editor-sub-message', $hookParent.attr('data-editor-sub-message'));
|
||||
return $dropzone;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handler
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onDropZoneOver: function () {
|
||||
this.$editable.find('.o_editable').css('background-color', '');
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onDropZoneOut: function () {
|
||||
const $oEditable = this.$editable.find('.o_editable');
|
||||
if ($oEditable.find('.oe_drop_zone.oe_insert:not(.oe_vertical):only-child').length) {
|
||||
$oEditable[0].style.setProperty('background-color', 'transparent', 'important');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onDropZoneStart: function () {
|
||||
const $oEditable = this.$editable.find('.o_editable');
|
||||
if ($oEditable.find('.oe_drop_zone.oe_insert:not(.oe_vertical):only-child').length) {
|
||||
$oEditable[0].style.setProperty('background-color', 'transparent', 'important');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onDropZoneStop: function () {
|
||||
const $oEditable = this.$editable.find('.o_editable');
|
||||
$oEditable.css('background-color', '');
|
||||
if (!$oEditable.find('.oe_drop_zone.oe_insert:not(.oe_vertical):only-child').length) {
|
||||
$oEditable.attr('contenteditable', true);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onSnippetRemoved: function () {
|
||||
this._super(...arguments);
|
||||
const $oEditable = this.$editable.find('.o_editable');
|
||||
if (!$oEditable.children().length) {
|
||||
$oEditable.empty(); // remove any superfluous whitespace
|
||||
$oEditable.attr('contenteditable', false);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return MassMailingSnippetsMenu;
|
||||
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
odoo.define('mass_mailing.wysiwyg', function (require) {
|
||||
'use strict';
|
||||
|
||||
var Wysiwyg = require('web_editor.wysiwyg');
|
||||
var MassMailingSnippetsMenu = require('mass_mailing.snippets.editor');
|
||||
|
||||
const MassMailingWysiwyg = Wysiwyg.extend({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_createSnippetsMenuInstance: function (options={}) {
|
||||
return new MassMailingSnippetsMenu(this, Object.assign({
|
||||
wysiwyg: this,
|
||||
selectorEditableArea: '.o_editable',
|
||||
}, options));
|
||||
},
|
||||
});
|
||||
|
||||
return MassMailingWysiwyg;
|
||||
|
||||
});
|
||||
@@ -273,6 +273,29 @@ body.editor_enable.o_basic_theme.o_in_iframe {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.editor_enable .o_mass_mailing_iframe {
|
||||
.o_editable:empty, .o_editable > .oe_drop_zone.oe_insert:not(.oe_vertical):only-child {
|
||||
background-color: white;
|
||||
border: 2px dashed #999999;
|
||||
padding: 112px 0px;
|
||||
text-align: center !important;
|
||||
color: #999999;
|
||||
margin: 5px;
|
||||
height: auto;
|
||||
|
||||
&:before {
|
||||
content: attr(data-editor-message);
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
line-height: 50px; // Useful for the "wizz" animation on snippet click to be more visible
|
||||
}
|
||||
&:after {
|
||||
content: attr(data-editor-sub-message);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.o_mass_mailing_iframe {
|
||||
//this will display the email body without padding
|
||||
@@ -284,5 +307,4 @@ body.editor_enable.o_basic_theme.o_in_iframe {
|
||||
.iframe-editor-wrapper {
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1317,6 +1317,7 @@ var SnippetsMenu = Widget.extend({
|
||||
if ($oeStructure.length && !$oeStructure.children().length && this.$snippets) {
|
||||
// If empty oe_structure, encourage using snippets in there by
|
||||
// making them "wizz" in the panel.
|
||||
this._updateRightPanelContent({content: [], tab: this.tabs.BLOCKS});
|
||||
this.$snippets.odooBounce();
|
||||
return;
|
||||
}
|
||||
@@ -2474,6 +2475,7 @@ var SnippetsMenu = Widget.extend({
|
||||
dropped = true;
|
||||
$(this).first().after($toInsert).addClass('invisible');
|
||||
$toInsert.removeClass('oe_snippet_body');
|
||||
self.trigger_up('drop_zone_over');
|
||||
},
|
||||
out: function () {
|
||||
var prev = $toInsert.prev();
|
||||
@@ -2483,6 +2485,7 @@ var SnippetsMenu = Widget.extend({
|
||||
$(this).removeClass('invisible');
|
||||
$toInsert.addClass('oe_snippet_body');
|
||||
}
|
||||
self.trigger_up('drop_zone_out');
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2497,6 +2500,7 @@ var SnippetsMenu = Widget.extend({
|
||||
self.draggableComponent.$scrollTarget.on('scroll.scrolling_element', function () {
|
||||
self.$el.trigger('scroll');
|
||||
});
|
||||
self.trigger_up('drop_zone_start');
|
||||
},
|
||||
stop: async function (ev, ui) {
|
||||
const doc = self.options.wysiwyg.odooEditor.document;
|
||||
@@ -2577,6 +2581,7 @@ var SnippetsMenu = Widget.extend({
|
||||
}
|
||||
self.$el.find('.oe_snippet_thumbnail').removeClass('o_we_already_dragging');
|
||||
}
|
||||
self.trigger_up('drop_zone_stop');
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,14 +19,15 @@ exports.loadWysiwyg = loadWysiwyg;
|
||||
* @param {object} options The wysiwyg options
|
||||
*/
|
||||
exports.createWysiwyg = async (parent, options, additionnalAssets = []) => {
|
||||
const wysiwygAlias = options.wysiwygAlias || 'web_editor.wysiwyg';
|
||||
if (!wysiwygPromise) {
|
||||
wysiwygPromise = new Promise(async (resolve) => {
|
||||
await loadWysiwyg(additionnalAssets);
|
||||
// Wait the loading of the service and his dependencies (use string to
|
||||
// avoid parsing of require function).
|
||||
const stringFunction = `return new Promise(resolve => {
|
||||
odoo.define('web_editor.wysiwig.loaded', require => {
|
||||
` + 'require' + `('web_editor.wysiwyg');
|
||||
odoo.define('${wysiwygAlias}.loaded', require => {
|
||||
` + 'require' + `('${wysiwygAlias}');
|
||||
resolve();
|
||||
});
|
||||
});`;
|
||||
@@ -35,7 +36,7 @@ exports.createWysiwyg = async (parent, options, additionnalAssets = []) => {
|
||||
});
|
||||
}
|
||||
await wysiwygPromise;
|
||||
const Wysiwyg = odoo.__DEBUG__.services['web_editor.wysiwyg'];
|
||||
const Wysiwyg = odoo.__DEBUG__.services[wysiwygAlias];
|
||||
return new Wysiwyg(parent, options);
|
||||
};
|
||||
|
||||
|
||||
@@ -216,10 +216,7 @@ const Wysiwyg = Widget.extend({
|
||||
|
||||
if (options.snippets) {
|
||||
$(this.odooEditor.document.body).addClass('editor_enable');
|
||||
this.snippetsMenu = new snippetsEditor.SnippetsMenu(this, Object.assign({
|
||||
wysiwyg: this,
|
||||
selectorEditableArea: '.o_editable',
|
||||
}, options));
|
||||
this.snippetsMenu = this._createSnippetsMenuInstance(options);
|
||||
await this._insertSnippetMenu();
|
||||
|
||||
this._onBeforeUnload = (event) => {
|
||||
@@ -1055,6 +1052,18 @@ const Wysiwyg = Widget.extend({
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns an instance of the snippets menu.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @returns {widget}
|
||||
*/
|
||||
_createSnippetsMenuInstance: function (options={}) {
|
||||
return new snippetsEditor.SnippetsMenu(this, Object.assign({
|
||||
wysiwyg: this,
|
||||
selectorEditableArea: '.o_editable',
|
||||
}, options));
|
||||
},
|
||||
_configureToolbar: function (options) {
|
||||
const $toolbar = this.toolbar.$el;
|
||||
$toolbar.on('mousedown', e => e.preventDefault());
|
||||
|
||||
Reference in New Issue
Block a user