summaryrefslogtreecommitdiff
path: root/addons/website/static
diff options
context:
space:
mode:
authorCocographique <nmi@odoo.com>2020-04-06 12:19:08 +0000
committerqsm-odoo <qsm@odoo.com>2020-06-12 17:06:36 +0000
commite5a5f98819b3a70b3e2564fb91722cab415ceea9 (patch)
tree3afeddd2b30ae78ee5414790f7ec674d684e9b56 /addons/website/static
parentcd4eb1fd33f76358849410d3f74581ed2889cf15 (diff)
[IMP] website: improve "Popup" snippet
Review the layout to always use standard bootstrap classes so that future task targeting modal can target s_popup snippets the same way (for example: our task allowing to open a popup on click on a button). This also allows to simplify the css and simplify the options. A new option also now allows to have a backdrop, or not, so that user clicks are blocked while the popup is opened, or not. + Adapt cookie bar accordingly. Part of https://github.com/odoo/odoo/pull/52698 task-2210730 Co-authored-by: qsm-odoo <qsm@odoo.com>
Diffstat (limited to 'addons/website/static')
-rw-r--r--addons/website/static/src/img/snippets_demo/s_popup.jpgbin0 -> 115943 bytes
-rw-r--r--addons/website/static/src/js/editor/snippets.options.js2
-rw-r--r--addons/website/static/src/scss/website.edit_mode.scss21
-rw-r--r--addons/website/static/src/scss/website.scss7
-rw-r--r--addons/website/static/src/snippets/s_popup/000.js36
-rw-r--r--addons/website/static/src/snippets/s_popup/000.scss2
-rw-r--r--addons/website/static/src/snippets/s_popup/001.scss66
-rw-r--r--addons/website/static/src/snippets/s_popup/options.js71
-rw-r--r--addons/website/static/src/xml/website.cookies_bar.xml82
9 files changed, 179 insertions, 108 deletions
diff --git a/addons/website/static/src/img/snippets_demo/s_popup.jpg b/addons/website/static/src/img/snippets_demo/s_popup.jpg
new file mode 100644
index 00000000000..3043903ef0b
--- /dev/null
+++ b/addons/website/static/src/img/snippets_demo/s_popup.jpg
Binary files differ
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index d1d3365c67b..88a00678336 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -1806,7 +1806,7 @@ options.registry.CookiesBar = options.registry.SnippetPopup.extend({
websiteId: websiteId,
}));
- const $content = this.$target.find('.s_popup_content');
+ const $content = this.$target.find('.modal-content');
const selectorsToKeep = [
'.o_cookies_bar_text_button',
'.o_cookies_bar_text_policy',
diff --git a/addons/website/static/src/scss/website.edit_mode.scss b/addons/website/static/src/scss/website.edit_mode.scss
index dc843fd148f..b916b232a85 100644
--- a/addons/website/static/src/scss/website.edit_mode.scss
+++ b/addons/website/static/src/scss/website.edit_mode.scss
@@ -150,21 +150,12 @@ table.editorbar-panel {
}
// s_popup in edit mode
-.editor_has_snippets {
- .s_popup_main {
- z-index: 1000 !important;
- left: $o-we-sidebar-width !important;
- top: var(--o-we-toolbar-height) !important;
-
- &.s_popup_fixed {
- .s_popup_full .s_popup_content {
- left: $o-we-sidebar-width !important;
- }
- }
- &.s_popup_fixed_top {
- .s_popup_content {
- top: var(--o-we-toolbar-height) !important;
- }
+body.editor_enable.editor_has_snippets {
+ .s_popup .modal {
+ top: var(--o-we-toolbar-height);
+ background-color: transparent;
+ &.fade .modal-dialog {
+ transform: none;
}
}
}
diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss
index 321f7792112..b954f1116f2 100644
--- a/addons/website/static/src/scss/website.scss
+++ b/addons/website/static/src/scss/website.scss
@@ -996,3 +996,10 @@ $ribbon-padding: 100px;
@include o-position-absolute($top: 0, $left: 0);
padding: 0.25rem 1rem;
}
+
+// Cookies Bar
+#website_cookies_bar {
+ :not(.o_cookies_popup) {
+ bottom: 0;
+ }
+}
diff --git a/addons/website/static/src/snippets/s_popup/000.js b/addons/website/static/src/snippets/s_popup/000.js
index a16b711b290..37b8e2a6a22 100644
--- a/addons/website/static/src/snippets/s_popup/000.js
+++ b/addons/website/static/src/snippets/s_popup/000.js
@@ -9,6 +9,7 @@ const PopupWidget = publicWidget.Widget.extend({
selector: '.s_popup',
events: {
'click .js_close_popup': '_onCloseClick',
+ 'hide.bs.modal': '_onHideModal',
},
/**
@@ -38,7 +39,7 @@ const PopupWidget = publicWidget.Widget.extend({
* @private
*/
_bindPopup: function () {
- const $main = this.$target.find('.s_popup_main');
+ const $main = this.$target.find('.modal');
let display = $main.data('display');
let delay = $main.data('showAfter');
@@ -48,7 +49,7 @@ const PopupWidget = publicWidget.Widget.extend({
display = 'afterDelay';
delay = 5000;
}
- this.$('.s_popup_main').removeClass('s_popup_center').addClass('s_popup_bottom');
+ this.$('.modal').removeClass('s_popup_middle').addClass('s_popup_bottom');
}
if (display === 'afterDelay') {
@@ -61,7 +62,7 @@ const PopupWidget = publicWidget.Widget.extend({
* @private
*/
_hidePopup: function () {
- this.$target.find('.s_popup_main').addClass('d-none');
+ this.$target.find('.modal').modal('hide');
},
/**
* @private
@@ -70,7 +71,7 @@ const PopupWidget = publicWidget.Widget.extend({
if (this._popupAlreadyShown) {
return;
}
- this.$target.find('.s_popup_main').removeClass('d-none');
+ this.$target.find('.modal').modal('show');
},
//--------------------------------------------------------------------------
@@ -81,14 +82,37 @@ const PopupWidget = publicWidget.Widget.extend({
* @private
*/
_onCloseClick: function () {
- const nbDays = this.$el.find('.s_popup_main').data('consentsDuration');
+ this._hidePopup();
+ },
+ /**
+ * @private
+ */
+ _onHideModal: function () {
+ const nbDays = this.$el.find('.modal').data('consentsDuration');
utils.set_cookie(this.$el.attr('id'), true, nbDays * 24 * 60 * 60);
this._popupAlreadyShown = true;
- this._hidePopup();
},
});
publicWidget.registry.popup = PopupWidget;
+// Prevent bootstrap to prevent scrolling and to add the strange body
+// padding-right they add if the popup does not use a backdrop (especially
+// important for default cookie bar).
+const _baseSetScrollbar = $.fn.modal.Constructor.prototype._setScrollbar;
+$.fn.modal.Constructor.prototype._setScrollbar = function () {
+ if (this._element.classList.contains('s_popup_no_backdrop')) {
+ return;
+ }
+ return _baseSetScrollbar.apply(this, ...arguments);
+};
+const _baseGetScrollbarWidth = $.fn.modal.Constructor.prototype._getScrollbarWidth;
+$.fn.modal.Constructor.prototype._getScrollbarWidth = function () {
+ if (this._element.classList.contains('s_popup_no_backdrop')) {
+ return 0;
+ }
+ return _baseGetScrollbarWidth.apply(this, ...arguments);
+};
+
return PopupWidget;
});
diff --git a/addons/website/static/src/snippets/s_popup/000.scss b/addons/website/static/src/snippets/s_popup/000.scss
index a7e28c8e6a9..b548a97dd79 100644
--- a/addons/website/static/src/snippets/s_popup/000.scss
+++ b/addons/website/static/src/snippets/s_popup/000.scss
@@ -1,5 +1,5 @@
// s_popup
-.s_popup_main {
+.s_popup_main:not([data-vcss]) {
.s_popup_content {
// keep lower than <p> height (cookies bar)
min-height: $o-font-size-base * $o-line-height-base;
diff --git a/addons/website/static/src/snippets/s_popup/001.scss b/addons/website/static/src/snippets/s_popup/001.scss
new file mode 100644
index 00000000000..af92f1b8c42
--- /dev/null
+++ b/addons/website/static/src/snippets/s_popup/001.scss
@@ -0,0 +1,66 @@
+.s_popup[data-vcss='001'] {
+ .modal-content {
+ min-height: $font-size-lg * 2;
+ border: 0;
+ border-radius: 0;
+ box-shadow: $modal-content-box-shadow-sm-up;
+ }
+
+ // Close icon
+ .s_popup_close {
+ z-index: $zindex-modal;
+ @include o-position-absolute(0, 0);
+ width: $font-size-lg * 2;
+ height: $font-size-lg * 2;
+ line-height: $font-size-lg * 2;
+ @include o-bg-color(color-yiq(o-color('primary')), o-color('primary'), $with-extras: false);
+ box-shadow: $box-shadow-sm;
+ cursor: pointer;
+ font-size: $font-size-lg;
+ text-align: center;
+ }
+
+ // Size option - Full
+ .s_popup_size_full {
+ padding: 0 !important;
+ max-width: 100%;
+
+ > .modal-content {
+ // Use the backdrop color as background-color
+ background-color: transparent;
+ box-shadow: none;
+ border-radius: 0;
+ }
+ }
+
+ // Position option - Middle
+ .s_popup_middle .modal-dialog {
+ align-items: center;
+ }
+
+ // Position option - Top/Bottom
+ .s_popup_top,
+ .s_popup_bottom {
+ .modal-dialog {
+ margin-right: 0;
+ &:not(.s_popup_size_full) {
+ padding: $spacer !important;
+ }
+ }
+ }
+ .s_popup_top .modal-dialog {
+ align-items: flex-start;
+ }
+ .s_popup_bottom .modal-dialog {
+ align-items: flex-end;
+ }
+
+ // No backdrop
+ .s_popup_no_backdrop {
+ pointer-events: none;
+
+ .modal-content {
+ pointer-events: auto;
+ }
+ }
+}
diff --git a/addons/website/static/src/snippets/s_popup/options.js b/addons/website/static/src/snippets/s_popup/options.js
index c667d8adc59..f31c00d3419 100644
--- a/addons/website/static/src/snippets/s_popup/options.js
+++ b/addons/website/static/src/snippets/s_popup/options.js
@@ -10,16 +10,29 @@ options.registry.SnippetPopup = options.Class.extend({
start: function () {
// Note: the link are excluded here so that internal modal buttons do
// not close the popup as we want to allow edition of those buttons.
- this.$target.find('.js_close_popup:not(a, .btn)').on('click', ev => {
+ this.$target.on('click.SnippetPopup', '.js_close_popup:not(a, .btn)', ev => {
ev.stopPropagation();
this.onTargetHide();
this.trigger_up('snippet_option_visibility_update', {show: false});
});
+ this.$target.on('shown.bs.modal.SnippetPopup', () => {
+ this.trigger_up('snippet_option_visibility_update', {show: true});
+ });
+ this.$target.on('hidden.bs.modal.SnippetPopup', () => {
+ this.trigger_up('snippet_option_visibility_update', {show: false});
+ });
return this._super(...arguments);
},
/**
* @override
*/
+ destroy: function () {
+ this._super(...arguments);
+ this.$target.off('.SnippetPopup');
+ },
+ /**
+ * @override
+ */
onBuilt: function () {
this._assignUniqueID();
},
@@ -33,14 +46,26 @@ options.registry.SnippetPopup = options.Class.extend({
* @override
*/
onTargetShow: async function () {
- this.$target.removeClass('d-none');
+ this.$target.modal('show');
+ $(document.body).children('.modal-backdrop:last').addClass('d-none');
},
/**
* @override
*/
onTargetHide: async function () {
- this.$target.addClass('d-none');
+ return new Promise(resolve => {
+ const timeoutID = setTimeout(() => {
+ this.$target.off('hidden.bs.modal.popup_on_target_hide');
+ resolve();
+ }, 500);
+ this.$target.one('hidden.bs.modal.popup_on_target_hide', () => {
+ clearTimeout(timeoutID);
+ resolve();
+ });
+ this.$target.modal('hide');
+ });
},
+
//--------------------------------------------------------------------------
// Options
//--------------------------------------------------------------------------
@@ -56,18 +81,11 @@ options.registry.SnippetPopup = options.Class.extend({
this.$target.closest('.s_popup').prependTo($container.find('.oe_structure:o_editable').first());
},
/**
- * Switch layout from modal <--> a sticky div
- *
* @see this.selectClass for parameters
*/
- setLayout: function (previewMode, widgetValue, params) {
- const isModal = widgetValue === 'modal';
- const isTop = widgetValue === 'fixedTop';
- this.$target.toggleClass('s_popup_fixed', !isModal);
- this.$target.toggleClass('s_popup_fixed_top', isTop);
- this.$target.toggleClass('s_popup_center modal', isModal);
- this.$target.find('.s_popup_frame').toggleClass('modal-dialog modal-dialog-centered', isModal);
- this.$target.find('.s_popup_content').toggleClass('modal-content', isModal);
+ setBackdrop(previewMode, widgetValue, params) {
+ const color = widgetValue ? 'var(--black-50)' : '';
+ this.$target[0].style.setProperty('background-color', color, 'important');
},
//--------------------------------------------------------------------------
@@ -89,33 +107,6 @@ options.registry.SnippetPopup = options.Class.extend({
switch (methodName) {
case 'moveBlock':
return this.$target.closest('footer').length ? 'moveToFooter' : 'moveToBody';
- case 'setLayout':
- if (this.$target.hasClass('s_popup_center')) {
- return 'modal';
- } else if (this.$target.hasClass('s_popup_fixed_top')) {
- return 'fixedTop';
- }
- return 'fixedBottom';
- }
- return this._super(...arguments);
- },
-});
-
-options.registry.PopupContent = options.Class.extend({
-
- //--------------------------------------------------------------------------
- // Private
- //--------------------------------------------------------------------------
-
- /**
- * Enable bg-color only if "centered AND full-size".
- * Visibility according to the size is managed by data-dependencies.
- *
- * @override
- */
- async _computeWidgetVisibility(widgetName, params) {
- if (widgetName === 'popup_content_colorpicker_opt') {
- return this.$target.closest('.s_popup_main').hasClass('s_popup_center');
}
return this._super(...arguments);
},
diff --git a/addons/website/static/src/xml/website.cookies_bar.xml b/addons/website/static/src/xml/website.cookies_bar.xml
index 8f43ccb3698..1f43786926b 100644
--- a/addons/website/static/src/xml/website.cookies_bar.xml
+++ b/addons/website/static/src/xml/website.cookies_bar.xml
@@ -1,74 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="website.cookies_bar.text_title">
- <div class="o_cookies_bar_text_title">
- <p>Respecting your privacy is our priority.</p>
- </div>
+ <h3 class="o_cookies_bar_text_title">
+ Respecting your privacy is our priority.
+ </h3>
</t>
<t t-name="website.cookies_bar.text_primary">
- <div class="o_cookies_bar_text_primary">
+ <p class="o_cookies_bar_text_primary">
We use cookies to provide you a better user experience.
- </div>
+ </p>
</t>
<t t-name="website.cookies_bar.text_secondary">
- <div class="o_cookies_bar_text_secondary">
- We use them to store info about your habits on our website. It will helps us to provide you the very best experience and customize what you see.
- <br/>
+ <p class="o_cookies_bar_text_secondary">
+ We use them to store info about your habits on our website. It will helps us to provide you the very best experience and customize what you see. <br/>
By clicking on this banner, you give us permission to collect data.
- </div>
+ </p>
</t>
-
<t t-name="website.cookies_bar.discrete">
- <section class="pt4 pb4">
- <div class="container text-600 d-flex align-items-center">
- <div class="mb0">
- <t t-call="website.cookies_bar.text_primary"/>
+ <section class="o_colored_level o_cc o_cc1">
+ <div class="container">
+ <div class="row">
+ <div class="col-lg-8 pt16">
+ <p>We use cookies to provide you a better user experience.</p>
+ </div>
+ <div class="col-lg-4 pt16 text-right">
+ <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link btn-sm">Cookie Policy</a>
+ <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-sm">I agree</a>
+ </div>
</div>
- <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link btn-sm text-nowrap ml-auto">Cookie Policy</a>
- <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-sm text-nowrap">I agree</a>
</div>
</section>
</t>
<t t-name="website.cookies_bar.classic">
- <section class="pt24 pb24">
- <div class="container text-600 d-flex align-items-center">
- <div>
- <div class="h3 text-900">
+ <section class="o_colored_level o_cc o_cc1 pt32 pb16">
+ <div class="container">
+ <div class="row">
+ <div class="col-lg-6">
<t t-call="website.cookies_bar.text_title"/>
- </div>
- <div class="small">
<t t-call="website.cookies_bar.text_primary"/>
- </div>
- <div class="small">
<t t-call="website.cookies_bar.text_secondary"/>
</div>
- </div>
- <div class="ml-auto">
- <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-block text-nowrap">I agree</a>
- <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link btn-sm text-nowrap">Cookie Policy</a>
+ <div class="col-lg-3 offset-lg-3">
+ <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-block">I agree</a>
+ <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link btn-block">Cookie Policy</a>
+ </div>
</div>
</div>
</section>
</t>
<t t-name="website.cookies_bar.popup">
- <section class="p-5">
- <div class="container text-800 text-center">
- <img t-attf-src="/web/image/website/#{websiteId}/logo/250x250" class="img img-fluid" alt="Website Logo"/>
- <br/><br/>
- <div class="h3">
- <t t-call="website.cookies_bar.text_title"/>
- </div>
- <br/>
- <div class="mb0 text-left">
- <t t-call="website.cookies_bar.text_primary"/>
- </div>
- <div class="text-left">
- <t t-call="website.cookies_bar.text_secondary"/>
+ <section class="o_colored_level o_cc o_cc1 p-5">
+ <div class="container text-center">
+ <div class="row">
+ <div class="col-lg-12">
+ <img t-attf-src="/web/image/website/#{websiteId}/logo/250x250" class="img img-fluid mb-4" alt="Website Logo"/>
+ <t t-call="website.cookies_bar.text_title"/>
+ <t t-call="website.cookies_bar.text_primary"/>
+ <t t-call="website.cookies_bar.text_secondary"/>
+ <a href="/cookie-policy" class=" o_cookies_bar_text_policy btn btn-link mr-2">Cookie Policy</a>
+ <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary">I agree</a>
+ </div>
</div>
- <br/>
- <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-lg">Cookie Policy</a>
- <br/>
- <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link">I agree</a>
</div>
</section>
</t>