summaryrefslogtreecommitdiff
path: root/addons/mass_mailing/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/mass_mailing/static/src')
-rw-r--r--addons/mass_mailing/static/src/css/basic_theme_readonly.css7
-rw-r--r--addons/mass_mailing/static/src/css/email_template.css21
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_banner.pngbin0 -> 604 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_comparison_table.pngbin0 -> 171 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_discount1.pngbin0 -> 1327 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_discount2.pngbin0 -> 1024 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_event.pngbin0 -> 821 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_footer_separator.pngbin0 -> 574 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_footer_social.pngbin0 -> 1017 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_footer_social_left.pngbin0 -> 722 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_footer_tag_line.pngbin0 -> 648 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_header_browser.pngbin0 -> 376 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_header_logo.pngbin0 -> 317 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_header_social.pngbin0 -> 746 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_header_text_social.pngbin0 -> 730 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_image.pngbin0 -> 642 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_image_text.pngbin0 -> 622 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_paragraph.pngbin0 -> 149 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_steps.pngbin0 -> 650 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_text_image.pngbin0 -> 611 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_three_cols.pngbin0 -> 692 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_title_sub.pngbin0 -> 240 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_title_text.pngbin0 -> 813 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/blocks/block_two_cols.pngbin0 -> 689 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_banner.jpgbin0 -> 1522 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_event.jpgbin0 -> 1154 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_image.jpgbin0 -> 2336 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_image_text.jpgbin0 -> 2033 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_text_image.jpgbin0 -> 1575 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_1.jpgbin0 -> 917 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_2.jpgbin0 -> 917 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_3.jpgbin0 -> 917 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_two_cols_1.jpgbin0 -> 1489 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_two_cols_2.jpgbin0 -> 1489 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_basic/s_default_image_logo.pngbin0 -> 4589 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_default/demo/signature.pngbin0 -> 8385 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_banner.jpgbin0 -> 33832 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_event.jpgbin0 -> 26456 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_image.jpgbin0 -> 30662 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_image_text.jpgbin0 -> 9522 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_text_image.jpgbin0 -> 26381 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_1.jpgbin0 -> 6598 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_2.jpgbin0 -> 5645 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_3.jpgbin0 -> 14684 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_two_cols_1.jpgbin0 -> 10341 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_block_two_cols_2.jpgbin0 -> 13659 bytes
-rwxr-xr-xaddons/mass_mailing/static/src/img/theme_default/s_default_image_logo.pngbin0 -> 1046 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_large.pngbin0 -> 11781 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_logo.pngbin0 -> 909 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_small.pngbin0 -> 7771 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_imgs/default_thumb_large.pngbin0 -> 17035 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_imgs/default_thumb_logo.pngbin0 -> 153 bytes
-rw-r--r--addons/mass_mailing/static/src/img/theme_imgs/default_thumb_small.pngbin0 -> 3058 bytes
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing.js15
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing_link_dialog_fix.js75
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing_list_kanban_record.js18
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing_list_kanban_renderer.js16
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing_list_kanban_view.js19
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing_snippets.js153
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing_widget.js520
-rw-r--r--addons/mass_mailing/static/src/js/tours/mass_mailing_tour.js88
-rw-r--r--addons/mass_mailing/static/src/js/unsubscribe.js198
-rw-r--r--addons/mass_mailing/static/src/scss/mass_mailing.scss50
-rw-r--r--addons/mass_mailing/static/src/scss/mass_mailing.ui.jw.scss0
-rw-r--r--addons/mass_mailing/static/src/scss/mass_mailing.ui.scss206
-rw-r--r--addons/mass_mailing/static/src/scss/mass_mailing.ui.shadow.scss0
-rw-r--r--addons/mass_mailing/static/src/scss/mass_mailing_mobile.scss7
-rw-r--r--addons/mass_mailing/static/src/scss/themes/theme_basic.scss54
-rw-r--r--addons/mass_mailing/static/src/scss/themes/theme_default.scss307
-rw-r--r--addons/mass_mailing/static/src/xml/mass_mailing.xml22
70 files changed, 1776 insertions, 0 deletions
diff --git a/addons/mass_mailing/static/src/css/basic_theme_readonly.css b/addons/mass_mailing/static/src/css/basic_theme_readonly.css
new file mode 100644
index 00000000..340eec95
--- /dev/null
+++ b/addons/mass_mailing/static/src/css/basic_theme_readonly.css
@@ -0,0 +1,7 @@
+/* We want to show system's default font in the mail sent with the basic theme.
+ And so we remove font-family from basic theme while saving. But by doing so
+ in readonly mode is not getting proper font in odoo. So we added if from here.
+ */
+#wrapwrap .o_layout.o_basic_theme {
+ font-family: -apple-system, "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
+}
diff --git a/addons/mass_mailing/static/src/css/email_template.css b/addons/mass_mailing/static/src/css/email_template.css
new file mode 100644
index 00000000..edd9c0c3
--- /dev/null
+++ b/addons/mass_mailing/static/src/css/email_template.css
@@ -0,0 +1,21 @@
+.openerp .oe_kanban_email_template {
+ width: 360px;
+ height: 340px;
+}
+
+.openerp .oe_kanban_email_template .oe_kanban_content{
+ height: 320px;
+ overflow: hidden !important;
+}
+
+.kanban_html_preview {
+ pointer-events: none;
+ width: 600px;
+ -webkit-transform: scale(.50);
+ -ms-transform: scale(.50);
+ transform: scale(.50);
+ -webkit-transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ transform-origin: 0 0;
+ margin: 0;
+}
diff --git a/addons/mass_mailing/static/src/img/blocks/block_banner.png b/addons/mass_mailing/static/src/img/blocks/block_banner.png
new file mode 100755
index 00000000..bcf62bd1
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_banner.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_comparison_table.png b/addons/mass_mailing/static/src/img/blocks/block_comparison_table.png
new file mode 100755
index 00000000..63c810cc
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_comparison_table.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_discount1.png b/addons/mass_mailing/static/src/img/blocks/block_discount1.png
new file mode 100755
index 00000000..478d2525
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_discount1.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_discount2.png b/addons/mass_mailing/static/src/img/blocks/block_discount2.png
new file mode 100755
index 00000000..0a14a917
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_discount2.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_event.png b/addons/mass_mailing/static/src/img/blocks/block_event.png
new file mode 100755
index 00000000..4dba58c9
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_event.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_footer_separator.png b/addons/mass_mailing/static/src/img/blocks/block_footer_separator.png
new file mode 100755
index 00000000..6af266fc
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_footer_separator.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_footer_social.png b/addons/mass_mailing/static/src/img/blocks/block_footer_social.png
new file mode 100755
index 00000000..41992607
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_footer_social.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_footer_social_left.png b/addons/mass_mailing/static/src/img/blocks/block_footer_social_left.png
new file mode 100755
index 00000000..ee39ed7c
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_footer_social_left.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_footer_tag_line.png b/addons/mass_mailing/static/src/img/blocks/block_footer_tag_line.png
new file mode 100755
index 00000000..73b5a29e
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_footer_tag_line.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_header_browser.png b/addons/mass_mailing/static/src/img/blocks/block_header_browser.png
new file mode 100755
index 00000000..c05196e7
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_header_browser.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_header_logo.png b/addons/mass_mailing/static/src/img/blocks/block_header_logo.png
new file mode 100755
index 00000000..eae72c93
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_header_logo.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_header_social.png b/addons/mass_mailing/static/src/img/blocks/block_header_social.png
new file mode 100755
index 00000000..43aaec4c
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_header_social.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_header_text_social.png b/addons/mass_mailing/static/src/img/blocks/block_header_text_social.png
new file mode 100755
index 00000000..61bb97fd
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_header_text_social.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_image.png b/addons/mass_mailing/static/src/img/blocks/block_image.png
new file mode 100755
index 00000000..e918a8d7
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_image.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_image_text.png b/addons/mass_mailing/static/src/img/blocks/block_image_text.png
new file mode 100755
index 00000000..de9e18f3
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_image_text.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_paragraph.png b/addons/mass_mailing/static/src/img/blocks/block_paragraph.png
new file mode 100755
index 00000000..bfba996c
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_paragraph.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_steps.png b/addons/mass_mailing/static/src/img/blocks/block_steps.png
new file mode 100755
index 00000000..e977a105
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_steps.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_text_image.png b/addons/mass_mailing/static/src/img/blocks/block_text_image.png
new file mode 100755
index 00000000..c0832ebd
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_text_image.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_three_cols.png b/addons/mass_mailing/static/src/img/blocks/block_three_cols.png
new file mode 100755
index 00000000..cd72e7b8
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_three_cols.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_title_sub.png b/addons/mass_mailing/static/src/img/blocks/block_title_sub.png
new file mode 100755
index 00000000..1320ccc5
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_title_sub.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_title_text.png b/addons/mass_mailing/static/src/img/blocks/block_title_text.png
new file mode 100755
index 00000000..399f13c2
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_title_text.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/blocks/block_two_cols.png b/addons/mass_mailing/static/src/img/blocks/block_two_cols.png
new file mode 100755
index 00000000..79e19de0
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/blocks/block_two_cols.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_banner.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_banner.jpg
new file mode 100644
index 00000000..872366f9
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_banner.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_event.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_event.jpg
new file mode 100644
index 00000000..50a9d033
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_event.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_image.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_image.jpg
new file mode 100644
index 00000000..047516fe
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_image.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_image_text.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_image_text.jpg
new file mode 100644
index 00000000..59a1806d
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_image_text.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_text_image.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_text_image.jpg
new file mode 100644
index 00000000..0009598d
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_text_image.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_1.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_1.jpg
new file mode 100644
index 00000000..7a7f2bbd
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_1.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_2.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_2.jpg
new file mode 100644
index 00000000..7a7f2bbd
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_2.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_3.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_3.jpg
new file mode 100644
index 00000000..7a7f2bbd
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_three_cols_3.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_two_cols_1.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_two_cols_1.jpg
new file mode 100644
index 00000000..98ed24c6
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_two_cols_1.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_two_cols_2.jpg b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_two_cols_2.jpg
new file mode 100644
index 00000000..98ed24c6
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_block_two_cols_2.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_basic/s_default_image_logo.png b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_logo.png
new file mode 100644
index 00000000..064f09c1
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_basic/s_default_image_logo.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/demo/signature.png b/addons/mass_mailing/static/src/img/theme_default/demo/signature.png
new file mode 100644
index 00000000..36cb2642
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/demo/signature.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_banner.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_banner.jpg
new file mode 100755
index 00000000..e6a85a38
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_banner.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_event.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_event.jpg
new file mode 100755
index 00000000..91fff96b
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_event.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_image.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_image.jpg
new file mode 100755
index 00000000..3ca5ebb5
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_image.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_image_text.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_image_text.jpg
new file mode 100755
index 00000000..87251f5f
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_image_text.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_text_image.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_text_image.jpg
new file mode 100755
index 00000000..10f6102f
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_text_image.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_1.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_1.jpg
new file mode 100755
index 00000000..fa939c89
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_1.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_2.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_2.jpg
new file mode 100755
index 00000000..35a8006b
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_2.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_3.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_3.jpg
new file mode 100755
index 00000000..e33e6679
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_three_cols_3.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_two_cols_1.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_two_cols_1.jpg
new file mode 100755
index 00000000..9a55e535
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_two_cols_1.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_two_cols_2.jpg b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_two_cols_2.jpg
new file mode 100755
index 00000000..38c77b3c
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_block_two_cols_2.jpg
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_default/s_default_image_logo.png b/addons/mass_mailing/static/src/img/theme_default/s_default_image_logo.png
new file mode 100755
index 00000000..1f5169a2
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_default/s_default_image_logo.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_large.png b/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_large.png
new file mode 100644
index 00000000..380661de
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_large.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_logo.png b/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_logo.png
new file mode 100644
index 00000000..2a562249
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_logo.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_small.png b/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_small.png
new file mode 100644
index 00000000..32b14ab1
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_imgs/basic_thumb_small.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_large.png b/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_large.png
new file mode 100644
index 00000000..d93ecd63
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_large.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_logo.png b/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_logo.png
new file mode 100644
index 00000000..157ab855
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_logo.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_small.png b/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_small.png
new file mode 100644
index 00000000..5c851797
--- /dev/null
+++ b/addons/mass_mailing/static/src/img/theme_imgs/default_thumb_small.png
Binary files differ
diff --git a/addons/mass_mailing/static/src/js/mass_mailing.js b/addons/mass_mailing/static/src/js/mass_mailing.js
new file mode 100644
index 00000000..e74d97f5
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/mass_mailing.js
@@ -0,0 +1,15 @@
+odoo.define('mass_mailing.mass_mailing', function (require) {
+"use strict";
+
+var KanbanColumn = require('web.KanbanColumn');
+
+KanbanColumn.include({
+ init: function () {
+ this._super.apply(this, arguments);
+ if (this.modelName === 'mailing.mailing') {
+ this.draggable = false;
+ }
+ },
+});
+
+});
diff --git a/addons/mass_mailing/static/src/js/mass_mailing_link_dialog_fix.js b/addons/mass_mailing/static/src/js/mass_mailing_link_dialog_fix.js
new file mode 100644
index 00000000..6b46340b
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/mass_mailing_link_dialog_fix.js
@@ -0,0 +1,75 @@
+
+odoo.define('mass_mailing.fix.LinkDialog', function (require) {
+'use strict';
+
+const LinkDialog = require('wysiwyg.widgets.LinkDialog');
+
+/**
+ * Primary and link buttons are "hacked" by mailing themes scss. We thus
+ * have to fix their preview if possible.
+ */
+LinkDialog.include({
+ /**
+ * @override
+ */
+ start() {
+ const ret = this._super(...arguments);
+ if (!$(this.editable).find('.o_mail_wrapper').length) {
+ return ret;
+ }
+
+ this.opened().then(() => {
+ // Ugly hack to show the real color for link and primary which
+ // depend on the mailing themes. Note: the hack is not enough as
+ // the mailing theme changes those colors in some environment,
+ // sometimes (for example 'btn-primary in this snippet looks like
+ // that')... we'll consider this a limitation until a master
+ // refactoring of those mailing themes.
+ this.__realMMColors = {};
+ const $previewArea = $('<div/>').addClass('o_mail_snippet_general');
+ $(this.editable).find('.o_layout').append($previewArea);
+ _.each(['link', 'primary', 'secondary'], type => {
+ const $el = $('<a href="#" class="btn btn-' + type + '"/>');
+ $el.appendTo($previewArea);
+ this.__realMMColors[type] = {
+ 'border-color': $el.css('border-top-color'),
+ 'background-color': $el.css('background-color'),
+ 'color': $el.css('color'),
+ };
+ $el.remove();
+
+ this.$('.form-group .o_btn_preview.btn-' + type)
+ .css(_.pick(this.__realMMColors[type], 'background-color', 'color'));
+ });
+ $previewArea.remove();
+
+ this._adaptPreview();
+ });
+
+ return ret;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _adaptPreview() {
+ this._super(...arguments);
+ if (this.__realMMColors) {
+ var $preview = this.$("#link-preview");
+ $preview.css('border-color', '');
+ $preview.css('background-color', '');
+ $preview.css('color', '');
+ _.each(['link', 'primary', 'secondary'], type => {
+ if ($preview.hasClass('btn-' + type) || type === 'link' && !$preview.hasClass('btn')) {
+ $preview.css(this.__realMMColors[type]);
+ }
+ });
+ }
+ },
+});
+
+});
diff --git a/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_record.js b/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_record.js
new file mode 100644
index 00000000..52d7076b
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_record.js
@@ -0,0 +1,18 @@
+odoo.define('mass_mailing.ListKanbanRecord', function (require) {
+"use strict";
+
+var KanbanRecord = require('web.KanbanRecord');
+
+var MassMailingListKanbanRecord = KanbanRecord.extend({
+ /**
+ * @override
+ * @private
+ */
+ _openRecord: function () {
+ this.$('.o_mailing_list_kanban_boxes a').first().click();
+ }
+});
+
+return MassMailingListKanbanRecord;
+
+});
diff --git a/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_renderer.js b/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_renderer.js
new file mode 100644
index 00000000..b9804e72
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_renderer.js
@@ -0,0 +1,16 @@
+odoo.define('mass_mailing.ListKanbanRenderer', function (require) {
+"use strict";
+
+var MassMailingListKanbanRecord = require('mass_mailing.ListKanbanRecord');
+
+var KanbanRenderer = require('web.KanbanRenderer');
+
+var MassMailingListKanbanRenderer = KanbanRenderer.extend({
+ config: _.extend({}, KanbanRenderer.prototype.config, {
+ KanbanRecord: MassMailingListKanbanRecord,
+ })
+});
+
+return MassMailingListKanbanRenderer;
+
+});
diff --git a/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_view.js b/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_view.js
new file mode 100644
index 00000000..86bac695
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/mass_mailing_list_kanban_view.js
@@ -0,0 +1,19 @@
+odoo.define('mass_mailing.ListKanbanView', function (require) {
+"use strict";
+
+var MassMailingListKanbanRenderer = require('mass_mailing.ListKanbanRenderer');
+
+var KanbanView = require('web.KanbanView');
+var view_registry = require('web.view_registry');
+
+var MassMailingListKanbanView = KanbanView.extend({
+ config: _.extend({}, KanbanView.prototype.config, {
+ Renderer: MassMailingListKanbanRenderer,
+ }),
+});
+
+view_registry.add('mass_mailing_list_kanban', MassMailingListKanbanView);
+
+return MassMailingListKanbanView;
+
+});
diff --git a/addons/mass_mailing/static/src/js/mass_mailing_snippets.js b/addons/mass_mailing/static/src/js/mass_mailing_snippets.js
new file mode 100644
index 00000000..ef4bd007
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/mass_mailing_snippets.js
@@ -0,0 +1,153 @@
+odoo.define('mass_mailing.snippets.options', function (require) {
+"use strict";
+
+var options = require('web_editor.snippets.options');
+
+// Snippet option for resizing image and column width inline like excel
+options.registry.mass_mailing_sizing_x = options.Class.extend({
+ /**
+ * @override
+ */
+ start: function () {
+ var def = this._super.apply(this, arguments);
+
+ this.containerWidth = this.$target.parent().closest("td, table, div").width();
+
+ var self = this;
+ var offset, sib_offset, target_width, sib_width;
+
+ this.$overlay.find(".o_handle.e, .o_handle.w").removeClass("readonly");
+ this.isIMG = this.$target.is("img");
+ if (this.isIMG) {
+ this.$overlay.find(".o_handle.w").addClass("readonly");
+ }
+
+ var $body = $(this.ownerDocument.body);
+ this.$overlay.find(".o_handle").on('mousedown', function (event) {
+ event.preventDefault();
+ var $handle = $(this);
+ var compass = false;
+
+ _.each(['n', 's', 'e', 'w'], function (handler) {
+ if ($handle.hasClass(handler)) { compass = handler; }
+ });
+ if (self.isIMG) { compass = "image"; }
+
+ $body.on("mousemove.mass_mailing_width_x", function (event) {
+ event.preventDefault();
+ offset = self.$target.offset().left;
+ target_width = self.get_max_width(self.$target);
+ if (compass === 'e' && self.$target.next().offset()) {
+ sib_width = self.get_max_width(self.$target.next());
+ sib_offset = self.$target.next().offset().left;
+ self.change_width(event, self.$target, target_width, offset, true);
+ self.change_width(event, self.$target.next(), sib_width, sib_offset, false);
+ }
+ if (compass === 'w' && self.$target.prev().offset()) {
+ sib_width = self.get_max_width(self.$target.prev());
+ sib_offset = self.$target.prev().offset().left;
+ self.change_width(event, self.$target, target_width, offset, false);
+ self.change_width(event, self.$target.prev(), sib_width, sib_offset, true);
+ }
+ if (compass === 'image') {
+ self.change_width(event, self.$target, target_width, offset, true);
+ }
+ });
+ $body.one("mouseup", function () {
+ $body.off('.mass_mailing_width_x');
+ });
+ });
+
+ return def;
+ },
+ change_width: function (event, target, target_width, offset, grow) {
+ target.css("width", grow ? (event.pageX - offset) : (offset + target_width - event.pageX));
+ this.trigger_up('cover_update');
+ },
+ get_int_width: function (el) {
+ return parseInt($(el).css("width"), 10);
+ },
+ get_max_width: function ($el) {
+ return this.containerWidth - _.reduce(_.map($el.siblings(), this.get_int_width), function (memo, w) { return memo + w; });
+ },
+ onFocus: function () {
+ this._super.apply(this, arguments);
+
+ if (this.$target.is("td, th")) {
+ this.$overlay.find(".o_handle.e, .o_handle.w").toggleClass("readonly", this.$target.siblings().length === 0);
+ }
+ },
+});
+
+options.registry.mass_mailing_table_item = options.Class.extend({
+ onClone: function (options) {
+ this._super.apply(this, arguments);
+
+ // If we cloned a td or th element...
+ if (options.isCurrent && this.$target.is("td, th")) {
+ // ... and that the td or th element was alone on its row ...
+ if (this.$target.siblings().length === 1) {
+ var $tr = this.$target.parent();
+ $tr.clone().empty().insertAfter($tr).append(this.$target); // ... move the clone in a new row instead
+ return;
+ }
+
+ // ... if not, if the clone neighbor is an empty cell, remove this empty cell (like if the clone content had been put in that cell)
+ var $next = this.$target.next();
+ if ($next.length && $next.text().trim() === "") {
+ $next.remove();
+ return;
+ }
+
+ // ... if not, insert an empty col in each other row, at the index of the clone
+ var width = this.$target.width();
+ var $trs = this.$target.closest("table").children("thead, tbody, tfoot").addBack().children("tr").not(this.$target.parent());
+ _.each($trs.children(":nth-child(" + this.$target.index() + ")"), function (col) {
+ $(col).after($("<td/>", {style: "width: " + width + "px;"}));
+ });
+ }
+ },
+ onRemove: function () {
+ this._super.apply(this, arguments);
+
+ // If we are removing a td or th element which was not alone on its row ...
+ if (this.$target.is("td, th") && this.$target.siblings().length > 0) {
+ var $trs = this.$target.closest("table").children("thead, tbody, tfoot").addBack().children("tr").not(this.$target.parent());
+ if ($trs.length) { // ... if there are other rows in the table ...
+ var $last_tds = $trs.children(":last-child");
+ if (_.reduce($last_tds, function (memo, td) { return memo + (td.innerHTML || ""); }, "").trim() === "") {
+ $last_tds.remove(); // ... remove the potential full empty column in the table
+ } else {
+ this.$target.parent().append("<td/>"); // ... else, if there is no full empty column, append an empty col in the current row
+ }
+ }
+ }
+ },
+});
+
+// Adding compatibility for the outlook compliance of mailings.
+// Commit of such compatibility : a14f89c8663c9cafecb1cc26918055e023ecbe42
+options.registry.BackgroundImage = options.registry.BackgroundImage.extend({
+ start: function () {
+ this._super();
+ if (this.snippets && this.snippets.split('.')[0] === "mass_mailing") {
+ var $table_target = this.$target.find('table:first');
+ if ($table_target.length) {
+ this.$target = $table_target;
+ }
+ }
+ }
+});
+
+// TODO remove in master when removing the XML div. The option has been disabled
+// in 14.0 because of tricky problems to resolve that require refactoring:
+// the ability to clean snippet without saving and reloading the page.
+options.registry.SnippetSave.include({
+
+ async saveSnippet(previewMode, widgetValue, params) {},
+
+ async _computeVisibility() {
+ return false;
+ },
+});
+});
diff --git a/addons/mass_mailing/static/src/js/mass_mailing_widget.js b/addons/mass_mailing/static/src/js/mass_mailing_widget.js
new file mode 100644
index 00000000..b39cb917
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/mass_mailing_widget.js
@@ -0,0 +1,520 @@
+odoo.define('mass_mailing.FieldHtml', function (require) {
+'use strict';
+
+var config = require('web.config');
+var core = require('web.core');
+var FieldHtml = require('web_editor.field.html');
+var fieldRegistry = require('web.field_registry');
+var convertInline = require('web_editor.convertInline');
+
+var _t = core._t;
+
+
+var MassMailingFieldHtml = FieldHtml.extend({
+ xmlDependencies: (FieldHtml.prototype.xmlDependencies || []).concat(["/mass_mailing/static/src/xml/mass_mailing.xml"]),
+ jsLibs: [
+ '/mass_mailing/static/src/js/mass_mailing_link_dialog_fix.js',
+ ],
+
+ custom_events: _.extend({}, FieldHtml.prototype.custom_events, {
+ snippets_loaded: '_onSnippetsLoaded',
+ }),
+
+ /**
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ if (!this.nodeOptions.snippets) {
+ this.nodeOptions.snippets = 'mass_mailing.email_designer_snippets';
+ }
+
+ // All the code related to this __extraAssetsForIframe variable is an
+ // ugly hack to restore mass mailing options in stable versions. The
+ // whole logic has to be refactored as soon as possible...
+ this.__extraAssetsForIframe = [{
+ jsLibs: ['/mass_mailing/static/src/js/mass_mailing_snippets.js'],
+ }];
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * Commit the change in 'style-inline' on an other field nodeOptions:
+ *
+ * - inline-field: fieldName to save the html value converted into inline code
+ *
+ * @override
+ */
+ commitChanges: function () {
+ var self = this;
+ if (config.isDebug() && this.mode === 'edit') {
+ var layoutInfo = $.summernote.core.dom.makeLayoutInfo(this.wysiwyg.$editor);
+ $.summernote.pluginEvents.codeview(undefined, undefined, layoutInfo, false);
+ }
+ if (this.mode === 'readonly' || !this.isRendered) {
+ return this._super();
+ }
+ var fieldName = this.nodeOptions['inline-field'];
+
+ if (this.$content.find('.o_basic_theme').length) {
+ this.$content.find('*').css('font-family', '');
+ }
+
+ var $editable = this.wysiwyg.getEditable();
+
+ return this.wysiwyg.saveModifiedImages(this.$content).then(function () {
+ return self.wysiwyg.save().then(function (result) {
+ self._isDirty = result.isDirty;
+
+ convertInline.attachmentThumbnailToLinkImg($editable);
+ convertInline.fontToImg($editable);
+ convertInline.classToStyle($editable);
+
+ // fix outlook image rendering bug
+ _.each(['width', 'height'], function(attribute) {
+ $editable.find('img[style*="width"], img[style*="height"]').attr(attribute, function(){
+ return $(this)[attribute]();
+ }).css(attribute, function(){
+ return $(this).get(0).style[attribute] || 'auto';
+ });
+ });
+
+ self.trigger_up('field_changed', {
+ dataPointID: self.dataPointID,
+ changes: _.object([fieldName], [self._unWrap($editable.html())])
+ });
+ self.wysiwyg.setValue(result.html);
+
+ if (self._isDirty && self.mode === 'edit') {
+ return self._doAction();
+ }
+ });
+ });
+ },
+ /**
+ * The html_frame widget is opened in an iFrame that has its URL encoded
+ * with all the key/values returned by this method.
+ *
+ * Some fields can get very long values and we want to omit them for the URL building.
+ *
+ * @override
+ */
+ getDatarecord: function () {
+ return _.omit(this._super(), [
+ 'mailing_domain',
+ 'contact_list_ids',
+ 'body_html',
+ 'attachment_ids'
+ ]);
+ },
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Returns true if must force the user to choose a theme.
+ *
+ * @private
+ * @returns {Boolean}
+ */
+ _checkIfMustForceThemeChoice: function () {
+ var firstChoice = this._editableAreaIsEmpty();
+ this.$content.closest('body').toggleClass("o_force_mail_theme_choice", firstChoice);
+ return firstChoice;
+ },
+ /**
+ * Returns true if the editable area is empty.
+ *
+ * @private
+ * @param {JQuery} [$layout]
+ * @returns {Boolean}
+ */
+ _editableAreaIsEmpty: function ($layout) {
+ $layout = $layout || this.$content.find(".o_layout");
+ var $mailWrapper = $layout.children(".o_mail_wrapper");
+ var $mailWrapperContent = $mailWrapper.find('.o_mail_wrapper_td');
+ if (!$mailWrapperContent.length) { // compatibility
+ $mailWrapperContent = $mailWrapper;
+ }
+ var value;
+ if ($mailWrapperContent.length > 0) {
+ value = $mailWrapperContent.html();
+ } else if ($layout.length) {
+ value = $layout.html();
+ } else {
+ value = this.wysiwyg.getValue();
+ }
+ var blankEditable = "<p><br></p>";
+ return value === "" || value === blankEditable;
+ },
+ /**
+ * @override
+ */
+ _renderEdit: function () {
+ this._isFromInline = !!this.value;
+ if (!this.value) {
+ this.value = this.recordData[this.nodeOptions['inline-field']];
+ }
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
+ _renderReadonly: function () {
+ this.value = this.recordData[this.nodeOptions['inline-field']];
+ return this._super.apply(this, arguments);
+ },
+
+ /**
+ * @override
+ * @returns {JQuery}
+ */
+ _renderTranslateButton: function () {
+ var fieldName = this.nodeOptions['inline-field'];
+ if (_t.database.multi_lang && this.record.fields[fieldName].translate && this.res_id) {
+ return $('<button>', {
+ type: 'button',
+ 'class': 'o_field_translate fa fa-globe btn btn-link',
+ })
+ .on('click', this._onTranslate.bind(this));
+ }
+ return $();
+ },
+ /**
+ * Returns the selected theme, if any.
+ *
+ * @private
+ * @param {Object} themesParams
+ * @returns {false|Object}
+ */
+ _getSelectedTheme: function (themesParams) {
+ var $layout = this.$content.find(".o_layout");
+ var selectedTheme = false;
+ if ($layout.length !== 0) {
+ _.each(themesParams, function (themeParams) {
+ if ($layout.hasClass(themeParams.className)) {
+ selectedTheme = themeParams;
+ }
+ });
+ }
+ return selectedTheme;
+ },
+ /**
+ * Swap the previous theme's default images with the new ones.
+ * (Redefine the `src` attribute of all images in a $container, depending on the theme parameters.)
+ *
+ * @private
+ * @param {Object} themeParams
+ * @param {JQuery} $container
+ */
+ _switchImages: function (themeParams, $container) {
+ if (!themeParams) {
+ return;
+ }
+ $container.find("img").each(function () {
+ var $img = $(this);
+ var src = $img.attr("src");
+
+ var m = src.match(/^\/web\/image\/\w+\.s_default_image_(?:theme_[a-z]+_)?(.+)$/);
+ if (!m) {
+ m = src.match(/^\/\w+\/static\/src\/img\/(?:theme_[a-z]+\/)?s_default_image_(.+)\.[a-z]+$/);
+ }
+ if (!m) {
+ return;
+ }
+
+ var file = m[1];
+ var img_info = themeParams.get_image_info(file);
+
+ if (img_info.format) {
+ src = "/" + img_info.module + "/static/src/img/theme_" + themeParams.name + "/s_default_image_" + file + "." + img_info.format;
+ } else {
+ src = "/web/image/" + img_info.module + ".s_default_image_theme_" + themeParams.name + "_" + file;
+ }
+
+ $img.attr("src", src);
+ });
+ },
+ /**
+ * Switch themes or import first theme.
+ *
+ * @private
+ * @param {Boolean} firstChoice true if this is the first chosen theme (going from no theme to a theme)
+ * @param {Object} themeParams
+ */
+ _switchThemes: function (firstChoice, themeParams) {
+ if (!themeParams || this.switchThemeLast === themeParams) {
+ return;
+ }
+ this.switchThemeLast = themeParams;
+
+ this.$content.closest('body').removeClass(this._allClasses).addClass(themeParams.className);
+
+ var $old_layout = this.$content.find('.o_layout');
+
+ var $new_wrapper;
+ var $newWrapperContent;
+ if (themeParams.nowrap) {
+ $new_wrapper = $('<div/>', {
+ class: 'oe_structure'
+ });
+ $newWrapperContent = $new_wrapper;
+ } else {
+ // This wrapper structure is the only way to have a responsive
+ // and centered fixed-width content column on all mail clients
+ $new_wrapper = $('<table/>', {
+ class: 'o_mail_wrapper'
+ });
+ $newWrapperContent = $('<td/>', {
+ class: 'o_mail_no_options o_mail_wrapper_td oe_structure'
+ });
+ $new_wrapper.append($('<tr/>').append(
+ $('<td/>', {
+ class: 'o_mail_no_resize o_not_editable',
+ contenteditable: 'false'
+ }),
+ $newWrapperContent,
+ $('<td/>', {
+ class: 'o_mail_no_resize o_not_editable',
+ contenteditable: 'false'
+ })
+ ));
+ }
+ var $newLayout = $('<div/>', {
+ class: 'o_layout ' + themeParams.className
+ }).append($new_wrapper);
+
+ var $contents;
+ if (firstChoice) {
+ $contents = themeParams.template;
+ } else if ($old_layout.length) {
+ $contents = ($old_layout.hasClass('oe_structure') ? $old_layout : $old_layout.find('.oe_structure').first()).contents();
+ } else {
+ $contents = this.$content.find('.o_editable').contents();
+ }
+
+ $newWrapperContent.append($contents);
+ this._switchImages(themeParams, $newWrapperContent);
+ this.$content.find('.o_editable').empty().append($newLayout);
+ $old_layout.remove();
+
+ if (firstChoice) {
+ $newWrapperContent.find('*').addBack()
+ .contents()
+ .filter(function () {
+ return this.nodeType === 3 && this.textContent.match(/\S/);
+ }).parent().addClass('o_default_snippet_text');
+
+ if (themeParams.name == 'basic') {
+ this.$content.focusIn();
+ }
+ }
+ this.wysiwyg.trigger('reload_snippet_dropzones');
+ },
+
+ //--------------------------------------------------------------------------
+ // Handler
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _onLoadWysiwyg: function () {
+ if (this._isFromInline) {
+ this._fromInline();
+ }
+ if (this.snippetsLoaded) {
+ this._onSnippetsLoaded(this.snippetsLoaded);
+ }
+ this._super();
+ },
+ /**
+ * @private
+ * @param {OdooEvent} ev
+ */
+ _onSnippetsLoaded: function (ev) {
+ var self = this;
+ if (!this.$content) {
+ this.snippetsLoaded = ev;
+ return;
+ }
+ var $snippetsSideBar = ev.data;
+ var $themes = $snippetsSideBar.find("#email_designer_themes").children();
+ var $snippets = $snippetsSideBar.find(".oe_snippet");
+ var $snippets_menu = $snippetsSideBar.find("#snippets_menu");
+
+ if (config.device.isMobile) {
+ $snippetsSideBar.hide();
+ this.$content.attr('style', 'padding-left: 0px !important');
+ }
+
+ if ($themes.length === 0) {
+ return;
+ }
+
+ /**
+ * Initialize theme parameters.
+ */
+ this._allClasses = "";
+ var themesParams = _.map($themes, function (theme) {
+ var $theme = $(theme);
+ var name = $theme.data("name");
+ var classname = "o_" + name + "_theme";
+ self._allClasses += " " + classname;
+ var imagesInfo = _.defaults($theme.data("imagesInfo") || {}, {
+ all: {}
+ });
+ _.each(imagesInfo, function (info) {
+ info = _.defaults(info, imagesInfo.all, {
+ module: "mass_mailing",
+ format: "jpg"
+ });
+ });
+ return {
+ name: name,
+ className: classname || "",
+ img: $theme.data("img") || "",
+ template: $theme.html().trim(),
+ nowrap: !!$theme.data('nowrap'),
+ get_image_info: function (filename) {
+ if (imagesInfo[filename]) {
+ return imagesInfo[filename];
+ }
+ return imagesInfo.all;
+ }
+ };
+ });
+ $themes.parent().remove();
+
+ /**
+ * Create theme selection screen and check if it must be forced opened.
+ * Reforce it opened if the last snippet is removed.
+ */
+ var $dropdown = $(core.qweb.render("mass_mailing.theme_selector", {
+ themes: themesParams
+ })).dropdown();
+
+ var firstChoice = this._checkIfMustForceThemeChoice();
+
+ /**
+ * Add proposition to install enterprise themes if not installed.
+ */
+ var $mail_themes_upgrade = $dropdown.find(".o_mass_mailing_themes_upgrade");
+ $mail_themes_upgrade.on("click", function (e) {
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ self.do_action("mass_mailing.action_mass_mailing_configuration");
+ });
+
+ /**
+ * Switch theme when a theme button is hovered. Confirm change if the theme button
+ * is pressed.
+ */
+ var selectedTheme = false;
+ $dropdown.on("mouseenter", ".dropdown-item", function (e) {
+ if (firstChoice) {
+ return;
+ }
+ e.preventDefault();
+ var themeParams = themesParams[$(e.currentTarget).index()];
+ self._switchThemes(firstChoice, themeParams);
+ });
+ $dropdown.on("mouseleave", ".dropdown-item", function (e) {
+ self._switchThemes(false, selectedTheme);
+ });
+ $dropdown.on("click", '[data-toggle="dropdown"]', function (e) {
+ var $menu = $dropdown.find('.dropdown-menu');
+ var isVisible = $menu.hasClass('show');
+ if (isVisible) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ $menu.removeClass('show');
+ }
+ });
+
+ $dropdown.on("click", ".dropdown-item", function (e) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ var themeParams = themesParams[$(e.currentTarget).index()];
+ if (firstChoice) {
+ self._switchThemes(firstChoice, themeParams);
+ self.$content.closest('body').removeClass("o_force_mail_theme_choice");
+ firstChoice = false;
+
+ if ($mail_themes_upgrade.length) {
+ $dropdown.remove();
+ $snippets_menu.empty();
+ }
+ }
+
+ self._switchImages(themeParams, $snippets);
+
+ selectedTheme = themeParams;
+
+ // Notify form view
+ self.wysiwyg.getEditable().trigger('change');
+ $dropdown.find('.dropdown-menu').removeClass('show');
+ $dropdown.find('.dropdown-item.selected').removeClass('selected');
+ $dropdown.find('.dropdown-item:eq(' + themesParams.indexOf(selectedTheme) + ')').addClass('selected');
+ });
+
+ /**
+ * If the user opens the theme selection screen, indicates which one is active and
+ * saves the information...
+ * ... then when the user closes check if the user confirmed its choice and restore
+ * previous state if this is not the case.
+ */
+ $dropdown.on("shown.bs.dropdown", function () {
+ selectedTheme = self._getSelectedTheme(themesParams);
+ $dropdown.find(".dropdown-item").removeClass("selected").filter(function () {
+ return ($(this).has(".o_thumb[style=\"" + "background-image: url(" + (selectedTheme && selectedTheme.img) + "_small.png)" + "\"]").length > 0);
+ }).addClass("selected");
+ });
+ $dropdown.on("hidden.bs.dropdown", function () {
+ self._switchThemes(firstChoice, selectedTheme);
+ });
+
+ /**
+ * On page load, check the selected theme and force switching to it (body needs the
+ * theme style for its edition toolbar).
+ */
+ selectedTheme = this._getSelectedTheme(themesParams);
+ if (selectedTheme) {
+ this.$content.closest('body').addClass(selectedTheme.className);
+ $dropdown.find('.dropdown-item:eq(' + themesParams.indexOf(selectedTheme) + ')').addClass('selected');
+ this._switchImages(selectedTheme, $snippets);
+ } else if (this.$content.find('.o_layout').length) {
+ themesParams.push({
+ name: 'o_mass_mailing_no_theme',
+ className: 'o_mass_mailing_no_theme',
+ img: "",
+ template: this.$content.find('.o_layout').addClass('o_mass_mailing_no_theme').clone().find('oe_structure').empty().end().html().trim(),
+ nowrap: true,
+ get_image_info: function () {}
+ });
+ selectedTheme = this._getSelectedTheme(themesParams);
+ }
+
+ $dropdown.insertAfter($snippets_menu);
+ },
+ /**
+ * @override
+ * @param {MouseEvent} ev
+ */
+ _onTranslate: function (ev) {
+ this.trigger_up('translate', {
+ fieldName: this.nodeOptions['inline-field'],
+ id: this.dataPointID,
+ isComingFromTranslationAlert: false,
+ });
+ },
+});
+
+fieldRegistry.add('mass_mailing_html', MassMailingFieldHtml);
+
+return MassMailingFieldHtml;
+
+});
diff --git a/addons/mass_mailing/static/src/js/tours/mass_mailing_tour.js b/addons/mass_mailing/static/src/js/tours/mass_mailing_tour.js
new file mode 100644
index 00000000..0004e50e
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/tours/mass_mailing_tour.js
@@ -0,0 +1,88 @@
+odoo.define('mass_mailing.mass_mailing_tour', function (require) {
+ "use strict";
+
+ var core = require('web.core');
+ var _t = core._t;
+ var tour = require('web_tour.tour');
+ var now = moment();
+
+ tour.register('mass_mailing_tour', {
+ url: '/web',
+ rainbowManMessage: _t('Congratulations, I love your first mailing. :)'),
+ sequence: 200,
+ }, [tour.stepUtils.showAppsMenuItem(), {
+ trigger: '.o_app[data-menu-xmlid="mass_mailing.mass_mailing_menu_root"]',
+ content: _t("Let's try the Email Marketing app."),
+ width: 210,
+ position: 'bottom',
+ edition: 'enterprise',
+ }, {
+ trigger: '.o_app[data-menu-xmlid="mass_mailing.mass_mailing_menu_root"]',
+ content: _t("Let's try the Email Marketing app."),
+ edition: 'community',
+ }, {
+ trigger: '.o-kanban-button-new',
+ content: _t("Start by creating your first <b>Mailing</b>."),
+ position: 'bottom',
+ }, {
+ trigger: 'input[name="subject"]',
+ content: _t('Pick the <b>email subject</b>.'),
+ position: 'right',
+ run: 'text ' + now.format("MMMM") + " Newsletter",
+ }, {
+ trigger: 'div[name="contact_list_ids"] > .o_input_dropdown > input[type="text"]',
+ run: 'click',
+ auto: true,
+ }, {
+ trigger: 'li.ui-menu-item',
+ run: 'click',
+ auto: true,
+ }, {
+ trigger: 'div[name="body_arch"] iframe #newsletter',
+ content: _t('Choose this <b>theme</b>.'),
+ position: 'left',
+ edition: 'enterprise',
+ run: 'click',
+ }, {
+ trigger: 'div[name="body_arch"] iframe #default',
+ content: _t('Choose this <b>theme</b>.'),
+ position: 'right',
+ edition: 'community',
+ run: 'click',
+ }, {
+ trigger: 'div[name="body_arch"] iframe div.o_mail_block_paragraph',
+ content: _t('Click on this paragraph to edit it.'),
+ position: 'top',
+ edition: 'enterprise',
+ run: 'click',
+ }, {
+ trigger: 'div[name="body_arch"] iframe div.o_mail_block_title_text',
+ content: _t('Click on this paragraph to edit it.'),
+ position: 'top',
+ edition: 'community',
+ run: 'click',
+ }, {
+ trigger: 'button[name="action_test"]',
+ content: _t("Test this mailing by sending a copy to yourself."),
+ position: 'bottom',
+ }, {
+ trigger: 'button[name="send_mail_test"]',
+ content: _t("Check the email address and click send."),
+ position: 'bottom',
+ }, {
+ trigger: 'button[name="action_put_in_queue"]',
+ content: _t("Ready for take-off!"),
+ position: 'bottom',
+ }, {
+ trigger: '.btn-primary:contains("Ok")',
+ content: _t("Don't worry, the mailing contact we created is an internal user."),
+ position: 'bottom',
+ run: "click",
+ }, {
+ trigger: '.o_back_button',
+ content: _t("By using the <b>Breadcrumb</b>, you can navigate back to the overview."),
+ position: 'bottom',
+ run: 'click',
+ }]
+ );
+});
diff --git a/addons/mass_mailing/static/src/js/unsubscribe.js b/addons/mass_mailing/static/src/js/unsubscribe.js
new file mode 100644
index 00000000..fae7d16e
--- /dev/null
+++ b/addons/mass_mailing/static/src/js/unsubscribe.js
@@ -0,0 +1,198 @@
+odoo.define('mass_mailing.unsubscribe', function (require) {
+ 'use strict';
+
+ var session = require('web.session');
+ var ajax = require('web.ajax');
+ var core = require('web.core');
+ require('web.dom_ready');
+
+ var _t = core._t;
+
+ var email = $("input[name='email']").val();
+ var mailing_id = parseInt($("input[name='mailing_id']").val());
+ var res_id = parseInt($("input[name='res_id']").val());
+ var token = (location.search.split('token' + '=')[1] || '').split('&')[0];
+
+ if (!$('.o_unsubscribe_form').length) {
+ return Promise.reject("DOM doesn't contain '.o_unsubscribe_form'");
+ }
+ session.load_translations().then(function () {
+ if (email != '' && email != undefined){
+ ajax.jsonRpc('/mailing/blacklist/check', 'call', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
+ .then(function (result) {
+ if (result == 'unauthorized'){
+ $('#button_add_blacklist').hide();
+ $('#button_remove_blacklist').hide();
+ }
+ else if (result == true) {
+ $('#button_remove_blacklist').show();
+ toggle_opt_out_section(false);
+ }
+ else if (result == false) {
+ $('#button_add_blacklist').show();
+ toggle_opt_out_section(true);
+ }
+ else {
+ $('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
+ }
+ })
+ .guardedCatch(function () {
+ $('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
+ });
+ }
+ else {
+ $('#div_blacklist').hide();
+ }
+
+ var unsubscribed_list = $("input[name='unsubscribed_list']").val();
+ if (unsubscribed_list){
+ $('#subscription_info').html(_.str.sprintf(
+ _t("You have been <strong>successfully unsubscribed from %s</strong>."),
+ _.escape(unsubscribed_list)
+ ));
+ }
+ else{
+ $('#subscription_info').html(_t('You have been <strong>successfully unsubscribed</strong>.'));
+ }
+ });
+
+ $('#unsubscribe_form').on('submit', function (e) {
+ e.preventDefault();
+
+ var checked_ids = [];
+ $("input[type='checkbox']:checked").each(function (i){
+ checked_ids[i] = parseInt($(this).val());
+ });
+
+ var unchecked_ids = [];
+ $("input[type='checkbox']:not(:checked)").each(function (i){
+ unchecked_ids[i] = parseInt($(this).val());
+ });
+
+ ajax.jsonRpc('/mail/mailing/unsubscribe', 'call', {'opt_in_ids': checked_ids, 'opt_out_ids': unchecked_ids, 'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
+ .then(function (result) {
+ if (result == 'unauthorized'){
+ $('#subscription_info').html(_t('You are not authorized to do this!'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-error').addClass('alert-warning');
+ }
+ else if (result == true) {
+ $('#subscription_info').html(_t('Your changes have been saved.'));
+ $('#info_state').removeClass('alert-info').addClass('alert-success');
+ }
+ else {
+ $('#subscription_info').html(_t('An error occurred. Your changes have not been saved, try again later.'));
+ $('#info_state').removeClass('alert-info').addClass('alert-warning');
+ }
+ })
+ .guardedCatch(function () {
+ $('#subscription_info').html(_t('An error occurred. Your changes have not been saved, try again later.'));
+ $('#info_state').removeClass('alert-info').addClass('alert-warning');
+ });
+ });
+
+ // ==================
+ // Blacklist
+ // ==================
+ $('#button_add_blacklist').click(function (e) {
+ e.preventDefault();
+
+ ajax.jsonRpc('/mailing/blacklist/add', 'call', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
+ .then(function (result) {
+ if (result == 'unauthorized'){
+ $('#subscription_info').html(_t('You are not authorized to do this!'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-error').addClass('alert-warning');
+ }
+ else
+ {
+ if (result) {
+ $('#subscription_info').html(_t('You have been successfully <strong>added to our blacklist</strong>. '
+ + 'You will not be contacted anymore by our services.'));
+ $('#info_state').removeClass('alert-warning').removeClass('alert-info').removeClass('alert-error').addClass('alert-success');
+ toggle_opt_out_section(false);
+ }
+ else {
+ $('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
+ }
+ $('#button_add_blacklist').hide();
+ $('#button_remove_blacklist').show();
+ $('#unsubscribed_info').hide();
+ }
+ })
+ .guardedCatch(function () {
+ $('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
+ });
+ });
+
+ $('#button_remove_blacklist').click(function (e) {
+ e.preventDefault();
+
+ ajax.jsonRpc('/mailing/blacklist/remove', 'call', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
+ .then(function (result) {
+ if (result == 'unauthorized'){
+ $('#subscription_info').html(_t('You are not authorized to do this!'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-error').addClass('alert-warning');
+ }
+ else
+ {
+ if (result) {
+ $('#subscription_info').html(_t("You have been successfully <strong>removed from our blacklist</strong>. "
+ + "You are now able to be contacted by our services."));
+ $('#info_state').removeClass('alert-warning').removeClass('alert-info').removeClass('alert-error').addClass('alert-success');
+ toggle_opt_out_section(true);
+ }
+ else {
+ $('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
+ }
+ $('#button_add_blacklist').show();
+ $('#button_remove_blacklist').hide();
+ $('#unsubscribed_info').hide();
+ }
+ })
+ .guardedCatch(function () {
+ $('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
+ });
+ });
+
+ // ==================
+ // Feedback
+ // ==================
+ $('#button_feedback').click(function (e) {
+ var feedback = $("textarea[name='opt_out_feedback']").val();
+ e.preventDefault();
+ ajax.jsonRpc('/mailing/feedback', 'call', {'mailing_id': mailing_id, 'res_id': res_id, 'email': email, 'feedback': feedback, 'token': token})
+ .then(function (result) {
+ if (result == 'unauthorized'){
+ $('#subscription_info').html(_t('You are not authorized to do this!'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-error').addClass('alert-warning');
+ }
+ else if (result == true){
+ $('#subscription_info').html(_t('Thank you! Your feedback has been sent successfully!'));
+ $('#info_state').removeClass('alert-warning').removeClass('alert-info').removeClass('alert-error').addClass('alert-success');
+ $("#div_feedback").hide();
+ }
+ else {
+ $('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
+ $('#info_state').removeClass('alert-success').removeClass('alert-info').removeClass('alert-error').addClass('alert-warning');
+ }
+ })
+ .guardedCatch(function () {
+ $('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
+ $('#info_state').removeClass('alert-info').removeClass('alert-success').removeClass('alert-error').addClass('alert-warning');
+ });
+ });
+});
+
+function toggle_opt_out_section(value) {
+ var result = !value;
+ $("#div_opt_out").find('*').attr('disabled',result);
+ $("#button_add_blacklist").attr('disabled', false);
+ $("#button_remove_blacklist").attr('disabled', false);
+ if (value) { $('[name="button_subscription"]').addClass('clickable'); }
+ else { $('[name="button_subscription"]').removeClass('clickable'); }
+}
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.scss b/addons/mass_mailing/static/src/scss/mass_mailing.scss
new file mode 100644
index 00000000..5b8ebff2
--- /dev/null
+++ b/addons/mass_mailing/static/src/scss/mass_mailing.scss
@@ -0,0 +1,50 @@
+.o_kanban_view {
+ .oe_kanban_mass_mailing {
+ .o_title {
+ margin-bottom: 16px;
+ }
+ .o_kanban_primary_bottom {
+ margin-top: 16px;
+ }
+ .oe_margin_top_8 {
+ margin-top: 8px;
+ }
+ .oe_margin_bottom_8 {
+ margin-bottom: 8px;
+ }
+ }
+}
+.o_form_view {
+ // This will display the emoji widget in the right position after a text field with sms option.
+ .o_sms_container ~ .o_mail_add_emoji{
+ bottom: 55px;
+ }
+}
+.o_white_body {
+ background-color: white;
+}
+
+.o_mass_mailing_unsubscribed {
+ margin-left: 20px;
+ color: #005326;
+ font-size: 90%;
+}
+
+@media only screen and (min-width: 1200px) {
+ .o_utm_campaign_mass_mailing_substats {
+ padding-right: 210px;
+ div {
+ margin-left: 50px;
+ }
+ }
+}
+
+@media only screen and (min-width: 768px) and (max-width: 1200px) {
+ .o_utm_campaign_mass_mailing_substats {
+ padding-right: 180px;
+ div {
+ margin-left: 30px;
+ }
+ }
+}
+
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.ui.jw.scss b/addons/mass_mailing/static/src/scss/mass_mailing.ui.jw.scss
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/addons/mass_mailing/static/src/scss/mass_mailing.ui.jw.scss
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss b/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss
new file mode 100644
index 00000000..fea99064
--- /dev/null
+++ b/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss
@@ -0,0 +1,206 @@
+.o_form_view .o_form_sheet .o_notebook .tab-content .tab-pane .o_mail_body {
+ // cancel padding of form_sheet
+ margin-top: -$o-sheet-cancel-tpadding;
+ margin-left: -$o-sheet-cancel-hpadding;
+ margin-right: -$o-sheet-cancel-hpadding;
+ margin-bottom: -$o-sheet-cancel-bpadding;
+}
+
+.o_mail_theme_selector {
+ > a {
+ @include o-position-absolute(0, 0, auto, 0);
+ height: $o-we-toolbar-height;
+ line-height: $o-we-toolbar-height;
+ border-radius: 0;
+ background-color: $o-we-sidebar-bg;
+ color: #212629;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-shadow: none !important;
+
+ &:hover, &:focus, &:active {
+ color: #4e525b;
+ }
+
+ i {
+ margin-right: 10px;
+ }
+ }
+
+ &.show > a {
+ color: white;
+ background-color: #212629;
+ }
+
+ .dropdown-menu {
+ position: absolute;
+ bottom: -2px;
+ top: -3px !important;
+ left: -5px !important;
+ right: -2px !important;
+ margin: 0;
+ border-radius: 0;
+ overflow: auto;
+ background-color: $o-we-sidebar-bg;
+ z-index: 1050;
+
+ &.show {
+ bottom: 31px !important;
+ top: -2px !important;
+ right: 3px !important;
+ }
+
+ .dropdown-item {
+ padding: 10px 10px;
+ &:first-child {
+ display: none;
+ }
+
+ .o_thumb {
+ display: none;
+ background-size: cover;
+ padding-top: 50%;
+ border: 1px solid $o-we-border-color;
+
+
+ &.logo {
+ display: block;
+ }
+ }
+
+
+ &:hover {
+ background-color: $o-we-sidebar-bg;
+
+ .o_thumb {
+ border: 1px solid black;
+ }
+ }
+
+ &.selected .o_thumb {
+ border: 2px solid $o-brand-odoo;
+ background-color: $o-we-sidebar-bg;
+ }
+ }
+ }
+}
+
+body.o_force_mail_theme_choice {
+ #oe_snippets {
+ width: 100%;
+
+ .o_mail_theme_selector {
+ .dropdown-toggle {
+ display: none;
+ }
+
+ .dropdown-menu {
+ display: block;
+
+ .dropdown-item {
+ margin: 0;
+ float: left;
+ clear: none;
+ width: 100%;
+ max-width: 25%;
+ transition: all 0.3s ease 0s;
+
+ &:first-child {
+ display: block;
+ }
+
+ .o_thumb {
+ display: none;
+ padding-top: 107%;
+ border: 1px solid #4e525b;
+ border-top: 1px solid $o-we-border-color;
+ box-shadow: 0 5px 10px rgba(black, 0.8);
+ will-change: transform;
+ backface-visibility: hidden;
+ transition: all 0.3s ease 0s;
+
+ &.small {
+ display: block;
+ }
+
+ @media screen and (min-width: 900px) {
+ &.small {
+ display: none;
+ }
+ &.large {
+ display: block;
+ }
+ }
+ }
+
+ &:hover {
+ background-color: #212629;
+
+ .o_thumb {
+ box-shadow: 0 5px 30px 1px rgba(black, 0.6);
+ }
+ }
+
+ &.o_mass_mailing_themes_upgrade .o_thumb {
+ position: relative;
+ display: block;
+ border: 1px dashed white;
+ opacity: 0.2;
+
+ > .fa {
+ @include o-position-absolute(0, 0, 0, 0);
+ text-align: center;
+ font-size: 50px;
+ color: white;
+
+ &::before {
+ vertical-align: middle;
+ }
+ &::after {
+ content: "";
+ display: inline-block;
+ height: 100%;
+ vertical-align: middle;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ .note-editor {
+ display: none;
+ }
+}
+
+body.editor_enable.o_basic_theme.o_in_iframe {
+ padding-right: 0px !important;
+
+ #web_editor-top-edit .note-popover .popover {
+ right: 0 !important;
+ }
+
+ #oe_snippets {
+ display: none;
+ }
+}
+
+.note-editable .o_layout {
+ overflow: initial;
+}
+
+#web_editor-toolbars .popover .note-color {
+ .note-back-color-preview .dropdown-toggle,
+ .note-fore-color-preview .dropdown-toggle {
+ height: $o-we-toolbar-height - 1;
+ }
+}
+
+.oe_structure {
+ width: 100%;
+}
+
+:root {
+ font-size: 14px;
+}
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.ui.shadow.scss b/addons/mass_mailing/static/src/scss/mass_mailing.ui.shadow.scss
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/addons/mass_mailing/static/src/scss/mass_mailing.ui.shadow.scss
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing_mobile.scss b/addons/mass_mailing/static/src/scss/mass_mailing_mobile.scss
new file mode 100644
index 00000000..9df45859
--- /dev/null
+++ b/addons/mass_mailing/static/src/scss/mass_mailing_mobile.scss
@@ -0,0 +1,7 @@
+@include media-breakpoint-down(sm) {
+ .o_utm_campaign_mass_mailing_substats {
+ width: 80%;
+ margin: 0 auto;
+ justify-content: space-between !important;
+ }
+} \ No newline at end of file
diff --git a/addons/mass_mailing/static/src/scss/themes/theme_basic.scss b/addons/mass_mailing/static/src/scss/themes/theme_basic.scss
new file mode 100644
index 00000000..d65ea077
--- /dev/null
+++ b/addons/mass_mailing/static/src/scss/themes/theme_basic.scss
@@ -0,0 +1,54 @@
+
+// TODO remove in master
+// Themes scss have to use bg-variant and text-emphasis-variant mixins of BS4
+// to properly work. That use was introduced as a fix in 12.0... but the BS4
+// mixins are unavailable in the mailing assets. As a stable fix cannot
+// introduce static code which requires an XML update to not crash, the mixins
+// were duplicated here instead.
+@mixin bg-variant($parent, $color) {
+ #{$parent} {
+ background-color: $color !important;
+ }
+ a#{$parent},
+ button#{$parent} {
+ &:hover, &:focus {
+ background-color: darken($color, 10%) !important;
+ }
+ }
+}
+@mixin text-emphasis-variant($parent, $color) {
+ #{$parent} {
+ color: $color !important;
+ }
+ a#{$parent} {
+ &:hover, &:focus {
+ color: darken($color, 10%) !important;
+ }
+ }
+}
+
+// ============================
+// Mass Mailing "Theme Basic"
+// ============================
+
+// ===== Layout =====
+.o_basic_theme {
+ &.o_layout {
+ margin: 0;
+ padding: 0;
+ background-color: white;
+
+ &, p, h1, h2, h3, h4, h5, h6, span, ul, ol {
+ color: black;
+ }
+
+ p {
+ font-size: 13px;
+ margin-bottom: 0px;
+ }
+
+ ul, ol {
+ margin: 0;
+ }
+ }
+}
diff --git a/addons/mass_mailing/static/src/scss/themes/theme_default.scss b/addons/mass_mailing/static/src/scss/themes/theme_default.scss
new file mode 100644
index 00000000..96e98648
--- /dev/null
+++ b/addons/mass_mailing/static/src/scss/themes/theme_default.scss
@@ -0,0 +1,307 @@
+// ============================
+// Mass Mailing "Theme Default"
+// ============================
+
+// ===== Default Theme palette =====
+$o-mm-def-color-1: #f5f5f5;
+$o-mm-def-color-2: #ffffff;
+$o-mm-def-color-3: #706482;
+$o-mm-def-color-4: #464646;
+$o-mm-def-color-5: darken($o-mm-def-color-3, 5%);
+$o-mm-def-color-6: #706482;
+$o-mm-def-color-7: #87a6b5;
+
+// ===== Default Theme variables =====
+$o-mm-def-body-width : 600px;
+$o-mm-def-body-bobile : 480px;
+$o-mm-def-b-radius : 2px;
+$o-mm-def-body-bg : $o-mm-def-color-2;
+
+$o-mm-def-font : -apple-system, "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
+$o-mm-def-text-color : $o-mm-def-color-4;
+
+$o-mm-def-btn-bg : $o-mm-def-color-3;
+$o-mm-def-btn-text : $o-mm-def-color-2;
+
+// ===== Colors =====
+@include bg-variant(".bg-o-color-2", $o-mm-def-color-6);
+@include text-emphasis-variant(".text-o-color-2", $o-mm-def-color-6);
+@include bg-variant(".bg-o-color-4", $o-mm-def-color-7);
+@include bg-variant(".bg-gray-lighter", $o-mm-def-color-1);
+
+td:not([align]) {
+ // Default browser style but needed so that alignment works on some mail
+ // clients (see convert_inline)
+ text-align: inherit;
+}
+
+// ===== Layout =====
+.o_layout {
+ overflow: hidden;
+ box-sizing: content-box;
+ width: 94%;
+ min-height: 100%;
+ background-color: $o-mm-def-color-1;
+ padding: 0 3%;
+
+ // Forces on <p/> and <hx/> elements as several mail clients does not
+ // correctly inherit font properties
+ &, p, ol {
+ font-size: 14px; // force bootstrap default
+ }
+ &, p, h1, h2, h3, h4, h5, h6, ol {
+ font-family: $o-mm-def-font;
+ color: lighten($o-mm-def-text-color, 20%);
+ }
+
+ > .o_mail_wrapper {
+ width: 100%;
+ border-collapse: separate; // Allow the first and last td to have the
+ // same width
+
+ .o_mail_wrapper_td {
+ width: $o-mm-def-body-width;
+ border: 1px solid darken($o-mm-def-color-1, 2%);
+ background-color: $o-mm-def-color-2;
+ }
+ }
+}
+
+// ===== Snippets (general) =====
+.o_mail_snippet_general {
+ width: 100%;
+ max-width: $o-mm-def-body-width; // should not be necessary thanks to mail wrapper
+ margin: 0 auto;
+
+ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
+ color: $o-mm-def-text-color;
+ }
+
+ .btn.btn-primary {
+ color: $o-mm-def-btn-text;
+ border: none;
+ text-decoration: none;
+ font-weight: normal;
+ font-family: $o-mm-def-font;
+ cursor: pointer;
+ border-radius: $o-mm-def-b-radius;
+ background-color: $o-mm-def-btn-bg;
+ }
+
+ a:not(.btn), .btn.btn-link {
+ color: $o-mm-def-color-5;
+ font-weight: bold;
+ text-decoration: none !important;
+
+ &:hover, &:focus, &:active {
+ text-decoration: none !important;
+ }
+ }
+
+ img {
+ width: 100%;
+ max-width: 100%;
+ height: auto;
+ }
+
+ .separator {
+ height: 2px;
+ background-color: $o-mm-def-color-1;
+ }
+
+ .bg-o-color-2 {
+ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
+ color: $o-mm-def-color-2;
+ }
+
+ .btn.btn-primary {
+ background-color: $o-mm-def-color-7;
+ }
+
+ a:not(.btn), .btn.btn-link {
+ color: $o-mm-def-color-7;
+ }
+ }
+
+ td, th {
+ vertical-align: top;
+ }
+}
+
+// ===== Snippets (specific) =====
+.o_mail_block_header_social, .o_mail_block_header_text_social, .o_mail_block_header_logo {
+ .o_mail_logo_container {
+ img {
+ width: auto;
+ }
+ }
+ .o_mail_header_social {
+ margin-right: 20px;
+
+ a:not(.btn), .btn.btn-link {
+ display: inline-block;
+ }
+ }
+ td {
+ vertical-align: middle;
+ }
+}
+
+.o_mail_block_header_text_social {
+ h3 {
+ font-weight: bold;
+ }
+}
+
+.o_mail_block_steps .o_mail_snippet_general{
+ background-color: $o-mm-def-color-1;
+}
+
+.o_mail_block_two_cols, .o_mail_block_three_cols {
+ // Forces on <p/> elements as several mail clients does not correctly
+ // inherit font properties
+ &, p {
+ font-size: small;
+ }
+
+ .o_mail_col_container {
+ padding: 10px 20px;
+
+ h4 {
+ margin-top: 15px;
+ }
+ }
+}
+
+.o_mail_block_image_text, .o_mail_block_text_image {
+ // Forces on <p/> elements as several mail clients does not correctly
+ // inherit font properties
+ &, p {
+ font-size: small;
+ }
+}
+
+.o_mail_block_event {
+ margin-left: 20px;
+ margin-right: 20px;
+ .o_mail_snippet_general{
+ background: darken($o-mm-def-color-1, 2%);
+ }
+}
+
+.o_mail_block_footer_separator {
+ margin-left: 20px;
+ margin-right: 20px;
+}
+
+.o_mail_block_comparison_table {
+ .separator {
+ height: 1px;
+ background-color: darken($o-mm-def-color-1, 15%);
+ }
+ table table {
+ td, th {
+ vertical-align: middle;
+ }
+ td {
+ padding: 10px 20px;
+ * {
+ margin: 0;
+ line-height: 1.3;
+ }
+ }
+ }
+}
+
+.o_mail_block_discount2 {
+ .o_code {
+ padding: 5px 10px;
+ background: $o-mm-def-color-1;
+ border-radius: 3px;
+ font-family: monospace;
+ }
+}
+
+.o_mail_block_footer_social {
+ .o_mail_table_styles {
+ border-top: 2px solid $o-mm-def-color-1;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ }
+
+ .o_mail_footer_links {
+ padding-top: 10px;
+ padding-bottom: 10px;
+
+ .btn-link{
+ padding: 0;
+ font-size: 12px;
+ }
+ }
+
+ .o_mail_footer_copy {
+ font-size: 9px;
+ font-weight: bold;
+ color: lighten($o-mm-def-text-color, 30%);
+ }
+
+ &.o_mail_footer_social_center {
+ .o_mail_footer_social, .o_mail_footer_links, .o_mail_footer_copy {
+ text-align: center;
+ }
+ }
+
+ &.o_mail_footer_social_left {
+ .o_mail_footer_description {
+ padding-left: 20px;
+ }
+ .o_mail_footer_social {
+ padding-right: 20px;
+ text-align: right;
+ vertical-align: top;
+
+ .btn-link{
+ padding: 0;
+ font-size: 12px;
+ }
+ }
+ }
+ td {
+ vertical-align: middle;
+ }
+}
+
+.o_mail_display_coupon {
+ font-size: 50px;
+ line-height: 1;
+}
+
+// ===== Misc =====
+.o_mail_h_padding {
+ padding-left: 20px;
+ padding-right: 20px;
+}
+.o_mail_v_padding {
+ padding-top: 20px;
+ padding-bottom: 20px;
+}
+.o_mail_no_margin {
+ margin: 0;
+
+ &.o_mail_display_coupon {
+ line-height: 1.1;
+ }
+}
+.o_mail_table_styles {
+ width: 100%;
+ border-collapse:separate;
+}
+
+// Compatibility: mb/mt classes on <td/> elements were interpreted as paddings
+// instead of margins before the introduction of pb/pt classes. As thoses mb/mt
+// classes may remain on clients' templates, <td/> are forced to 0 margin to
+// be sure (normally <td/> should not consider margin properties but some mail
+// clients might make the mistake to do so).
+td[class*="mb"], td[class*="mt"] {
+ margin: 0!important;
+}
diff --git a/addons/mass_mailing/static/src/xml/mass_mailing.xml b/addons/mass_mailing/static/src/xml/mass_mailing.xml
new file mode 100644
index 00000000..b4a3bfce
--- /dev/null
+++ b/addons/mass_mailing/static/src/xml/mass_mailing.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates id="template" xml:space="preserve">
+ <div t-name="mass_mailing.theme_selector" class="o_mail_theme_selector">
+ <a role="button" href="#" class="btn btn-sm dropdown-toggle" data-toggle="dropdown">
+ <i class="fa fa-paint-brush"/> Change Style
+ </a>
+ <div class="dropdown-menu" role="menu">
+ <t t-foreach="themes" t-as="theme">
+ <a t-att-id="theme.name" role="menuitem" href="#" class="dropdown-item">
+ <div class="o_thumb small" t-attf-style="background-image: url(#{theme.img}_small.png)"/>
+ <div class="o_thumb large" t-attf-style="background-image: url(#{theme.img}_large.png)"/>
+ <div class="o_thumb logo" t-attf-style="background-image: url(#{theme.img}_logo.png)"/>
+ </a>
+ </t>
+ <t t-if="themes.length === 1">
+ <a role="menuitem" href="#" class="dropdown-item o_mass_mailing_themes_upgrade">
+ <div class="o_thumb"><i class="fa fa-plus" role="img" aria-label="Upgrade theme" title="Upgrade theme"/></div>
+ </a>
+ </t>
+ </div>
+ </div>
+</templates>