[IMP] web_editor, website, website_sale: hide block in desktop display
Since [1] it is possible to request that some blocks are not displayed on mobile devices. This commit adds a similar option to prevent blocks from being displayed on desktops (i.e. on non-mobile devices). [1]: https://github.com/odoo/odoo/commit/9463f0f889f9dd8da6077895c125da4998a933c0 task-2900730 closes odoo/odoo#101483 X-original-commit: 3103e0553011b5c1f4078972d7a88fa3fd4068b2 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com> Co-authored-by: Antoine (anso) <anso@odoo.com>
This commit is contained in:
committed by
qsm-odoo
co-authored by
Antoine
parent
c6fa784c43
commit
1139ad7aff
@@ -313,7 +313,9 @@ var SnippetEditor = Widget.extend({
|
||||
if (this.isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
await this.toggleTargetVisibility(!this.$target.hasClass('o_snippet_invisible'));
|
||||
await this.toggleTargetVisibility(!this.$target.hasClass('o_snippet_invisible')
|
||||
&& !this.$target.hasClass('o_snippet_mobile_invisible')
|
||||
&& !this.$target.hasClass('o_snippet_desktop_invisible'));
|
||||
const proms = _.map(this.styles, option => {
|
||||
return option.cleanForSave();
|
||||
});
|
||||
@@ -2162,7 +2164,14 @@ var SnippetsMenu = Widget.extend({
|
||||
this.invisibleDOMMap = new Map();
|
||||
const $invisibleDOMPanelEl = $(this.invisibleDOMPanelEl);
|
||||
$invisibleDOMPanelEl.find('.o_we_invisible_entry').remove();
|
||||
const $invisibleSnippets = globalSelector.all().find('.o_snippet_invisible').addBack('.o_snippet_invisible');
|
||||
let isMobile;
|
||||
this.trigger_up('service_context_get', {
|
||||
callback: (ctx) => {
|
||||
isMobile = ctx['isMobile'];
|
||||
},
|
||||
});
|
||||
const invisibleSelector = `.o_snippet_invisible, ${isMobile ? '.o_snippet_mobile_invisible' : '.o_snippet_desktop_invisible'}`;
|
||||
const $invisibleSnippets = globalSelector.all().find(invisibleSelector).addBack(invisibleSelector);
|
||||
|
||||
$invisibleDOMPanelEl.toggleClass('d-none', !$invisibleSnippets.length);
|
||||
|
||||
@@ -3875,6 +3884,12 @@ var SnippetsMenu = Widget.extend({
|
||||
for (const gridItemEl of gridItemEls) {
|
||||
gridUtils._reloadLazyImages(gridItemEl);
|
||||
}
|
||||
for (const invisibleOverrideEl of this.getEditableArea().find('.o_snippet_mobile_invisible, .o_snippet_desktop_invisible')) {
|
||||
invisibleOverrideEl.classList.remove('o_snippet_override_invisible');
|
||||
invisibleOverrideEl.dataset.invisible = '1';
|
||||
}
|
||||
// This is async but using the main editor mutex.
|
||||
this._updateInvisibleDOM();
|
||||
},
|
||||
/**
|
||||
* Undo..
|
||||
|
||||
@@ -674,6 +674,17 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
|
||||
_onContextGet(event) {
|
||||
return event.data.callback(this._context);
|
||||
}
|
||||
/**
|
||||
* Retrieves the website service context.
|
||||
*
|
||||
* @private
|
||||
* @param {OdooEvent} ev
|
||||
*/
|
||||
_onServiceContextGet(ev) {
|
||||
ev.data.callback({
|
||||
isMobile: this.websiteService.context.isMobile,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Discards changes and reload the iframe.
|
||||
*
|
||||
@@ -841,6 +852,7 @@ WysiwygAdapterComponent.prototype.events = {
|
||||
'gmap_api_key_request': '_onRootEventRequest',
|
||||
'request_save': '_onSaveRequest',
|
||||
'context_get': '_onContextGet',
|
||||
'service_context_get': '_onServiceContextGet',
|
||||
'action_demand': '_handleAction',
|
||||
'request_cancel': '_onCancelRequest',
|
||||
'snippet_will_be_cloned': '_onSnippetWillBeCloned',
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg viewBox="0 0 465 462" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M456.969 9.84743L454.026 6.90425C444.956 -2.16512 429.098 -1.01124 418.605 9.48152L10.8984 417.188C0.405681 427.681 -0.748186 443.539 8.32118 452.609L11.2644 455.552C20.3337 464.621 36.1919 463.467 46.6847 452.975L454.392 45.2678C464.884 34.775 466.038 18.9168 456.969 9.84743Z"/>
|
||||
<path d="M346.673 26.269H39.1908C17.8303 26.269 0.5 43.6036 0.5 64.9695V322.973C0.5 336.409 7.35309 348.251 17.752 355.19L114.47 258.472H62.9696C56.9597 258.472 52.0878 253.601 52.0878 247.591V88.7515C52.0878 82.7417 56.9597 77.8697 62.9696 77.8697H295.072L346.673 26.269Z"/>
|
||||
<path d="M296.331 258.472H402.32C408.33 258.472 413.202 253.601 413.202 247.591V141.602L464.79 90.0139V322.973C464.79 344.339 447.46 361.674 426.099 361.674H271.336L284.233 400.375H342.269C352.949 400.375 361.614 409.042 361.614 419.725C361.614 430.408 352.949 439.075 342.269 439.075H123.021C120.837 439.075 118.734 438.708 116.771 438.033L154.429 400.375H181.057L193.954 361.674H193.13L226.244 328.56C228.268 329.181 230.417 329.516 232.645 329.516C244.665 329.516 254.409 319.772 254.409 307.753C254.409 305.525 254.074 303.376 253.452 301.352L296.331 258.472Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 513 457" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M43.1667 0.887085H469.833C493.389 0.887085 512.5 20.003 512.5 43.5645V328.081C512.5 351.642 493.389 370.758 469.833 370.758H299.167L313.389 413.435H377.389C389.167 413.435 398.722 422.993 398.722 434.774C398.722 446.555 389.167 456.113 377.389 456.113H135.611C123.878 456.113 114.278 446.51 114.278 434.774C114.278 423.038 123.878 413.435 135.611 413.435H199.611L213.833 370.758H43.1667C19.6111 370.758 0.5 351.642 0.5 328.081V43.5645C0.5 20.003 19.6111 0.887085 43.1667 0.887085ZM443.611 256.952C450.239 256.952 455.611 251.579 455.611 244.952V69.7903C455.611 63.1629 450.239 57.7903 443.611 57.7903H69.3889C62.7615 57.7903 57.3889 63.1629 57.3889 69.7903V244.952C57.3889 251.579 62.7615 256.952 69.3889 256.952H443.611ZM256.5 335.296C269.755 335.296 280.5 324.551 280.5 311.296C280.5 298.041 269.755 287.296 256.5 287.296C243.245 287.296 232.5 298.041 232.5 311.296C232.5 324.551 243.245 335.296 256.5 335.296Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 995 B |
@@ -2294,36 +2294,61 @@ options.registry.topMenuColor = options.Class.extend({
|
||||
});
|
||||
|
||||
/**
|
||||
* Manage the visibility of snippets on mobile.
|
||||
* Manage the visibility of snippets on mobile/desktop.
|
||||
*/
|
||||
options.registry.MobileVisibility = options.Class.extend({
|
||||
isTopOption: true,
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async updateUI() {
|
||||
await this._super(...arguments);
|
||||
const $button = this.$el.find('we-button');
|
||||
$button.attr('title', $button.hasClass('active') ? _t("Visible on mobile") : _t("Hidden on mobile"));
|
||||
},
|
||||
options.registry.DeviceVisibility = options.Class.extend({
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Options
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Allows to show or hide the associated snippet in mobile display mode.
|
||||
* Toggles the device visibility.
|
||||
*
|
||||
* @see this.selectClass for parameters
|
||||
*/
|
||||
showOnMobile(previewMode, widgetValue, params) {
|
||||
const classes = `d-none d-md-${this.$target.css('display')}`;
|
||||
this.$target.toggleClass(classes, !widgetValue);
|
||||
async toggleDeviceVisibility(previewMode, widgetValue, params) {
|
||||
this.$target[0].classList.remove('d-none', 'd-md-none',
|
||||
'o_snippet_mobile_invisible', 'o_snippet_desktop_invisible',
|
||||
'o_snippet_override_invisible',
|
||||
);
|
||||
const style = getComputedStyle(this.$target[0]);
|
||||
this.$target[0].classList.remove(`d-md-${style['display']}`);
|
||||
if (widgetValue === 'no_desktop') {
|
||||
this.$target[0].classList.add('d-md-none', 'o_snippet_desktop_invisible');
|
||||
} else if (widgetValue === 'no_mobile') {
|
||||
this.$target[0].classList.add(`d-md-${style['display']}`, 'd-none', 'o_snippet_mobile_invisible');
|
||||
}
|
||||
|
||||
// Update invisible elements.
|
||||
let isMobile;
|
||||
this.trigger_up('service_context_get', {
|
||||
callback: (ctx) => {
|
||||
isMobile = ctx['isMobile'];
|
||||
},
|
||||
});
|
||||
this.trigger_up('snippet_option_visibility_update', {show: widgetValue !== (isMobile ? 'no_mobile' : 'no_desktop')});
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async onTargetHide() {
|
||||
this.$target[0].classList.remove('o_snippet_override_invisible');
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async onTargetShow() {
|
||||
if (this.$target[0].classList.contains('o_snippet_mobile_invisible')
|
||||
|| this.$target[0].classList.contains('o_snippet_desktop_invisible')) {
|
||||
this.$target[0].classList.add('o_snippet_override_invisible');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
cleanForSave() {
|
||||
this.$target[0].classList.remove('o_snippet_override_invisible');
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -2334,10 +2359,16 @@ options.registry.MobileVisibility = options.Class.extend({
|
||||
* @override
|
||||
*/
|
||||
async _computeWidgetState(methodName, params) {
|
||||
if (methodName === 'showOnMobile') {
|
||||
if (methodName === 'toggleDeviceVisibility') {
|
||||
const classList = [...this.$target[0].classList];
|
||||
return classList.includes('d-none') &&
|
||||
classList.some(className => className.startsWith('d-md-')) ? '' : 'true';
|
||||
if (classList.includes('d-none') &&
|
||||
classList.some(className => className.startsWith('d-md-'))) {
|
||||
return 'no_mobile';
|
||||
}
|
||||
if (classList.includes('d-md-none')) {
|
||||
return 'no_desktop';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
return await this._super(...arguments);
|
||||
},
|
||||
@@ -2874,7 +2905,9 @@ options.registry.ConditionalVisibility = options.Class.extend({
|
||||
* @override
|
||||
*/
|
||||
async onTargetHide() {
|
||||
this.$target[0].classList.add('o_conditional_hidden');
|
||||
if (this.$target[0].classList.contains('o_snippet_invisible')) {
|
||||
this.$target[0].classList.add('o_conditional_hidden');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -2891,7 +2924,9 @@ options.registry.ConditionalVisibility = options.Class.extend({
|
||||
// snippet will be shown naturally (as the CSS rules won't apply).
|
||||
// Without this, the "eye" icon of the visibility panel would be shut
|
||||
// when entering edit mode.
|
||||
this.trigger_up('snippet_option_visibility_update', { show: true });
|
||||
if (this.$target[0].classList.contains('o_snippet_invisible')) {
|
||||
this.trigger_up('snippet_option_visibility_update', { show: true });
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -33,6 +33,32 @@ html[data-edit_translations="1"] {
|
||||
}
|
||||
}
|
||||
|
||||
.o_snippet_override_invisible {
|
||||
display: block !important;
|
||||
opacity: 70%;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
// Content is 0px wide => use available width.
|
||||
width: -webkit-fill-available;
|
||||
width: -moz-available;
|
||||
right: 20px;
|
||||
z-index: 100;
|
||||
background-color: $o-we-accent;
|
||||
font-size: 0px;
|
||||
content: "."; // Content is mandatory.
|
||||
}
|
||||
&.d-md-none::before {
|
||||
height: 50px;
|
||||
-webkit-mask: url("/website/static/src/img/snippets_options/desktop_invisible.svg") no-repeat 100% 100%;
|
||||
}
|
||||
&:not(.d-md-none)::before {
|
||||
height: 30px;
|
||||
-webkit-mask: url("/website/static/src/img/snippets_options/mobile_invisible.svg") no-repeat 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// SNIPPET PANEL
|
||||
$i: 1;
|
||||
@each $font-name, $font-config in $o-theme-font-configs {
|
||||
@@ -89,7 +115,7 @@ $i: 1;
|
||||
}
|
||||
}
|
||||
|
||||
we-button.o_we_mobile {
|
||||
we-button.o_we_device {
|
||||
> div {
|
||||
// FIXME maybe there is some refactoring to do so that all SVG icons
|
||||
// can be properly aligned with extra CSS rules...
|
||||
@@ -97,21 +123,19 @@ $i: 1;
|
||||
align-items: center;
|
||||
|
||||
svg {
|
||||
width: 15px;
|
||||
fill: $o-we-color-danger;
|
||||
width: 12px;
|
||||
fill: $o-we-sidebar-content-field-clickable-color;
|
||||
margin-bottom: 0;
|
||||
margin-left: -3px;
|
||||
|
||||
&:hover {
|
||||
fill: darken($o-we-color-danger, 7.5%);
|
||||
fill: $o-we-sidebar-content-field-pressed-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.active > div > svg {
|
||||
fill: $o-we-sidebar-content-field-color;
|
||||
|
||||
&.active > div svg {
|
||||
fill: $o-we-color-danger;
|
||||
&:hover {
|
||||
fill: $o-we-sidebar-content-field-pressed-color;
|
||||
fill: darken($o-we-color-danger, 7.5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1503,8 +1503,8 @@ options.registry.WebsiteFormSubmitRequired = DisableOverlayButtonOption.extend({
|
||||
}
|
||||
});
|
||||
|
||||
// Disable "Shown on Mobile" option if for an hidden field
|
||||
options.registry.MobileVisibility.include({
|
||||
// Disable "Shown on Mobile/Desktop" option if for an hidden field
|
||||
options.registry.DeviceVisibility.include({
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
|
||||
@@ -589,14 +589,6 @@
|
||||
<t t-call="website.snippet_options_shadow_widgets"/>
|
||||
</div>
|
||||
|
||||
<!-- Mobile display options -->
|
||||
<div data-js="MobileVisibility" data-selector="section, section .row > div"
|
||||
data-exclude=".s_col_no_resize.row > div, .s_masonry_block .s_col_no_resize">
|
||||
<we-button class="o_we_link o_we_mobile" data-show-on-mobile="true" data-no-preview="true"
|
||||
data-img="/website/static/src/img/snippets_options/mobile_invisible.svg"
|
||||
data-active-img="/website/static/src/img/snippets_options/mobile_visible.svg"/>
|
||||
</div>
|
||||
|
||||
<div data-js="sizing_y"
|
||||
data-selector="section, .row > div, .parallax, .s_hr, .carousel-item, .s_rating"
|
||||
data-exclude="section:has(> .carousel), .s_image_gallery .carousel-item, .s_col_no_resize.row > div, .s_col_no_resize"/>
|
||||
@@ -1277,6 +1269,21 @@
|
||||
</we-collapse>
|
||||
</div>
|
||||
|
||||
<!-- Mobile/Desktop display options -->
|
||||
<div data-js="DeviceVisibility" data-selector="section, section .row > div"
|
||||
data-exclude=".s_col_no_resize.row > div, .s_masonry_block .s_col_no_resize">
|
||||
<we-row string="Device">
|
||||
<we-button class="o_we_device" data-toggle-device-visibility="no_desktop" title="Show/Hide on Desktop"
|
||||
data-no-preview="true"
|
||||
data-img="/website/static/src/img/snippets_options/desktop_invisible.svg"
|
||||
/>
|
||||
<we-button class="o_we_device" data-toggle-device-visibility="no_mobile" title="Show/Hide on Mobile"
|
||||
data-no-preview="true"
|
||||
data-img="/website/static/src/img/snippets_options/mobile_invisible.svg"
|
||||
/>
|
||||
</we-row>
|
||||
</div>
|
||||
|
||||
<!-- Cookies Bar -->
|
||||
<div data-selector="#website_cookies_bar" data-js="CookiesBar" data-target=".modal">
|
||||
<we-select string="Layout" class="o_we_inline">
|
||||
|
||||
@@ -925,8 +925,8 @@ options.registry.WebsiteSaleProductAttribute = options.Class.extend({
|
||||
},
|
||||
});
|
||||
|
||||
// Disable "Shown on Mobile" option if for dynamic product snippets
|
||||
options.registry.MobileVisibility.include({
|
||||
// Disable "Shown on Mobile/Desktop" option if for dynamic product snippets
|
||||
options.registry.DeviceVisibility.include({
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
|
||||
Reference in New Issue
Block a user